1 // JavaScript Document
  2 /**
  3  * canvas user interface.
  4  * @constructor
  5  */
  6 function Y2DCanvasUI2(canvas){
  7 	this.canvas			= canvas&&canvas.tagName ? canvas : document.getElementById(canvas);
  8 //	this.canvas			= YDom.get(canvas);
  9 	this.context		= this.canvas.getContext("2d");
 10 	this.cpile			= new YCallPile(this);
 11 	this.waitingUrls	= 0;
 12 	this.waitingFlush	= false;
 13 	this.styleLibs=[];
 14 	this.addStyle=function(name,styleObj){
 15 		var lib = {};
 16 		for(var i in styleObj){
 17 			switch(i){
 18 				case 'borderWidth':
 19 				case 'lineWidth':
 20 				case 'width':
 21 					lib.lineWidth = styleObj[i]
 22 					break;
 23 				case 'borderColor':
 24 				case 'strokeStyle':
 25 					lib.strokeStyle = styleObj[i]
 26 					break;
 27 				case 'backgroundColor':
 28 				case 'color':
 29 				case 'fillStyle':
 30 					lib.fillStyle = styleObj[i]
 31 					break;
 32 				case 'backgroundImage':
 33 				case 'image':
 34 					var url = styleObj[i].indexOf('url(')>-1?
 35 								str.substring(styleObj[i].indexOf("(")+1,styleObj[i].lastIndexOf(")"))
 36 								: styleObj[i];
 37 					var lobj = {name:name,url:url,owner:this,styleObj:styleObj};
 38 					this.waitingUrls++;
 39 					YLoader.loadImg(url,function(img,ldr,dat){
 40 						dat.owner.__on_img_load(img,ldr,dat);
 41 					},lobj);
 42 					break;
 43 				case 'font':
 44 				case 'fontFamily':
 45 					lib.font = styleObj[i]
 46 					break;
 47 				case 'linearGradient':
 48 					break;
 49 				case 'radialGradient':
 50 					//lib.fillStyle = styleObj[i]
 51 					break;
 52 			}
 53 		}
 54 		this.styleLibs[name]=lib;
 55 	};
 56 	/*@ignore*/
 57 	this.__on_img_load=function(img,ldr,dat){
 58 		this.waitingUrls--;
 59 		var lib		= this.styleLibs[dat.name];
 60 		
 61 		if(dat.styleObj['imageCrop']&&!dat.ii){
 62 			dat.crop	= dat.styleObj['imageCrop'];
 63 			dat.ii		= new YImageInfo();
 64 			dat.ii.load(img.src,function(own,dat){
 65 				var img = dat.ii.subimage(dat.crop[0],dat.crop[1],dat.crop[2],dat.crop[3]);
 66 				own.__on_img_load(img,null,dat);
 67 			},dat);
 68 		}else{
 69 			var pattern	= this.context.createPattern(img, "repeat");
 70 			lib.fillStyle = pattern;
 71 			if(this.waitingUrls==0&&this.waitingFlush){
 72 				this.flush();
 73 			}
 74 		}
 75 		
 76 	};
 77 	this.setStyle=function(name){
 78 		if(this.styleLibs[name]){
 79 			var lib = this.styleLibs[name];
 80 			if(!lib.lineWidth)this.context.lineWidth=0;
 81 			for(var i in lib){	
 82 				if(i=='linear'||i=='radial'){
 83 					var grd = i=='linear'?
 84 								  this.context.createLinearGradient(lib[i].from[0],lib[i].from[1], lib[i].to[0],lib[i].to[1])
 85 								: this.context.createRadialGradient(lib[i].from[0],lib[i].from[1],lib[i].from[2],
 86 																	lib[i].to[0],lib[i].to[1],lib[i].to[2]);
 87 					for(var j in lib[i].colors){
 88 						grd.addColorStop(lib[i].colors[j].at,lib[i].colors[j].color);
 89 					}
 90 				}
 91 				this.context[i]=lib[i];
 92 			}
 93 		}
 94 	};
 95 	this._styleHasStroke=function(name){
 96 		return this.styleLibs[name]&&this.styleLibs[name].lineWidth;
 97 	};
 98 	this.clear=function(){
 99 		this.context.clearRect ( 0 , 0 , this.canvas.width , this.canvas.height );
100 	};
101 	this._styleHasFill=function(name){
102 		return this.styleLibs[name]&&this.styleLibs[name].fillStyle;
103 	};
104 	this.path=function(vList){
105 		this.context.moveTo(vList[0][0],vList[0][1]);
106 		for(var i=1;i<vList.length;i++){//alert('path '+i);
107 			var next = vList[i];
108 			if(next.length==2){
109 				this.context.lineTo(next[0],next[1]);
110 			}else if(next.length==4){
111 				this.context.quadraticCurveTo(next[0],next[1],next[2],next[3]);
112 			}else if(next.length==6){
113 				this.context.bezierCurveTo(next[0],next[1],next[2],next[3],next[4],next[5]);
114 			}
115 		}
116 	};
117 	this.strip=function(vList,styleName){
118 		if(!this.flushing){
119 			this.cpile.call('strip',[vList,styleName]);
120 		}else{
121 			this.context.beginPath();
122 			this.setStyle(styleName);
123 			this.path(vList);
124 			if(this._styleHasStroke(styleName))this.context.stroke();
125 			if(this._styleHasFill(styleName)){
126 				this.context.fill();
127 				this.context.closePath();
128 			}
129 		}
130 	};
131 	this.text=function(text,vxy,styleName){
132 		if(!this.flushing){
133 			this.cpile.call('text',[text,vxy,styleName]);
134 		}else{
135 			this.setStyle(styleName);
136 			this.context.fillText(text, vxy[0], vxy[1]);
137 		}
138 	};
139 	this.rect=function(vxy,vwh,styleName){
140 		var vlist = [
141 			[vxy[0]			,vxy[1]			],
142 			[vxy[0]+vwh[0]	,vxy[1]			],
143 			[vxy[0]+vwh[0]	,vxy[1]+vwh[1]	],
144 			[vxy[0]			,vxy[1]+vwh[1]	],
145 			[vxy[0]			,vxy[1]			]
146 		];
147 		this.strip(vlist,styleName);
148 	};
149 	this.flush=function(){
150 		if(this.waitingUrls>0){
151 			this.waitingFlush	= true;
152 		}else{
153 			this.flushing		= true;
154 			this.cpile.fire();
155 			this.cpile.fired	= false;
156 			this.flushing		= false;
157 		}
158 	};
159 };
160 /**
161  * image info.
162  * @constructor
163  */
164 var YImageInfo = function(){
165 	this.url		= "";
166 	this.size		= [];
167 	this.image		= null;
168 	this.imagedata	= null;
169 	this.pixels		= [];
170 	this.loaded		= false;
171 	this.domElement	= null;
172 };
173 YImageInfo.prototype = {
174 	constructor		: YImageInfo,
175 	constructorName : "YImageInfo",
176 	getPixel		: function(vxy){
177 		if(this.loaded && (vxy[0]>=0&&vxy[0]<this.size[0]) && (vxy[1]>=0&&vxy[1]<this.size[1])){
178 			var ipixi = vxy[0]+this.size[0]*vxy[1];
179 			return	 [	this.pixels[ipixi*4+0],this.pixels[ipixi*4+1],
180 						this.pixels[ipixi*4+2],this.pixels[ipixi*4+3]];
181 		}else return [0,0,0,0];	
182 	},
183 	subimage : function(x,y,w,h){
184 		var canvas		= YDom.create('canvas',{width:w,height:h});
185 		var imageData	= this.domElement.getContext("2d").getImageData(x,y,w,h);
186 		canvas.getContext("2d").putImageData(imageData, 0, 0);
187 		var dataURL = canvas.toDataURL();
188 		return YDom.create('img',{width:w,height:h,src : dataURL});
189 	},
190 	load : function(url,onmLoad,datas){
191 		this.url	= url;
192 		var obj = {
193 			onmLoad	: onmLoad,
194 			datas	: datas,
195 			own		: this
196 		};
197 		this.onLoad = onmLoad;
198 		this.datas	= datas;
199 		YLoader.loadImg(this.url,function(img,ldr,dat){dat.own._on_load(img,dat.onmLoad,dat.datas);},obj);
200 	},
201 	_on_load : function(img,onmLoad,datas){
202 		this.loaded		= true;
203 		this.image		= img;
204 		var str="";for(var i in this.image)str+=i+"\n";
205 		this.size		= [img.width,img.height];
206 		this.domElement	= YDom.create('canvas',{width:this.size[0],height:this.size[1]});
207 		var context		= this.domElement.getContext("2d");
208 		context.drawImage(img, 0, 0);
209 		this.imagedata 	= context.getImageData(0, 0, this.size[0], this.size[1]);
210 		this.pixels 	= this.imagedata.data;
211 		//context.drawImage(context.getImageData(0, 0, this.size[0], this.size[1]), 0, 0);
212 		onmLoad(this,datas);
213 	}
214 };