1 // ---
  2 // Copyright (c) 2010 Francesco Cottone, http://www.kesiev.com/
  3 // ---
  4 
  5 /**
  6  * @namespace Tool module provides simple developing tools. Currently, this file only has a cel-composer: 
  7  * it can compose an image stacking a set of frames for animating objects, applying a 
  8  * number of filters to each frame.
  9  */
 10 var tool={
 11 	_images:[],
 12 	_loadedflag:[],
 13 	_data:{},
 14 	_count:0,
 15 	_countloaded:0,
 16 	
 17 	/**
 18 	* This function documents that an image in an animation sequence is loaded and checks if the other images are loaded or not
 19 	* @param {Object} id This is the object which is used as an id for keeping track of things related to this object in this function
 20 	*/
 21 	_loaded:function(id) {
 22 		this._loadedflag[id]=true;
 23 		tool._countloaded++;
 24 		document.title=tool._countloaded+"/"+tool._count;
 25 		for (var i=0;i<this._images.length;i++)
 26 			if (!this._loadedflag[i]) document.title+=this._images[i].src+", ";
 27 	},
 28 	
 29 	/**
 30 	* This checks that everything being kept track of with _count is loaded and depending on the result calls 
 31 	*/
 32 	_loadall:function() {
 33 		if (tool._count!=tool._countloaded)
 34 			setTimeout(tool._loadall,1000);
 35 		else
 36 			tool._allloaded();
 37 	},
 38 	
 39 	/**
 40 	* This makes the image cells for an animation and adds the load event listeners that the other stuff work to them. Calls loadall at the end.
 41 	* @param {Object} data This is the created animation data being passed in to be used by the function.
 42 	*/
 43 	makecels:function(data) {
 44 		this._data=data;
 45 		var id=0;
 46 		for (var r=0;r<data.rows.length;r++) {
 47 			for (var i=0;i<data.rows[r].length;i++) {
 48 				this._images[id]=new Image();
 49 				this._images[id].addEventListener('load', function(){tool._loaded(this.id)},false);
 50 				this._images[id].setAttribute("id",id);
 51 				this._images[id].src=data.rows[r][i].img;
 52 				this._count++;
 53 				id++;
 54 			}
 55 		}
 56 		this._loadall();
 57 	},
 58 	
 59 	/**
 60 	* @function
 61     * Creates and initializes the Canvas element. Is called from makecels. This function requires that this._data have been instantiated prior to function call.
 62 	*/
 63 	_allloaded:function() {
 64 		var data=this._data;
 65 		var wid=0;
 66 		var hei=0;
 67 		var curwid=0;
 68 		var id=0;
 69 		for (var r=0;r<data.rows.length;r++) {
 70 			hei+=this._images[id].height*1;
 71 			curwid=0;
 72 			for (var i=0;i<data.rows[r].length;i++) { curwid+=this._images[id].width*1; id++}
 73 			if (wid<curwid) wid=curwid;
 74 		}
 75 		
 76 		var cels=document.createElement("canvas");
 77 		cels.style.border="1px solid red";
 78 		cels.setAttribute('height',hei);
 79 		cels.setAttribute('width',wid);
 80 		document.body.appendChild(cels);
 81 		var ctx=cels.getContext("2d");
 82 	
 83 		var curx=0;
 84 		var cury=0;
 85 		id=0;
 86 		for (var r=0;r<data.rows.length;r++) {
 87 			curx=0;
 88 			for (var i=0;i<data.rows[r].length;i++) {
 89 				ctx.drawImage(this._images[id],curx,cury);
 90 				if (data.rows[r][i].filter) {
 91 					if (data.rows[r][i].filter) {
 92 						var imgd = ctx.getImageData(curx, cury, this._images[id].width, this._images[id].height);
 93 						var pix = imgd.data;
 94 
 95 						// Loop over each pixel and invert the color.
 96 						for (var z = 0, n = pix.length; z < n; z += 4) {
 97 							if (data.rows[r][i].filter.replace) {
 98 								for (var w=0;w<data.rows[r][i].filter.replace.length;w++) {
 99 									
100 									repl=data.rows[r][i].filter.replace[w].from;
101 									to=data.rows[r][i].filter.replace[w].to;
102 									if ((pix[z]==repl.r)&&(pix[z+1]==repl.g)&&(pix[z+2]==repl.b)&&(pix[z+3]==repl.a)) {
103 										pix[z  ] = to.r;
104 										pix[z+1] = to.g;
105 										pix[z+2] =to.b;
106 										pix[z+3] =to.a;
107 									}
108 								}
109 							}
110 							if (data.rows[r][i].filter.color&&(pix[z+3]!=0)) {
111 								pix[z  ] = data.rows[r][i].filter.color.r;
112 								pix[z+1] = data.rows[r][i].filter.color.g;
113 								pix[z+2] =data.rows[r][i].filter.color.b;
114 								pix[z+3] =data.rows[r][i].filter.color.a;
115 							}
116 							
117 							// i+3 is alpha (the fourth element)
118 						}
119 						ctx.putImageData(imgd, curx, cury);
120 					
121 					}
122 				}
123 				curx+=this._images[id].width*1;
124 				id++;
125 			}
126 			cury+=this._images[id-1].height*1;
127 		}
128 		
129 	}
130 
131 }
132