Added an image loader system, wherein files to be loaded notify the display of their status. The status of images can be polled by an App thereafter. Added fairly limited Spritesheet and Sprite Drawables. Added vertical and horizontal centering flags, as well as scale to parent element flags for the display. Some changes may have broken other functionality, but this is likely moot, as CBDL will be rewritten later on.

master
kts 2014-09-18 17:44:29 -06:00
parent 3fb2511b53
commit 2fe6f269a1
2 changed files with 246 additions and 24 deletions

View File

@ -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) {

View File

@ -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) {