1 
  2 /**
  3  * @class canvas画布渲染器。所有可视对象将渲染在canvas画布上。
  4  * @augments Renderer
  5  * @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。
  6  * @module hilo/renderer/CanvasRenderer
  7  * @requires hilo/core/Class
  8  * @requires hilo/renderer/Renderer
  9  * @property {CanvasRenderingContext2D} context canvas画布的上下文。只读属性。
 10  */
 11 var CanvasRenderer = Class.create(/** @lends CanvasRenderer.prototype */{
 12     Extends: Renderer,
 13     constructor: function CanvasRenderer(properties){
 14         CanvasRenderer.superclass.constructor.call(this, properties);
 15 
 16         this.context = this.canvas.getContext("2d");
 17     },
 18 
 19     context: null,
 20 
 21     /**
 22      * @private
 23      * @see Renderer#startDraw
 24      */
 25     startDraw: function(target){
 26         if(target.visible && target.alpha > 0){
 27             if(target === this.stage){
 28                 this.context.clearRect(0, 0, target.width, target.height);
 29             }
 30             this.context.save();
 31             return true;
 32         }
 33         return false;
 34     },
 35 
 36     /**
 37      * @private
 38      * @see Renderer#draw
 39      */
 40     draw: function(target){
 41         var ctx = this.context, w = target.width, h = target.height;
 42 
 43         //draw background fill
 44         var bgFill = target.bgFill;
 45         if(bgFill){
 46             ctx.fillStyle = bgFill.style;
 47             ctx.fillRect(bgFill.x, bgFill.y,  bgFill.width || w, bgFill.height || h);
 48         }
 49 
 50         //draw image
 51         var drawable = target.drawable;
 52         if(drawable && drawable.image){
 53             var rect = drawable.rect, sw = rect[2], sh = rect[3];
 54             if(!w && !h){
 55                 //fix width/height TODO: how to get rid of this?
 56                 target.width = rect[2];
 57                 target.height = rect[3];
 58             }
 59             ctx.drawImage(drawable.image, rect[0], rect[1], sw, sh, 0, 0, w, h);
 60         }
 61     },
 62 
 63     /**
 64      * @private
 65      * @see Renderer#endDraw
 66      */
 67     endDraw: function(target){
 68         this.context.restore();
 69     },
 70 
 71     /**
 72      * @private
 73      * @see Renderer#transform
 74      */
 75     transform: function(target){
 76         var ctx = this.context,
 77             scaleX = target.scaleX,
 78             scaleY = target.scaleY;
 79         
 80         if(target === this.stage){
 81             var style = this.canvas.style,
 82                 oldScaleX = target._scaleX,
 83                 oldScaleY = target._scaleY;
 84 
 85             if((!oldScaleX && scaleX != 1) || (oldScaleX && oldScaleX != scaleX)){
 86                 target._scaleX = scaleX;
 87                 style.width = scaleX * target.width + "px";
 88             }
 89             if((!oldScaleY && scaleY != 1) || (oldScaleY && oldScaleY != scaleY)){
 90                 target._scaleY = scaleY;
 91                 style.height = scaleY * target.height + "px";
 92             }
 93         }else{
 94             var x = target.x,
 95                 y = target.y,
 96                 pivotX = target.pivotX,
 97                 pivotY = target.pivotY,
 98                 rotation = target.rotation % 360;
 99 
100             if(x != 0 || y != 0) ctx.translate(x, y);
101             if(rotation != 0) ctx.rotate(rotation * Math.PI / 180);
102             if(scaleX != 1 || scaleY != 1) ctx.scale(scaleX, scaleY);
103             if(pivotX != 0 || pivotY != 0) ctx.translate(-pivotX, -pivotY);
104         }
105         
106         if(target.alpha > 0) ctx.globalAlpha *= target.alpha;
107     },
108 
109     /**
110      * @private
111      * @see Renderer#remove
112      */
113     remove: function(target){
114         if(target instanceof DOMElement){
115             var elem = target.drawable.domElement,
116                 parentElem = elem && elem.parentNode;
117             if(parentElem){
118                 parentElem.removeChild(elem);
119             }
120         }
121     },
122 
123     /**
124      * @private
125      * @see Renderer#clear
126      */
127     clear: function(x, y, width, height){
128         this.context.clearRect(x, y, width, height);
129     }
130 });