1 /** 2 *Offers support for images in diagrams 3 *@this {CanvasImage} 4 *@constructor 5 *@param {Number} x 6 *@param {Number} y 7 *@param {String} src 8 *@author zack 9 **/ 10 function CanvasImage(x, y, src){ 11 this.img = null; 12 13 this.noImage = new Image(); 14 this.noImage.src = CanvasImage.NO_IMAGE; 15 16 this.src = src; 17 this.encoded = ""; 18 19 this.width = CanvasImage.DEFAULT_WIDTH; 20 this.height= CanvasImage.DEFAULT_WIDTH; 21 22 this.fixed = CanvasImage.FIXED_AUTO; 23 this.vector= [new Point(x,y), new Point(x,y-20), new Point(x+this.width, y+this.height)]; 24 25 this.gifTimer = null; 26 27 this.style = new Style(); 28 } 29 30 CanvasImage.DEFAULT_WIDTH = 100; 31 CanvasImage.NO_IMAGE = "assets/images/selectImage.gif"; 32 CanvasImage.LOADING_IMAGE = "assets/images/loading.gif"; 33 34 CanvasImage.FIXED_NONE = 0; 35 CanvasImage.FIXED_WIDTH = 1; 36 CanvasImage.FIXED_HEIGHT = 2; 37 CanvasImage.FIXED_BOTH = 3; 38 CanvasImage.FIXED_AUTO = 4; 39 40 41 /**Creates a {CanvasImage} out of JSON parsed object 42 *@param {JSONObject} o - the JSON parsed object 43 *@return {CanvasImage} a newly constructed Point 44 **/ 45 CanvasImage.load = function(o){ 46 var newCanvasImage = new CanvasImage(); 47 48 newCanvasImage.width = o.width; 49 newCanvasImage.height = o.height; 50 newCanvasImage.style = Style.load(o.style); 51 newCanvasImage.src = o.src; 52 53 return newCanvasImage; 54 } 55 56 57 CanvasImage.prototype = { 58 getFile:function(){ 59 return "" 60 }, 61 62 setFile:function(figure, file){ 63 this.src = ""; 64 this.noImage.src = CanvasImage.LOADING_IMAGE; 65 var primNum = 0; 66 for(var i = 0; i < figure.primitives.length; i++){ 67 if(figure.primitives[i] == this){ 68 primNum = i; 69 break; 70 } 71 } 72 $.ajaxFileUpload({ 73 url:'upload.php?figureID='+figure.id+'&primitive='+primNum, 74 dataType:'json', 75 fileElementId: 'fileToUpload', 76 secureuri: false, 77 success: function (data, status){ 78 var prim = stack.figureGetById(data.figure).primitives[data.primitive]; 79 prim.img = null; 80 prim.src = data.File; 81 prim.gifTimer = setTimeout("draw();",333); 82 }, 83 error: function (data, status, e){ 84 alert(e); 85 } 86 }) 87 return false; 88 }, 89 90 getURL:function(){ 91 return this.src; 92 }, 93 94 setURL:function(figure, url){ 95 this.img = null; 96 if(url != ""){ 97 this.encoded = ""; 98 } 99 if(this.src != url){ 100 this.image = null; 101 this.src = url; 102 } 103 }, 104 105 getEncoded:function(){ 106 return this.encoded; 107 }, 108 109 setEncoded:function(figure, encoded){ 110 if(encoded != ""){ 111 this.src = ""; 112 } 113 if(encoded != this.encoded){ 114 this.image = null; 115 this.encoded = encoded; 116 } 117 }, 118 119 drawImage:function(context, img){ 120 var fixed; 121 var sWidth; 122 var sHeight; 123 var dWidth; 124 var dHeight; 125 126 if(img == this.img){//if we are displaying a logo, use the selected scaling 127 fixed = this.fixed; 128 } 129 else{//otherwise (please select, loading), force fit 130 fixed = CanvasImage.FIXED_BOTH; 131 } 132 133 //determine auto width 134 if(img.width > img.height && fixed == CanvasImage.FIXED_AUTO){ 135 fixed = CanvasImage.FIXED_WIDTH; 136 } 137 else if(fixed == CanvasImage.FIXED_AUTO){ 138 fixed = CanvasImage.FIXED_HEIGHT; 139 } 140 141 //set up properties of source width, height and dest width and height, based on which dimension(s) are fixed 142 if(fixed == CanvasImage.FIXED_NONE){ 143 sHeight = Math.min(this.height, img.height); 144 dHeight = sHeight; 145 146 sWidth = Math.min(this.width, img.width); 147 dWidth = sWidth; 148 } 149 else if(fixed == CanvasImage.FIXED_BOTH){ 150 sHeight = img.height; 151 dHeight = this.height; 152 153 sWidth = img.width; 154 dWidth = this.width; 155 } 156 else if(fixed == CanvasImage.FIXED_WIDTH){ 157 var ratio = 100 / img.width * this.width; 158 sWidth = img.width; 159 dWidth = this.width; 160 161 sHeight = img.height; 162 if(this.height >= sHeight / 100 * ratio){ 163 dHeight = sHeight / 100 * ratio;//sWidth / 100 * ratio; 164 } 165 else{ 166 dHeight = this.height; 167 sHeight = this.height * 100 / ratio; 168 } 169 } 170 else if(fixed == CanvasImage.FIXED_HEIGHT){ 171 var ratio = 100 / img.height * this.height; 172 sHeight = img.height; 173 dHeight = this.height; 174 175 sWidth = img.width; 176 if(this.width >= sWidth / 100 * ratio){ 177 dWidth = sWidth / 100 * ratio;//sWidth / 100 * ratio; 178 } 179 else{ 180 dWidth = this.width; 181 sWidth = this.width * 100 / ratio; 182 } 183 }context.drawImage(img, 184 0, 0, //sx, sy 185 sWidth, 186 sHeight, 187 this.vector[0].x, this.vector[0].y, //dx,dy 188 dWidth, 189 dHeight 190 ); 191 if(img.src.indexOf(".gif") != -1){ 192 this.gifTimer = setTimeout("draw();",333); 193 } 194 }, 195 196 paint:function(context){ 197 //context.save(); 198 if(this.debug){ 199 //paint vector 200 context.beginPath(); 201 context.moveTo(this.vector[0].x,this.vector[0].y); 202 context.lineTo(this.vector[0].x+this.width,this.vector[0].y+this.height); 203 context.closePath(); 204 context.stroke(); 205 } 206 var angle = Util.getAngle(this.vector[0],this.vector[1]); 207 208 context.translate(this.vector[0].x,this.vector[0].y); 209 context.rotate(angle); 210 context.translate(-this.vector[0].x, -this.vector[0].y); 211 if(this.img == null){ 212 if(this.src != ""){ 213 this.img = new Image(); 214 /*this.img.onload = function(canvasImage){ 215 return function(event){ 216 if(img.) 217 canvasImage.drawImage(context, canvasImage.img); 218 } 219 }(this);*/ 220 this.img.src = "getImage.php?url="+this.src; 221 } 222 else if(this.encoded != ""){ 223 this.img = new Image(); 224 this.img.src = this.encoded; 225 } 226 this.drawImage(context, this.noImage); 227 } 228 else if(this.img.complete == false){ 229 this.noImage.src = CanvasImage.LOADING_IMAGE; 230 this.drawImage(context, this.noImage); 231 } 232 else{ 233 this.gifTimer = setTimeout("draw();",1);//its loaded lets make sure it is displayed 234 clearTimeout(this.gifTimer); 235 this.gifTimer = null; 236 this.drawImage(context, this.img); 237 } 238 239 //context.fill(); 240 //context.restore(); 241 }, 242 243 transform:function(matrix){ 244 this.vector[0].transform(matrix); 245 this.vector[1].transform(matrix); 246 this.vector[2].transform(matrix); 247 248 //now we need to get it's actual width and height, so lets rotate it back to 0 and set it's width and height 249 var angle = Util.getAngle(this.vector[0], this.vector[1]); 250 251 this.vector[0].transform(Matrix.rotationMatrix(-angle)); 252 this.vector[2].transform(Matrix.rotationMatrix(-angle)); 253 254 this.width = this.vector[2].x - this.vector[0].x; 255 this.height = this.vector[2].y - this.vector[0].y; 256 257 this.vector[0].transform(Matrix.rotationMatrix(angle)); 258 this.vector[2].transform(Matrix.rotationMatrix(angle)); 259 }, 260 261 getNormalBounds:function(){ 262 var poly = new Polygon(); 263 poly.addPoint(new Point(this.vector[0].x, this.vector[0].y)); 264 poly.addPoint(new Point(this.vector[0].x+this.width, this.vector[0].y)); 265 poly.addPoint(new Point(this.vector[0].x+this.width, this.vector[0].y+this.height)); 266 poly.addPoint(new Point(this.vector[0].x, this.vector[0].y+this.height)); 267 return poly; 268 }, 269 270 getBounds:function(){ 271 var angle = Util.getAngle(this.vector[0],this.vector[1]); 272 var nBounds = this.getNormalBounds(); 273 /*if(this.align == Text.ALIGN_LEFT){ 274 nBounds.transform(Matrix.translationMatrix(this.getNormalWidth()/2,0)); 275 } 276 if(this.align == Text.ALIGN_RIGHT){ 277 nBounds.transform(Matrix.translationMatrix(-this.getNormalWidth()/2,0)); 278 }*/ 279 nBounds.transform(Matrix.translationMatrix(-this.vector[0].x,-this.vector[0].y) ); 280 nBounds.transform(Matrix.rotationMatrix(angle)); 281 nBounds.transform(Matrix.translationMatrix(this.vector[0].x,this.vector[0].y)); 282 283 return nBounds.getBounds(); 284 }, 285 286 287 288 contains: function(x,y){ 289 var angle = Util.getAngle(this.vector[0],this.vector[1]); 290 var nBounds = this.getNormalBounds(); 291 nBounds.transform( Matrix.translationMatrix(-this.vector[0].x,-this.vector[0].y) ); 292 nBounds.transform(Matrix.rotationMatrix(angle)); 293 nBounds.transform(Matrix.translationMatrix(this.vector[0].x,this.vector[0].y)); 294 295 return nBounds.contains(x,y); 296 }, 297 298 299 near:function(x, y, radius){ 300 var angle = Util.getAngle(this.vector[0],this.vector[1]); 301 var nBounds = this.getNormalBounds(); 302 nBounds.transform( Matrix.translationMatrix(-this.vector[0].x,-this.vector[0].y) ); 303 nBounds.transform(Matrix.rotationMatrix(angle)); 304 nBounds.transform(Matrix.translationMatrix(this.vector[0].x,this.vector[0].y)); 305 306 return nBounds.near(x,y, radius); 307 }, 308 309 310 equals:function(anotherImage){ 311 if(!anotherImage instanceof CanvasImage){ 312 return false; 313 } 314 315 if( 316 this.img.src != anotherImage.img.src 317 || this.x != anotherImage.x 318 || this.y != anotherImage.y 319 || this.width != anotherImage.width 320 || this.height != anotherImage.height){ 321 return false; 322 } 323 324 325 for(var i=0; i<this.vector.length; i++){ 326 if(!this.vector[i].equals(anotherImage.vector[i])){ 327 return false; 328 } 329 } 330 331 if(!this.style.equals(anotherImage.style)){ 332 return false; 333 } 334 335 //TODO: compare styles too this.style = new Style(); 336 return true; 337 }, 338 339 340 clone: function(){ 341 throw 'Image:clone - not implemented'; 342 }, 343 344 345 toString:function(){ 346 return 'Image: ' + (this.img == null ? "null" : this.img.src) + ' x:' + this.vector[0].x + ' y:' + this.vector[0].y; 347 }, 348 349 350 getPoints:function(){ 351 return []; 352 } 353 }