1 /* Name: Graphics Module 2 Date: April 2011 3 Description: Main module for the UniPlay graphics (2D/Sprite) functionality 4 Dependencies: <none> 5 Children: <none> */ 6 7 /* Sprite object 8 Properies: visible, path, origWidth, origHeight, 9 scaleWidth, scaleHeight, angle, alpha 10 Methods: load, draw, show, hide, scale */ 11 12 /** 13 * Creates an instance of a Sprite 14 * 15 * @constructor 16 * @this {Sprite} 17 * @param {String} path Path to sprite image file. 18 * @see graphics.js 19 */ 20 function Sprite(path) { 21 /** 22 * Path to sprite image file. 23 * 24 * @type String 25 */ 26 this.path = path; 27 28 /** 29 * Image array for animated sprites. 30 * 31 * @type Array 32 */ 33 this.image = []; 34 35 /** 36 * Sprite visible property. 37 * 38 * @type Boolean 39 */ 40 this.visible = true; 41 42 /** 43 * Starting angle value for rotation. 44 * 45 * @type Number 46 */ 47 this.angle = null; 48 49 /** 50 * Alpha transparency value. 51 * 52 * @type Number 53 */ 54 this.alpha = 1.0; 55 56 /** 57 * Sprite image index. 58 * 59 * @type Number 60 */ 61 this.imageindex = 0; 62 63 /** 64 * Number of sprites in current Sprite object. 65 * 66 * @type Number 67 */ 68 this.nsprites = 0; 69 70 /** 71 * Current sprite X position. 72 * 73 * @type Number 74 */ 75 this.x = 0; 76 77 /** 78 * Current sprite Y position. 79 * 80 * @type Number 81 */ 82 this.y = 0; 83 84 85 /** 86 * Load sprite image file from the path given in {@link #path}. 87 * 88 * @this {Sprite} 89 */ 90 this.load = function() { 91 this.image[0] = new Image(); 92 this.image[0].src = this.path; 93 94 this.origWidth = this.image[0].width; 95 this.origHeight = this.image[0].height; 96 97 this.scaleWidth = this.origWidth; 98 this.scaleHeight = this.origHeight; 99 100 this.nsprites++; 101 }; 102 103 /** Load in sprite on instantiation */ 104 this.load(); 105 106 /** 107 * Add a sprite to the sprite {@link #image} Array. 108 * <i>Used to create animated sprites.</i> 109 * @param {String} path Path to sprite image file. 110 * @this {Sprite} 111 */ 112 this.add = function(path) { 113 this.image[this.nsprites] = new Image(); 114 this.image[this.nsprites].src = path; 115 this.nsprites++; 116 }; 117 118 /** 119 * Cycle through sprites in {@link #image} Array. 120 * <i>Used to play animated sprites.</i> 121 * @this {Sprite} 122 */ 123 this.cycle = function() { 124 this.imageindex++; 125 126 if (this.imageindex === this.nsprites){ 127 this.imageindex = 0; 128 } 129 }; 130 131 /** 132 * Set a sprites current image. 133 * <i>Used to set animated sprite image.</i> 134 * @param {Number} i Index of image in {@link #image} Array. 135 * @this {Sprite} 136 */ 137 this.setSpriteIndex = function(i){ 138 this.imageindex = i; 139 }; 140 141 /** 142 * Draw sprite on Canvas 2D context. 143 * 144 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D context to draw onto. 145 * @this {Sprite} 146 */ 147 this.draw = function(ctx){ 148 if (ctx){ 149 if (ctx.drawImage){ 150 if (this.visible === true){ 151 var previousAlpha = ctx.globalAlpha; 152 ctx.globalAlpha = this.alpha; 153 154 if (this.angle != null){ 155 ctx.save(); 156 ctx.translate(this.x+(this.scaleWidth/2),this.y+(this.scaleHeight/2)); 157 ctx.rotate(this.angle); 158 ctx.translate(-this.x-(this.scaleWidth/2),-this.y-(this.scaleHeight/2)); 159 } 160 161 ctx.drawImage(this.image[this.imageindex],this.x,this.y,this.scaleWidth,this.scaleHeight); 162 163 if (this.angle != null){ 164 ctx.restore(); 165 } 166 167 ctx.globalAlpha = previousAlpha; 168 } 169 } 170 } 171 }; 172 173 /** 174 * Set sprite to be visible when drawing. 175 * 176 * @this {Sprite} 177 */ 178 this.show = function(){ 179 this.visible = true; 180 }; 181 182 /** 183 * Set sprite to be invisible when drawing. 184 * 185 * @this {Sprite} 186 */ 187 this.hide = function(){ 188 this.visible = false; 189 }; 190 191 /** 192 * Scale sprite when drawing by width and height. 193 * 194 * @param {Number} width Width to scale sprite by. 195 * @param {Number} height Height to scale sprite by. 196 * @this {Sprite} 197 */ 198 this.scale = function(width,height){ 199 this.scaleWidth = width; 200 this.scaleHeight = height; 201 }; 202 203 /** 204 * Rotate sprite when drawing. 205 * 206 * @param {Number} angle Angle of rotation in degrees. 207 * @this {Sprite} 208 */ 209 this.rotate = function(angle) { 210 this.angle = angle*(Math.PI/180); 211 }; 212 213 /** 214 * Set alpha transparency of sprite. 215 * 216 * @param {Number} value Transparency value from 0.0 to 1.0 217 * @this {Sprite} 218 */ 219 this.transparency = function(value){ 220 this.alpha = value; 221 }; 222 223 /** 224 * Set sprite position using cartesian coordinates. 225 * 226 * @param {Number} x Set sprite X axis position. 227 * @param {Number} y Set sprite Y axis position. 228 * @this {Sprite} 229 */ 230 this.setPosition = function(x,y){ 231 this.x = x; 232 this.y = y; 233 }; 234 235 /** 236 * Return visible property stored in {@link #visible}. 237 * @return {Boolean} Boolean denoting visible property. 238 * @this {Sprite} 239 */ 240 this.getVisible = function(){ 241 return this.visible; 242 }; 243 244 /** 245 * Return angle of sprite value stored in {@link #angle}. 246 * @return {Number} Number denoting angle of sprite. 247 * @this {Sprite} 248 */ 249 this.getAngle = function(){ 250 return this.angle; 251 }; 252 253 /** 254 * Return alpha transparency value stored in {@link #alpha}. 255 * @return {Number} Number denoting alpha transparency value. 256 * @this {Sprite} 257 */ 258 this.getTransparency = function(){ 259 return this.alpha; 260 }; 261 262 /** 263 * Return sprite image index value stored in {@link #imageindex}. 264 * @return {Number} Number denoting image index value. 265 * @this {Sprite} 266 */ 267 this.getImageIndex = function(){ 268 return this.imageindex; 269 }; 270 271 /** 272 * Return number of sprites value stored in {@link #nsprites}. 273 * @return {Number} Number denoting number of sprites value. 274 * @this {Sprite} 275 */ 276 this.getNumSprites = function(){ 277 return this.nsprites; 278 }; 279 280 /** 281 * Return sprite x axis cartesian co-ordinate value stored in {@link #x}. 282 * @return {Number} Number denoting sprite x axis cartesian co-ordinate value. 283 * @this {Sprite} 284 */ 285 this.getX = function(){ 286 return this.x; 287 }; 288 289 /** 290 * Return sprite y axis cartesian co-ordinate value stored in {@link #y}. 291 * @return {Number} Number denoting sprite y axis cartesian co-ordinate value. 292 * @this {Sprite} 293 */ 294 this.getY = function(){ 295 return this.y; 296 }; 297 } 298 299 /** 300 * Creates an instance of the Drawing object 301 * 302 * @constructor 303 * @this {Drawing} 304 * @see graphics.js 305 */ 306 307 function Drawing() { 308 /** 309 * RGB line colour property. 310 * 311 * @type Number 312 */ 313 this.rgbLine = "rgb(255,255,255)"; 314 315 /** 316 * Line red colour property. 317 * 318 * @type Number 319 */ 320 this.lineR = 255; 321 322 /** 323 * Line green colour property. 324 * 325 * @type Number 326 */ 327 this.lineG = 255; 328 329 /** 330 * Line blue colour property. 331 * 332 * @type Number 333 */ 334 this.lineB = 255; 335 336 /** 337 * RGB fill colour property. 338 * 339 * @type Number 340 */ 341 this.rgbFill = "rgb(255,255,255)"; 342 343 /** 344 * Fill red colour property. 345 * 346 * @type Number 347 */ 348 this.fillR = 255; 349 350 /** 351 * Fill green colour property. 352 * 353 * @type Number 354 */ 355 this.fillG = 255; 356 357 /** 358 * Fill blue colour property. 359 * 360 * @type Number 361 */ 362 this.fillB = 255; 363 364 /** 365 * Current font face property. e.g "Verdana" 366 * 367 * @type String 368 */ 369 this.currentFont = ""; 370 371 /** 372 * Current font size property. e.g. 14 373 * 374 * @type Number 375 */ 376 this.fontSize = 0; 377 378 /** 379 * Current font style property. e.g. "bold" 380 * 381 * @type String 382 */ 383 this.fontStyle = ""; 384 385 /** 386 * Previous RGB fill style. 387 * 388 * @type String 389 */ 390 this.prevFillRGB = ""; 391 392 /** 393 * Drawing transparency (alpha) value. 394 * 395 * @type Number 396 */ 397 this.alpha = 1.0; 398 399 /** 400 * Text drawing function. 401 * <i>Note: uses all font property values to draw text.</i> 402 * @param {[object CanvasRenderingContext2D]} ctx Canvas drawing context. 403 * @param {String} string String for text to draw. 404 * @param {Number} x X axis coordinate to draw text at. 405 * @param {Number} y Y axis coordinate to draw text at. 406 * @this {Drawing} 407 */ 408 this.text = function(ctx,string,x,y) { 409 if (ctx){ 410 var previousAlpha = ctx.globalAlpha; 411 ctx.globalAlpha = this.alpha; 412 413 this.prevFillRGB = ctx.fillStyle; 414 415 ctx.fillStyle = this.rgbFill; 416 ctx.font = this.fontStyle + " " + this.fontSize + "px " + this.currentFont; 417 ctx.fillText(string, x, y); 418 419 ctx.fillStyle = this.prevFillRGB; 420 421 ctx.globalAlpha = previousAlpha; 422 } 423 }; 424 425 /** 426 * Set the font face. e.g "Verdana" 427 * 428 * @param {String} string String denoting font face. 429 * @this {Drawing} 430 */ 431 this.setFontFace = function(string) { 432 this.currentFont = string; 433 }; 434 435 /** 436 * Set the font size. e.g. 11 437 * 438 * @param {Number} integer Number denoting font size. 439 * @this {Drawing} 440 */ 441 this.setFontSize = function(number) { 442 this.fontSize = number; 443 }; 444 445 /** 446 * Set the font style. e.g. "bold" 447 * 448 * @param {String} string String denoting font style. 449 * @this {Drawing} 450 */ 451 this.setFontStyle = function(string) { 452 this.fontStyle = string; 453 }; 454 455 /** 456 * Pixel drawing function. 457 * 458 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D rendering context. 459 * @param {ImageData} id Image data object. 460 * @param {ImageData.data} pix ImageData.data object. 461 * @param {Number} x X axis coordinate to draw pixel at. 462 * @param {Number} y Y axis coordinate to draw pixel at. 463 * @this {Drawing} 464 */ 465 this.pixel = function(ctx,id,pix,x,y) { 466 if (ctx){ 467 var previousAlpha = ctx.globalAlpha; 468 ctx.globalAlpha = this.alpha; 469 470 pix[0] = this.fillR; 471 pix[1] = this.fillG; 472 pix[2] = this.fillB; 473 pix[3] = 255; 474 ctx.putImageData(id,x,y); 475 476 ctx.globalAlpha = previousAlpha; 477 } 478 }; 479 480 /** 481 * Line drawing function. 482 * 483 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D rendering context. 484 * @param {Number} x1 X1 axis coordinate to start line at. 485 * @param {Number} y1 Y1 axis coordinate to start line at. 486 * @param {Number} x2 X2 axis coordinate to end line at. 487 * @param {Number} y2 Y2 axis coordinate to end line at. 488 * @this {Drawing} 489 */ 490 this.line = function(ctx,x1,y1,x2,y2) { 491 if (ctx){ 492 var previousAlpha = ctx.globalAlpha; 493 ctx.globalAlpha = this.alpha; 494 495 ctx.strokeStyle = this.rgbLine; 496 ctx.beginPath(); 497 ctx.moveTo(x1,y1); 498 ctx.lineTo(x2,y2); 499 ctx.closePath(); 500 ctx.stroke(); 501 502 ctx.globalAlpha = previousAlpha; 503 } 504 }; 505 506 /** 507 * Box (rectangle) drawing function. 508 * 509 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D rendering context. 510 * @param {Number} x X axis coordinate to start box drawing at. 511 * @param {Number} y Y axis coordinate to start box drawing at. 512 * @param {Number} width Width of box. 513 * @param {Number} height Height of box. 514 * @param {Boolean} fill Boolean denoting if the box should be filled or empty. 515 * @this {Drawing} 516 */ 517 this.box = function(ctx,x,y,width,height,fill) { 518 if (ctx){ 519 var previousAlpha = ctx.globalAlpha; 520 ctx.globalAlpha = this.alpha; 521 522 if (fill){ 523 ctx.fillStyle = this.rgbFill; 524 ctx.fillRect(x,y,width,height); 525 } else { 526 ctx.strokeRect(x,y,width,height); 527 } 528 529 ctx.globalAlpha = previousAlpha; 530 } 531 }; 532 533 /** 534 * Circle drawing function. 535 * 536 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D rendering context. 537 * @param {Number} x X axis coordinate to start circle drawing at. 538 * @param {Number} y Y axis coordinate to start circle drawing at. 539 * @param {Number} radius Radius of circle. 540 * @param {Boolean} fill Boolean denoting if the circle should be filled or empty. 541 * @this {Drawing} 542 */ 543 this.circle = function(ctx,x,y,radius,fill) { 544 if (ctx){ 545 var previousAlpha = ctx.globalAlpha; 546 ctx.globalAlpha = this.alpha; 547 548 ctx.fillStyle = this.rgbFill; 549 ctx.strokeStyle = this.rgbLine; 550 ctx.save(); 551 ctx.beginPath(); 552 ctx.arc(x, y, radius, 0, Math.PI*2, true); 553 ctx.closePath(); 554 ctx.restore(); 555 if (fill){ 556 ctx.fill(); 557 } else { 558 ctx.stroke(); 559 } 560 ctx.restore(); 561 562 ctx.globalAlpha = previousAlpha; 563 } 564 }; 565 566 567 /** 568 * Ellipse drawing function. 569 * 570 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D rendering context. 571 * @param {Number} x X axis coordinate to start ellipse drawing at. 572 * @param {Number} y Y axis coordinate to start ellipse drawing at. 573 * @param {Number} radiusx X axis radius of ellipse. 574 * @param {Number} radiusy Y axis radius of ellipse. 575 * @param {Boolean} fill Boolean denoting if the ellipse should be filled or empty. 576 * @this {Drawing} 577 */ 578 this.ellipse = function(ctx,x,y,radiusx,radiusy,fill) { 579 if (ctx){ 580 var previousAlpha = ctx.globalAlpha; 581 ctx.globalAlpha = this.alpha; 582 583 ctx.save(); 584 ctx.save(); 585 ctx.beginPath(); 586 ctx.translate(x, y); 587 ctx.scale(radiusx, radiusy); 588 ctx.arc(0, 0, 1, 0, 2*Math.PI, false); 589 ctx.closePath(); 590 ctx.restore(); 591 if (fill) 592 ctx.fill(); 593 ctx.stroke(); 594 ctx.restore(); 595 596 ctx.globalAlpha = previousAlpha; 597 } 598 }; 599 600 /** 601 * Set RGB line colour. 602 * 603 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D rendering context. 604 * @param {Number} r Red line colour value. 605 * @param {Number} g Green line colour value. 606 * @param {Number} b Blue line colour value. 607 * @this {Drawing} 608 */ 609 this.setRGBLine = function(ctx,r,g,b) { 610 if (ctx){ 611 this.rgbLine = "rgb(" + r + "," + g + "," + b + ")"; 612 this.lineR = r; 613 this.lineG = g; 614 this.lineB = b; 615 } 616 }; 617 618 /** 619 * Set RGB fill colour. 620 * 621 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D rendering context. 622 * @param {Number} r Red fill colour value. 623 * @param {Number} g Green fill colour value. 624 * @param {Number} b Blue fill colour value. 625 * @this {Drawing} 626 */ 627 this.setRGBFill = function(ctx,r,g,b) { 628 if (ctx){ 629 this.rgbFill = "rgb(" + r + "," + g + "," + b + ")"; 630 this.fillR = r; 631 this.fillG = g; 632 this.fillB = b; 633 } 634 }; 635 636 /** 637 * Clear the Canvas drawing context. 638 * 639 * @param {[object CanvasRenderingContext2D]} ctx Canvas 2D rendering context. 640 * @this {Drawing} 641 */ 642 this.cls = function(ctx) { 643 if (ctx){ 644 ctx.strokeStyle = this.rgbFill; 645 ctx.fillStyle = this.rgbFill; 646 ctx.clearRect(0, 0, ctx.canvas.offsetWidth, ctx.canvas.offsetHeight); 647 } 648 }; 649 650 /** 651 * Set the drawing transparency (alpha) value. 652 * 653 * @param {Number} value Transparency (alpha) value. 654 * @this {Drawing} 655 */ 656 this.transparency = function(value){ 657 this.alpha = value; 658 }; 659 660 /** 661 * Return the RGB value of a pixel as a string. 662 * @return {String} String denoting pixel RGB value. 663 * @this {Drawing} 664 */ 665 this.getPixelRGB = function(ctx,x,y) { 666 if (ctx){ 667 var getImgData = ctx.getImageData(x,y,1,1); 668 return "rgb(" + getImgData.data[0] + "," + getImgData.data[1] + "," + getImgData.data[2] + ")"; 669 } 670 }; 671 672 /** 673 * Return the RGB value of the line colour as a 3 element array. 674 * @return {Array} 3 element array with red, green and blue line colours. 675 * @this {Drawing} 676 */ 677 this.getRGBLine = function(){ 678 return [lineR,lineG,lineB]; 679 }; 680 681 /** 682 * Return the RGB value of the fill colour as a 3 element array. 683 * @return {Array} 3 element array with red, green and blue fill colours. 684 * @this {Drawing} 685 */ 686 this.getRGBFill = function(){ 687 return [fillR,fillG,fillB]; 688 }; 689 690 /** 691 * Return the current font face. 692 * @return {String} String denoting current font face. 693 * @this {Drawing} 694 */ 695 this.getCurrentFont = function(){ 696 return this.currentFont; 697 }; 698 699 /** 700 * Return the current font size. 701 * @return {Number} Number denoting current font size. 702 * @this {Drawing} 703 */ 704 this.getFontSize = function(){ 705 return this.fontSize; 706 }; 707 708 /** 709 * Return the current font style. 710 * @return {String} String denoting current font style. 711 * @this {Drawing} 712 */ 713 this.getFontStyle = function(){ 714 return this.fontStyle; 715 }; 716 717 /** 718 * Return the current drawing transparency (alpha) value. 719 * @return {Number} Number denoting current drawing transparency (alpha) value. 720 * @this {Drawing} 721 */ 722 this.getTransparency = function(){ 723 return this.alpha; 724 }; 725 }