diff --git a/CBDL.js b/CBDL.js index 3879060..436e741 100644 --- a/CBDL.js +++ b/CBDL.js @@ -72,6 +72,8 @@ CBDL.Includes Object that manages includes for an App. Attempts to load all includes specified by the App, providing they are provided prior to the App's onExecute member function being called. + +TODO: fix on mobile, yoo =============================================================================== */ CBDL.Includes = function(app) { diff --git a/CBDL_graphics.js b/CBDL_graphics.js index 6a64069..ad1a513 100644 --- a/CBDL_graphics.js +++ b/CBDL_graphics.js @@ -7,7 +7,7 @@ CBDL.Graphics = CBDL.Graphics || { version: 0.1, BACKEND: {DIV: 0x00, CANVAS_2D:0x01, WEBGL:0x02}, // FILL sets the initial Display to the width and height of the browser window. Resizing when the window's dimensions change is left to the developer. - VM: {SCALE: 0x01, ABSOLUTE: 0x02, FILL: 0x03}, + VM: {ABSOLUTE: 0x01, SCALE: 0x02, FILL: 0x04, VCENTER: 0x08, HCENTER: 16}, RADIAN: (Math.PI/180), getViewport: function() { var h = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight; @@ -31,6 +31,7 @@ bulk. CBDL.Graphics.BaseDisplay = function(video_mode, target_element) { this.video_mode = video_mode; this.target_element = target_element; + this.loading_elements = []; }; CBDL.Graphics.BaseDisplay.prototype.Init = function() {}; @@ -39,7 +40,26 @@ CBDL.Graphics.BaseDisplay.prototype.setHeight = function() {}; CBDL.Graphics.BaseDisplay.prototype.Fill = function(red, green, blue) {}; CBDL.Graphics.BaseDisplay.prototype.clear = function() {}; CBDL.Graphics.BaseDisplay.prototype.draw = function() {}; - +CBDL.Graphics.BaseDisplay.prototype.getViewport = function() { + if (!this.target_element) return null; + var h = this.target_element.innerHeight || this.target_element.clientHeight; + var w = this.target_element.innerWidth || this.target_element.clientWidth; + return { width : w , height : h } +}; +CBDL.Graphics.BaseDisplay.prototype.checkLoading = function() { + var len = this.loading_elements.length; + for (i = 0; i < len; i++) { + if (this.loading_elements[i].state != 1) { + return i+1; + } + } + return 0; +}; +CBDL.Graphics.BaseDisplay.prototype.addLoading = function(name) { + var load = { name: name, state: 0 }; + this.loading_elements.push(load); + return load; +}; CBDL.Graphics.BaseDisplay.prototype._Drawable_ = function(display, size, scale, rotation) { this.display = display; this.size = size; @@ -67,13 +87,16 @@ CBDL.Graphics.BaseDisplay.prototype._Drawable_.prototype.destroy = function() {} CBDL.Graphics.BaseDisplay.prototype._Image_ = function(display, image, scale, rotation) { this.display = display; this.data = new Image(); + this.image = image; this.size = { width: 1, height: 1 }; - this.data.onload = (function(scope) { + var load_obj = display.addLoading(image); + this.data.onload = (function(scope, load_obj) { return function() { scope.size.width = this.width; scope.size.height = this.height; + load_obj.state = 1; } - })(this); + })(this, load_obj); this.data.src = image; this.scale = scale; this.rotation = rotation; @@ -82,6 +105,47 @@ CBDL.Graphics.BaseDisplay.prototype._Image_.prototype.destroy = function() { this.data = null; }; +CBDL.Graphics.BaseDisplay.prototype._Spritesheet_ = function(display, image, size, sprite_size) { + this.display = display; + this.data = new Image(); + this.image = image; + this.size = size; + this.cols = size.width / sprite_size.width; + this.rows = size.height / sprite_size.height; + this.sprite_size = sprite_size; + var load_obj = display.addLoading(image); + this.data.onload = (function(scope, load_obj) { + return function() { + //scope.size.width = this.width; + //scope.size.height = this.height; + //scope.rows = this.width / scope.sprite_width; + //scope.cols = this.height / scope.sprite_height; + load_obj.state = 1; + } + })(this, load_obj); + + this.data.src = image; + this.scale = 1; + this.rotation = 0; +};CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.BaseDisplay.prototype._Spritesheet_); +CBDL.Graphics.BaseDisplay.prototype._Spritesheet_.prototype.destroy = function() { + this.data = null; +}; +CBDL.Graphics.BaseDisplay.prototype._Sprite_ = function(display, spritesheet, position, size) { + this.display = display; + this.data = spritesheet.data; + this.position = position; + this.size = size; + this.scale = 1; + this.rotation = 0; +};CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.BaseDisplay.prototype._Sprite_); +CBDL.Graphics.BaseDisplay.prototype._Sprite_.prototype.destroy = function() { + this.data = null; +}; +CBDL.Graphics.BaseDisplay.prototype._Sprite_.prototype.setPosition = function(x, y) { + this.position.x = x; + this.position.y = y; +}; CBDL.Graphics.BaseDisplay.prototype._Box_ = function(display, size, scale, rotation) { this.display = display; @@ -247,6 +311,7 @@ CBDL.Graphics.WebGlDisplay.prototype._Image_ = function(display, image, scale, r CBDL.Graphics.Canvas2dDisplay = function(target_element, video_mode) { this.video_mode = video_mode; this.target_element = target_element; + this.scale = {x: 1, y: 1}; this.type = 'Canvas2dDisplay'; }; CBDL.extend(CBDL.Graphics.BaseDisplay, CBDL.Graphics.Canvas2dDisplay); @@ -274,7 +339,15 @@ CBDL.Graphics.Canvas2dDisplay.prototype.Init = function() { } this.element_context = this.element.getContext("2d"); + // FIXME: should be handled as a render flag + /*this.element_context.imageSmoothingEnabled = false; + this.element_context.mozImageSmoothingEnabled = false; + this.element_context.webkitImageSmoothingEnabled = false;*/ this.target_element.appendChild(this.element); + // FIXME: it seems elements do not trigger resize events :S + CBDL.addEvent(this.target_element, "resize", (function(scope) { return function(event) { + scope.updateViewport(); + }})(this), true); // offscreen canvas, used for any transformations that must be done via putImageData // or getImageData. (e.g., opacity) @@ -290,23 +363,41 @@ CBDL.Graphics.Canvas2dDisplay.prototype.updateViewport = function() { this.element.width = this.viewport.width; this.element.height = this.viewport.height; } + var viewport = this.getViewport(); + if (this.video_mode.flags & CBDL.Graphics.VM.SCALE) { + var ratio = Math.min(viewport.width / this.video_mode.width, viewport.height / this.video_mode.height); + this.scale.x = ratio; + this.scale.y = ratio; + this.element.width = this.viewport.width * ratio; + this.element.height = this.viewport.height * ratio; + } + if (this.video_mode.flags & CBDL.Graphics.VM.VCENTER) { + this.element.style.top = (viewport.height/2 - this.viewport.height/2)+"px"; + } + if (this.video_mode.flags & CBDL.Graphics.VM.HCENTER) { + this.element.style.left = (viewport.width/2 - this.viewport.width/2)+"px"; + } }; CBDL.Graphics.Canvas2dDisplay.prototype.setWidth = function(width) { this.video_mode.width = width; this.element.width = width; + this.viewport.width = width; + this.element.style.width = width+"px"; }; CBDL.Graphics.Canvas2dDisplay.prototype.setHeight = function(height) { this.video_mode.height = height; this.element.height = height; + this.viewport.height = height; + this.element.style.height = height+"px"; }; CBDL.Graphics.Canvas2dDisplay.prototype.Fill = function(red, green, blue) { var hex_value = ((1 << 24) + (red << 16) + (green << 8) + blue); var hex_string = hex_value.toString(16).substr(1); this.element_context.fillStyle = "#"+hex_string; - this.element_context.fillRect(0, 0, this.video_mode.width, this.video_mode.height); + this.element_context.fillRect(0, 0, this.video_mode.width*this.scale.x, this.video_mode.height*this.scale.y); }; CBDL.Graphics.Canvas2dDisplay.prototype.clear = function() { @@ -328,6 +419,17 @@ CBDL.Graphics.Canvas2dDisplay.prototype.draw = function(source, s_position, t_po // element_context as an Image when complete. this.element_context.save(); + + if (source instanceof CBDL.Graphics.BaseDisplay.prototype._Sprite_) { + s_position.x -= source.position.x; + s_position.y -= source.position.y; + } + + scale_x = this.scale.x + (source.scale.x ? source.scale.x : 0); + scale_y = this.scale.y + (source.scale.y ? source.scale.y: 0); + t_position.x *= scale_x; + t_position.y *= scale_y; + this.element_context.translate(t_position.x, t_position.y); if (source.data instanceof Image) { @@ -339,13 +441,12 @@ CBDL.Graphics.Canvas2dDisplay.prototype.draw = function(source, s_position, t_po if (typeof source.rotation !== 'undefined') { this.element_context.rotate(source.rotation * CBDL.Graphics.RADIAN); } - if (typeof source.scale !== 'undefined') { - this.element_context.scale(source.scale.x, source.scale.y); - } - + //if (typeof source.scale !== 'undefined') { + this.element_context.scale(scale_x, scale_y); + //} // Set transparency offscreen due to putImageData overwriting all pixel values in // the canvas. - this.offscreen_context.drawImage(source.data, 0, 0); + this.offscreen_context.drawImage(source.data, s_position.x, s_position.y); if (typeof source.opacity !== 'undefined') { // NOTE: getImageData & putImageData are painfully slow! :( var image = this.offscreen_context.getImageData(0, 0, width, height); @@ -443,6 +544,14 @@ CBDL.Graphics.Canvas2dDisplay.prototype.Image = function(image, scale, rotation) return (new CBDL.Graphics.BaseDisplay.prototype._Image_(this, image, scale, rotation)); }; +CBDL.Graphics.Canvas2dDisplay.prototype.Spritesheet = function(image, size, sprite_size) { + return (new CBDL.Graphics.Canvas2dDisplay.prototype._Spritesheet_(this, image, size, sprite_size)); +}; + +CBDL.Graphics.Canvas2dDisplay.prototype.Sprite = function(image, position, size) { + return (new CBDL.Graphics.BaseDisplay.prototype._Sprite_(this, image, position, size)); +}; + CBDL.Graphics.Canvas2dDisplay.prototype.Box = function(size, scale, rotation) { return (new CBDL.Graphics.BaseDisplay.prototype._Box_(this, size, scale, rotation)); }; @@ -475,6 +584,7 @@ CBDL.Graphics.DivDisplay = function(target_element, video_mode) { this.target_element = target_element; this.video_mode = video_mode; this.type = 'DivDisplay'; + this.scale = {x: 1, y: 1}; }; CBDL.extend(CBDL.Graphics.BaseDisplay, CBDL.Graphics.DivDisplay); CBDL.Graphics.DivDisplay.prototype.Init = function() { @@ -487,16 +597,20 @@ CBDL.Graphics.DivDisplay.prototype.Init = function() { this.element.style.position = "relative"; } if (this.video_mode.flags & CBDL.Graphics.VM.FILL) { - this.viewport = CBDL.Graphics.getViewport(); - this.element.style.width = this.viewport.width+"px"; - this.element.style.height = this.viewport.height+"px"; + alert(this.video_mode.flags); + this.viewport = CBDL.Graphics.getViewport(); + this.video_mode.width = this.viewport.width; + this.video_mode.height = this.viewport.height; + this.element.width = this.viewport.width; + this.element.height = this.viewport.height; } else { this.viewport = {}; this.viewport.width = this.video_mode.width; this.viewport.height = this.video_mode.height; - this.element.style.width = this.video_mode.width+"px"; - this.element.style.height = this.video_mode.height+"px"; + this.element.width = this.video_mode.width; + this.element.height = this.video_mode.height; } + this.updateViewport(); this.element.style.display = "block"; this.element.style.overflow = "hidden"; this.target_element.appendChild(this.element); @@ -509,13 +623,29 @@ CBDL.Graphics.DivDisplay.prototype.updateViewport = function() { this.element.style.width = this.viewport.width+"px"; this.element.style.height = this.viewport.height+"px"; } + var viewport = this.getViewport(); + if (this.video_mode.flags & CBDL.Graphics.VM.SCALE) { + var ratio = Math.min(viewport.width / this.video_mode.width, viewport.height / this.video_mode.height); + this.scale.x = ratio; + this.scale.y = ratio; + this.element.style.width = this.viewport.width * ratio + "px"; + this.element.style.height = this.viewport.height * ratio + "px"; + } + if (this.video_mode.flags & CBDL.Graphics.VM.VCENTER) { + this.element.style.top = (viewport.height/2 - this.viewport.height/2)+"px"; + } + if (this.video_mode.flags & CBDL.Graphics.VM.HCENTER) { + this.element.style.left = (viewport.width/2 - this.viewport.width/2)+"px"; + } }; CBDL.Graphics.DivDisplay.prototype.setWidth = function(width) { + this.viewport.width = width; this.element.style.width = width+"px"; }; CBDL.Graphics.DivDisplay.prototype.setHeight = function(height) { + this.viewport.height = height; this.element.style.height = height+"px"; }; @@ -533,10 +663,25 @@ CBDL.Graphics.DivDisplay.prototype.draw = function(source, s_position, t_positio if (!source.isDrawn) { source.data.style.position = "absolute"; source.data.style.display = "block"; + source.data.style.overflow = "hidden"; + if (source instanceof CBDL.Graphics.DivDisplay.prototype._Sprite_) { + source.image_data.style.position = "absolute"; + source.image_data.style.display = "block"; + } this.element.appendChild(source.data); source.isDrawn = true; } + if (source instanceof CBDL.Graphics.DivDisplay.prototype._Sprite_) { + source.image_data.style.left = -(source.position.x)+"px"; + source.image_data.style.top = -(source.position.y)+"px"; + } + + scale_x = this.scale.x; + scale_y = this.scale.y; + t_position.x *= scale_x; + t_position.y *= scale_y; + var transform = ''; if (source instanceof CBDL.Graphics.BaseDisplay.prototype._Line_) { @@ -555,15 +700,15 @@ CBDL.Graphics.DivDisplay.prototype.draw = function(source, s_position, t_positio t_position.y += rot_y; transform += "rotate("+angle+"deg)"; } else { - source.data.style.height = source.size.height; + source.data.style.height = source.size.height+"px"; } if (typeof source.rotation !== 'undefined') { - transform += "rotate("+source.rotation+"deg)" - } - if (typeof source.scale !== 'undefined') { - transform += "scale("+source.scale.x+", "+source.scale.y+")" + transform += "rotate("+source.rotation+"deg)"; } + //if (typeof source.scale !== 'undefined') { + transform += "scale("+scale_x+", "+scale_y+")"; + //} if (typeof source.opacity !== 'undefined') { source.data.style.opacity = source.opacity; } @@ -582,7 +727,6 @@ CBDL.Graphics.DivDisplay.prototype.clear = function() { CBDL.Graphics.DivDisplay.prototype.Drawable = function() { this.lol = "lol"; - console.log("buh"); }; CBDL.Graphics.DivDisplay.prototype.Image = function(image, scale, rotation) { @@ -592,16 +736,93 @@ CBDL.Graphics.DivDisplay.prototype.Image = function(image, scale, rotation) { CBDL.Graphics.DivDisplay.prototype._Image_ = function(display, image, scale, rotation) { this.isDrawn = false; this.display = display; - this.data = document.createElement("img"); - this.data.src = image; + this.data = document.createElement("div"); + this.size = { width: 1, height: 1 }; + this.image = image; + this.image_data = document.createElement("img"); + var load_obj = display.addLoading(image); + this.image_data.onload = (function(scope, load_obj) { + return function() { + scope.size.width = this.width; + scope.size.height = this.height; + load_obj.state = 1; + } + })(this, load_obj); + this.image_data.src = image; + this.image_data.style.position = "absolute"; + this.data.appendChild(this.image_data); + this.scale = scale; this.rotation = rotation; this.data.style.visibility = 'hidden'; };CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.DivDisplay.prototype._Image_); CBDL.Graphics.DivDisplay.prototype._Image_.prototype.destroy = function() { + this.data.removeChild(this.image_data); this.data.parentNode.removeChild(this.data); }; +// What is a spritesheet? Basically an Image that is not supposed to be displayed. It should pretty much just be the data of the Images. +CBDL.Graphics.DivDisplay.prototype.Spritesheet = function(image, size, sprite_size) { + return (new CBDL.Graphics.DivDisplay.prototype._Spritesheet_(this, image, size, sprite_size)); +}; +CBDL.Graphics.DivDisplay.prototype._Spritesheet_ = function(display, image, size, sprite_size) { + this.isDrawn = false; + this.display = display; + this.data = document.createElement("div"); + this.size = size; + this.sprite_size = sprite_size; + this.cols = size.width / sprite_size.width; + this.rows = size.height / sprite_size.height; + this.image_data = document.createElement("img"); + var load_obj = display.addLoading(image); + this.image_data.onload = (function(scope, load_obj) { + return function() { + load_obj.state = 1; + //scope.size.width = this.width; + //scope.size.height = this.height; + //scope.rows = this.width / scope.sprite_width; + //scope.cols = this.height / scope.sprite_height; + } + })(this, load_obj); + this.image_data.src = image; + this.image_data.style.position = "absolute"; + this.data.appendChild(this.image_data); + + this.scale = 1; + this.rotation = 0; + this.data.style.visibility = 'hidden'; +};CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.DivDisplay.prototype._Spritesheet_); + +CBDL.Graphics.DivDisplay.prototype.Sprite = function(spritesheet, position, size) { + return (new CBDL.Graphics.DivDisplay.prototype._Sprite_(this, spritesheet, position, size)); +}; +// DivDisplay uses individual img elements for every Sprite. +CBDL.Graphics.DivDisplay.prototype._Sprite_ = function(display, spritesheet, position, size) { + this.isDrawn = false; + this.display = display; + this.spritesheet = spritesheet; + this.position = position; + this.data = document.createElement("div"); + this.size = size; + this.image_data = document.createElement("img"); + this.image_data.src = spritesheet.image_data.src; + this.image_data.style.position = "absolute"; + this.data.appendChild(this.image_data); + + this.scale = {x: 1, y: 1}; + this.rotation = 0; + this.data.style.visibility = 'hidden'; +};CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.DivDisplay.prototype._Sprite_); +CBDL.Graphics.DivDisplay.prototype._Sprite_.prototype.destroy = function() { + this.data.removeChild(this.image_data); + this.data.parentNode.removeChild(this.data); + this.data = null; +}; +CBDL.Graphics.DivDisplay.prototype._Sprite_.prototype.setPosition = function(x, y) { + this.position.x = x; + this.position.y = y; +}; + CBDL.Graphics.DivDisplay.prototype.Box = function(size, scale, rotation) { return (new CBDL.Graphics.DivDisplay.prototype._Box_(this, size, scale, rotation)); }; @@ -780,7 +1001,6 @@ Usage: CBDL.Graphics.Drawable = function(position, scale, rotation) { this.setPosition = function(x, y) { - } this.setScale = function(x, y) {