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 };