CBDL.include("excanvas.js"); /* **** CBDL_net - Optional layer which adds network support * * * */ 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: {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; var w = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth; return { width : w , height : h } } }; /* =============================================================================== CBDL.Graphics.BaseDisplay Basic Display skeleton from which all Display backends should be derived from. It is through the backend detection that the Display backend, being named something similar to Html5Display, is assigned as Graphics.Display. This allows for backends to be used/sent according to browser capability, rather than via 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() {}; CBDL.Graphics.BaseDisplay.prototype.setWidth = function() {}; 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; this.scale = scale; this.rotation = rotation; }; CBDL.Graphics.BaseDisplay.prototype._Drawable_.prototype.setRotation = function(rotation) { this.rotation = rotation; }; CBDL.Graphics.BaseDisplay.prototype._Drawable_.prototype.setScale = function(scale) { this.scale = scale; }; CBDL.Graphics.BaseDisplay.prototype._Drawable_.prototype.setSize = function(size) { this.size = size; }; CBDL.Graphics.BaseDisplay.prototype._Drawable_.prototype.setOpacity = function(opacity) { this.opacity = opacity; }; 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 }; 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, load_obj); this.data.src = image; this.scale = scale; this.rotation = rotation; };CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.BaseDisplay.prototype._Image_); 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; this.size = size; this.scale = scale; this.rotation = rotation; }; CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.BaseDisplay.prototype._Box_); CBDL.Graphics.BaseDisplay.prototype._Box_.prototype.setColor = function(color) { this.color = color; }; CBDL.Graphics.BaseDisplay.prototype._Line_ = function(display, coords, size, scale, rotation) { this.display = display; this.coords = coords; this.size = size; this.scale = scale; this.rotation = rotation; }; CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.BaseDisplay.prototype._Line_); CBDL.Graphics.BaseDisplay.prototype._Line_.prototype.setColor = function(color) { this.color = color; }; CBDL.Graphics.BaseDisplay.prototype._Font_ = function(family) { this.family = family; }; CBDL.Graphics.BaseDisplay.prototype._Font_.prototype.destroy = function() {}; CBDL.Graphics.BaseDisplay.prototype._Font_.prototype.getWidth = function(size) { var test = document.createElement('div'); test.innerHTML = 'a'; //test.style.left = "-1000px"; //test.style.top = "-1000px"; test.style.visibility = "hidden"; test.style.position = "absolute"; test.style.fontFamily = this.family; test.style.fontSize = size+"px"; document.body.appendChild(test); var width = test.clientWidth+1; document.body.removeChild(test); return width; }; CBDL.Graphics.BaseDisplay.prototype._Font_.prototype.getTextWidth = function(size, string) { var test = document.createElement('div'); test.innerHTML = string; test.style.left = "-1000px"; test.style.top = "-1000px"; //test.style.visibility = "hidden"; test.style.position = "absolute"; test.style.fontFamily = this.family; test.style.fontSize = size+"px"; document.body.appendChild(test); var width = test.clientWidth; document.body.removeChild(test); return width; }; CBDL.Graphics.BaseDisplay.prototype._String_ = function(text, font, size) { this.text = text; this.font = font; this.size = size; this.color = "#000000"; }; CBDL.Graphics.BaseDisplay.prototype._String_.prototype.setText = function(text) { this.text = text; }; CBDL.Graphics.BaseDisplay.prototype._String_.prototype.setFont = function(font) { this.font = font; }; CBDL.Graphics.BaseDisplay.prototype._String_.prototype.setSize = function(size) { this.size = size; }; CBDL.Graphics.BaseDisplay.prototype._String_.prototype.setColor = function(color) { this.color = color; }; CBDL.Graphics.BaseDisplay.prototype._String_.prototype.destroy = function() {}; CBDL.Graphics.getBackend = function() { var supports = []; try { var element = document.createElement("div"); } catch (err) { element = null; } if (element != null) { supports.push(CBDL.Graphics.BACKEND.DIV); } try { var element = document.createElement("canvas"); } catch (err) { element = null; } if (element != null) { supports.push(CBDL.Graphics.BACKEND.CANVAS_2D); if (element.getContext('webgl')) { supports.push(CBDL.Graphics.BACKEND.WEBGL); } } return supports[supports.length-1]; }; /* =============================================================================== CBDL.Graphics.Display Base window onto which various Graphics elements can be placed within. Effectively exists as a simple wrapper to a 'div' element. The first parameter passed is an instance of a VideoMode(width, height). The second optional parameter is a target HTML element. If ommitted, the Display adds its element to document.body. Usage: =============================================================================== */ CBDL.Graphics.Display = function(target_element, video_mode, backend) { backend = (typeof backend !== 'undefined' ? backend : CBDL.Graphics.getBackend()); target_element = (typeof target_element !== 'undefined' ? target_element : document.body); switch (backend) { case CBDL.Graphics.BACKEND.WEBGL: return (new CBDL.Graphics.WebGlDisplay(target_element, video_mode)); break; case CBDL.Graphics.BACKEND.CANVAS_2D: return (new CBDL.Graphics.Canvas2dDisplay(target_element, video_mode)); break; case CBDL.Graphics.BACKEND.DIV: return (new CBDL.Graphics.DivDisplay(target_element, video_mode)); break; } return false; }; CBDL.Graphics.WebGlDisplay = function(target_element, video_mode) { this.video_mode = video_mode; this.target_element = target_element; this.type = 'WebGlDisplay'; }; CBDL.extend(CBDL.Graphics.BaseDisplay, CBDL.Graphics.WebGlDisplay); CBDL.Graphics.WebGlDisplay.prototype.Init = function() { this.element = document.createElement("canvas"); this.element.width = this.video_mode.width; this.element.height = this.video_mode.height; this.element_context = this.element.getContext("webgl") || this.element.getContext("experimental-webgl"); this.element_context.viewport(0, 0, this.video_mode.width, this.video_mode.height); this.target_element.appendChild(this.element); }; CBDL.Graphics.WebGlDisplay.prototype.Image = function(image, scale, rotation) { return (new CBDL.Graphics.BaseDisplay.prototype._Image_(this, image, scale, rotation)); }; CBDL.Graphics.WebGlDisplay.prototype._Image_ = function(display, image, scale, rotation) { this.display = display; this.data = new Image(); this.data.texture = display.element_context.createTexture(); this.data.onload = (function(image) { return function() { image.loaded = true; }; }(this)); this.data.src = image; this.scale = scale; this.rotation = rotation; };CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Drawable_, CBDL.Graphics.WebGlDisplay.prototype._Image_); 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); CBDL.Graphics.Canvas2dDisplay.prototype.Init = function() { this.element = document.createElement("canvas"); if (this.video_mode.flags & CBDL.Graphics.VM.ABSOLUTE) { this.element.style.position = "absolute"; this.element.style.left = "0px"; this.element.style.top = "0px"; } else { this.element.style.position = "relative"; } if (this.video_mode.flags & CBDL.Graphics.VM.FILL) { 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.width = this.video_mode.width; this.element.height = this.video_mode.height; } 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) this.offscreen = document.createElement("canvas"); this.offscreen_context = this.offscreen.getContext("2d"); }; CBDL.Graphics.Canvas2dDisplay.prototype.updateViewport = function() { if (this.video_mode.flags & CBDL.Graphics.VM.FILL) { 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; } 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.scale.x, this.video_mode.height*this.scale.y); }; CBDL.Graphics.Canvas2dDisplay.prototype.clear = function() { // this.element_context.fillStyle = "#000000"; // this.element_context.fillRect(0, 0, this.video_mode.width, this.video_mode.height); // this.offscreen_context.fillStyle = "#000000"; // this.offscreen_context.fillRect(0, 0, this.video_mode.width, this.video_mode.height); this.element_context.clearRect(0, 0, this.element.width, this.element.height); this.offscreen_context.clearRect(0, 0, this.offscreen.width, this.offscreen.height); }; CBDL.Graphics.Canvas2dDisplay.prototype.draw = function(source, s_position, t_position) { var width = source.size.width || 1; var height = source.size.height || 1; var s_position = s_position || {x: 0, y: 0}; var t_position = t_position || {x: 0, y: 0}; // How this works: element_context, being the overall canvas, handles sprite rotation // and scaling. offscreen_context handles setting opacity, and is written to // 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) { // set offscreen this.offscreen.width = width; this.offscreen.height = height; this.element_context.translate(width/2, height/2); if (typeof source.rotation !== 'undefined') { this.element_context.rotate(source.rotation * CBDL.Graphics.RADIAN); } //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, 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); var image_data = image.data; var length = image_data.length; for (var i=3;i < length;i +=4) { if (image_data[i] > 0) { // if not transparent image_data[i] = image_data[i]*source.opacity; } } image.data = image_data; this.offscreen_context.putImageData(image, 0, 0); } // Copy manipulated image back over to main canvas. this.element_context.drawImage(this.offscreen, -(width/2), -(height/2)); } else if (source instanceof CBDL.Graphics.BaseDisplay.prototype._Box_) { this.offscreen.width = width; this.offscreen.height = height; this.element_context.translate(width/2, height/2); if (typeof source.scale !== 'undefined') { this.element_context.scale(source.scale.x, source.scale.y); } if (typeof source.rotation !== 'undefined') { this.element_context.rotate(source.rotation * CBDL.Graphics.RADIAN); } this.offscreen_context.fillStyle = source.color; this.offscreen_context.fillRect(0, 0, this.video_mode.width, this.video_mode.height); if (typeof source.opacity !== 'undefined') { // NOTE: getImageData & putImageData are painfully slow! :( var image = this.offscreen_context.getImageData(0, 0, width, height); var image_data = image.data; var length = image_data.length; for (var i=3;i < length;i +=4) { if (image_data[i] > 0) { // if not transparent image_data[i] = image_data[i]*source.opacity; } } image.data = image_data; this.offscreen_context.putImageData(image, 0, 0); } // Copy manipulated image back over to main canvas. this.element_context.drawImage(this.offscreen, -(width/2), -(height/2)); } else if (source instanceof CBDL.Graphics.BaseDisplay.prototype._Line_) { this.offscreen.width = width; this.offscreen.height = height; this.element_context.translate(width/2, height/2); if (typeof source.scale !== 'undefined') { this.element_context.scale(source.scale.x, source.scale.y); } if (typeof source.rotation !== 'undefined') { this.element_context.rotate(source.rotation * CBDL.Graphics.RADIAN); } this.element_context.fillStyle = source.color; this.element_context.beginPath(); this.element_context.moveTo(source.coords.ax, source.coords.ay); this.element_context.lineTo(source.coords.bx, source.coords.by); this.element_context.lineWidth = width; this.element_context.stroke(); if (typeof source.opacity !== 'undefined') { // NOTE: getImageData & putImageData are painfully slow! :( var image = this.offscreen_context.getImageData(0, 0, width, height); var image_data = image.data; var length = image_data.length; for (var i=3;i < length;i +=4) { if (image_data[i] > 0) { // if not transparent image_data[i] = image_data[i]*source.opacity; } } image.data = image_data; this.offscreen_context.putImageData(image, 0, 0); } // Copy manipulated image back over to main canvas. this.element_context.drawImage(this.offscreen, -(width/2), -(height/2)); } else if (source instanceof CBDL.Graphics.BaseDisplay.prototype._String_) { this.element_context.font = source.size+"px "+source.font.family; this.element_context.fillStyle = source.color; this.element_context.fillText(source.text, 0, source.size); } else { /*this.element_context.translate(source.size.width/2, source.size.height/2); if (typeof source.rotation !== 'undefined') { this.element_context.rotate(source.rotation * CBDL.Graphics.RADIAN); } this.element_context.fillStyle = "#FFFFFF"; this.element_context.fillRect(-(source.size.width/2), -(source.size.height/2), source.size.width, source.size.height); */ } this.element_context.restore(); }; CBDL.Graphics.Canvas2dDisplay.prototype.Drawable = function(size, scale, rotation) { return (new CBDL.Graphics.BaseDisplay.prototype._Drawable_(this, size, scale, rotation)); }; 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)); }; CBDL.Graphics.Canvas2dDisplay.prototype.Line = function(coords, size, scale, rotation) { return (new CBDL.Graphics.BaseDisplay.prototype._Line_(this, coords, size, scale, rotation)); }; CBDL.Graphics.Canvas2dDisplay.prototype.Font = function(family) { return (new CBDL.Graphics.BaseDisplay.prototype._Font_(family)); }; CBDL.Graphics.Canvas2dDisplay.prototype.String = function(string, font, size) { return (new CBDL.Graphics.BaseDisplay.prototype._String_(string, font, size)); }; /* =============================================================================== CBDL.Graphics.DivDisplay The div element based backend. This is the least capable backend of all default backends, supporting only the most basic drawing operations, not including rotation, shearing, or other such operations. =============================================================================== */ 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() { this.element = document.createElement("div"); if (this.video_mode.flags & CBDL.Graphics.VM.ABSOLUTE) { this.element.style.position = "absolute"; this.element.style.left = "0px"; this.element.style.top = "0px"; } else { this.element.style.position = "relative"; } if (this.video_mode.flags & CBDL.Graphics.VM.FILL) { 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.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); this.current_z = 0; }; CBDL.Graphics.DivDisplay.prototype.updateViewport = function() { 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"; } 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"; }; CBDL.Graphics.DivDisplay.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.style.backgroundColor = "#"+hex_string; }; CBDL.Graphics.DivDisplay.prototype.draw = function(source, s_position, t_position) { var s_position = s_position || {x: 0, y: 0}; var t_position = t_position || {x: 0, y: 0}; this.current_z++; source.data.style.visibility = 'hidden'; 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_) { delta_x = source.coords.bx - source.coords.ax; delta_y = source.coords.by - source.coords.ay; source.data.style.height = (Math.abs(delta_x) + Math.abs(delta_y))+"px"; rads = Math.atan2(delta_y, delta_x); angle = (rads * 180 / Math.PI) + 90; var rot_x = (source.coords.ax < source.coords.bx ? source.coords.ax : source.coords.bx); var rot_y = (source.coords.ay < source.coords.by ? source.coords.ay : source.coords.by); /*t_position.x += rot_x * Math.cos(rads) + rot_y * Math.sin(rads); t_position.y += -rot_x * Math.sin(rads) + rot_y * Math.cos(rads); //t_position.x += rot_x - (rot_x/2); //t_position.y += rot_y - (rot_y/2);*/ t_position.x += rot_x; t_position.y += rot_y; transform += "rotate("+angle+"deg)"; } else { 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("+scale_x+", "+scale_y+")"; //} if (typeof source.opacity !== 'undefined') { source.data.style.opacity = source.opacity; } source.data.style.width = source.size.width+"px"; source.data.style.left = t_position.x+"px"; source.data.style.top = t_position.y+"px"; source.data.style.zIndex = this.current_z; CBDL.setElementTransform(source.data, transform); source.data.style.visibility = 'visible'; }; CBDL.Graphics.DivDisplay.prototype.clear = function() { this.element.style.backgroundColor = "#000000"; this.current_z = 0; }; CBDL.Graphics.DivDisplay.prototype.Drawable = function() { this.lol = "lol"; }; CBDL.Graphics.DivDisplay.prototype.Image = function(image, scale, rotation) { return (new CBDL.Graphics.DivDisplay.prototype._Image_(this, image, scale, rotation)); }; CBDL.Graphics.DivDisplay.prototype._Image_ = function(display, image, scale, rotation) { this.isDrawn = false; this.display = display; 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)); }; CBDL.Graphics.DivDisplay.prototype._Box_ = function(display, size, scale, rotation) { this.isDrawn = false; this.display = display; this.color = "black"; this.data = document.createElement("div"); this.data.style.width = size.width+"px"; this.data.style.height = size.height+"px"; this.data.style.display = "block"; this.data.style.backgroundColor = this.color; this.size = size; this.scale = scale; this.rotation = rotation; }; CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Box_, CBDL.Graphics.DivDisplay.prototype._Box_); CBDL.Graphics.DivDisplay.prototype._Box_.prototype.destroy = function() { if (this.data.parentNode) { this.data.parentNode.removeChild(this.data); } }; CBDL.Graphics.DivDisplay.prototype._Box_.prototype.setColor = function(color) { this.color = color; this.data.style.backgroundColor = this.color; }; CBDL.Graphics.DivDisplay.prototype.Line = function(coords, size, scale, rotation) { return (new CBDL.Graphics.DivDisplay.prototype._Line_(this, coords, size, scale, rotation)); }; CBDL.Graphics.DivDisplay.prototype._Line_ = function(display, coords, size, scale, rotation) { this.isDrawn = false; this.display = display; this.color = "black"; this.data = document.createElement("div"); this.data.style.width = Math.abs(coords.ax - coords.bx) + Math.abs(coords.ay - coords.by); this.data.style.height = size.height; this.data.style.display = "block"; this.data.style.backgroundColor = this.color; this.coords = coords; this.size = size; this.scale = scale; this.rotation = rotation; }; CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._Line_, CBDL.Graphics.DivDisplay.prototype._Line_); CBDL.Graphics.DivDisplay.prototype._Line_.prototype.destroy = function() { if (this.data.parentNode) { this.data.parentNode.removeChild(this.data); } }; CBDL.Graphics.DivDisplay.prototype._Line_.prototype.setColor = function(color) { this.color = color; this.data.style.backgroundColor = this.color; }; CBDL.Graphics.DivDisplay.prototype.Font = function(family) { return (new CBDL.Graphics.BaseDisplay.prototype._Font_(family)); }; CBDL.Graphics.DivDisplay.prototype.String = function(text, font, size) { return (new CBDL.Graphics.DivDisplay.prototype._String_(this, text, font, size)); }; CBDL.Graphics.DivDisplay.prototype._String_ = function(display, text, font, size) { this.isDrawn = false; this.display = display; this.text = text; this.font = font; this.size = size; this.color = "black"; this.data = document.createElement("xmp"); // xmp is universally supported and displays contained content raw, so we use it this.data.style.padding = this.data.style.margin = 0; this.data.style.display = "block"; this.data.style.fontSize = size+"px"; this.data.style.fontFamily = font.family; this.data.style.color = "#000000"; this.data.innerHTML = text; }; CBDL.extend(CBDL.Graphics.BaseDisplay.prototype._String_, CBDL.Graphics.DivDisplay.prototype._String_); CBDL.Graphics.DivDisplay.prototype._String_.prototype.destroy = function() { if (this.data.parentNode) { this.data.parentNode.removeChild(this.data); } }; CBDL.Graphics.DivDisplay.prototype._String_.prototype.setText = function(text) { this.text = text; this.data.innerHTML = text; }; CBDL.Graphics.DivDisplay.prototype._String_.prototype.setSize = function(size) { this.size = size; this.data.style.fontSize = size+"px"; }; CBDL.Graphics.DivDisplay.prototype._String_.prototype.setColor = function(color) { this.color = color; this.data.style.color = color; }; CBDL.Graphics.Dispray = function(video_mode, target_element) { var _context = CBDL.Graphics; this.context = null; this.init = function() { try { this.element = document.createElement("canvas"); } catch (x) { this.element = null; } if (this.element == null) { // fallback to nasty divs this.element = document.createElement("div"); this.element.style.width = this.videomode.width; this.element.style.height = this.videomode.height; this.element.style.backgroundColor = 'black'; this.element.style.display = "block"; this.type = _context.DisplayType.DIV; } else { // using HTML5 canvas if (typeof G_vmlCanvasManager != "undefined") { // IE8, bleh G_vmlCanvasManager.initElement(this.element); } this.type = _context.DisplayType.CANVAS_2D; this.element.style.width = this.videomode.width; this.element.style.height = this.videomode.height; try { this.context = this.element.getContext("2d"); } catch (x) { this.context = null; } if (this.context == null) { } else { this.context.fillStyle = "#000000"; this.context.fillRect(0, 0, this.videomode.width, this.videomode.height); } } (target_element ? target_element : document.body).appendChild(this.element); }; this.Fill = function(red, green, blue) { var hex_value = ((1 << 24) + (red << 16) + (green << 8) + blue); var hex_string = hex_value.toString(16).substr(1); if (this.type == _context.DisplayType.DIV) { this.element.style.backgroundColor = '#'+hex_string; } else if (this.type == _context.DisplayType.CANVAS_2D) { //this.context.fillStyle = "#"+hex_string; //this.context.fillRect(0, 0, this.videomode.width, this.videomode.height); } }; if (video_mode instanceof CBDL.Graphics.VideoMode) { this.videomode = video_mode; this.init(); } } /* =============================================================================== CBDL.Graphics.VideoMode(width, height); Object which should be passed as the first parameter to Graphics.Display, defining the width and height of the Display. =============================================================================== */ CBDL.Graphics.VideoMode = function(width, height, flags) { this.width = width; this.height = height; this.flags = flags; return this; }; /* =============================================================================== CBDL.Graphics.Drawable(2dVector position, 2dVector scale, float rotation) Base class for all objects that can be drawn to a Graphics.Display. Usage: =============================================================================== */ CBDL.Graphics.Drawable = function(position, scale, rotation) { this.setPosition = function(x, y) { } this.setScale = function(x, y) { } this.setCenter = function(x, y) { } this.setRotation = function(rotation) { } }