1 /** 2 * Hilo 3 * Copyright 2015 alibaba.com 4 * Licensed under the MIT License 5 */ 6 7 /** 8 * @language=en 9 * @class CanvasRenderer CanvasRenderer, all the visual object is drawing on the canvas element.The stage will create different renderer depend on the canvas and renderType properties, developer need not use this class directly. 10 * @augments Renderer 11 * @param {Object} properties The properties to create a renderer, contains all writeable props of this class. 12 * @module hilo/renderer/CanvasRenderer 13 * @requires hilo/core/Class 14 * @requires hilo/core/Hilo 15 * @requires hilo/renderer/Renderer 16 * @property {CanvasRenderingContext2D} context The context of the canvas element, readonly. 17 */ 18 var CanvasRenderer = Class.create(/** @lends CanvasRenderer.prototype */{ 19 Extends: Renderer, 20 constructor: function(properties){ 21 CanvasRenderer.superclass.constructor.call(this, properties); 22 23 this.context = this.canvas.getContext("2d"); 24 }, 25 renderType:'canvas', 26 context: null, 27 28 /** 29 * @private 30 * @see Renderer#startDraw 31 */ 32 startDraw: function(target){ 33 if(target.visible && target.alpha > 0){ 34 if(target === this.stage){ 35 this.context.clearRect(0, 0, target.width, target.height); 36 } 37 this.context.save(); 38 return true; 39 } 40 return false; 41 }, 42 43 /** 44 * @private 45 * @see Renderer#draw 46 */ 47 draw: function(target){ 48 var ctx = this.context, w = target.width, h = target.height; 49 50 //draw background 51 var bg = target.background; 52 if(bg){ 53 ctx.fillStyle = bg; 54 ctx.fillRect(0, 0, w, h); 55 } 56 57 //draw image 58 var drawable = target.drawable, image = drawable && drawable.image; 59 if(image){ 60 var rect = drawable.rect, sw = rect[2], sh = rect[3], offsetX = rect[4], offsetY = rect[5]; 61 //ie9+浏览器宽高为0时会报错 fixed ie9 bug. 62 if(!sw || !sh){ 63 return; 64 } 65 if(!w && !h){ 66 //fix width/height TODO: how to get rid of this? 67 w = target.width = sw; 68 h = target.height = sh; 69 } 70 //the pivot is the center of frame if has offset, otherwise is (0, 0) 71 if(offsetX || offsetY) ctx.translate(offsetX - sw * 0.5, offsetY - sh * 0.5); 72 ctx.drawImage(image, rect[0], rect[1], sw, sh, 0, 0, w, h); 73 } 74 }, 75 76 /** 77 * @private 78 * @see Renderer#endDraw 79 */ 80 endDraw: function(target){ 81 this.context.restore(); 82 }, 83 84 /** 85 * @private 86 * @see Renderer#transform 87 */ 88 transform: function(target){ 89 var drawable = target.drawable; 90 if(drawable && drawable.domElement){ 91 Hilo.setElementStyleByView(target); 92 return; 93 } 94 95 var ctx = this.context, 96 scaleX = target.scaleX, 97 scaleY = target.scaleY; 98 99 if(target === this.stage){ 100 var style = this.canvas.style, 101 oldScaleX = target._scaleX, 102 oldScaleY = target._scaleY; 103 104 if((!oldScaleX && scaleX != 1) || (oldScaleX && oldScaleX != scaleX)){ 105 target._scaleX = scaleX; 106 style.width = scaleX * target.width + "px"; 107 } 108 if((!oldScaleY && scaleY != 1) || (oldScaleY && oldScaleY != scaleY)){ 109 target._scaleY = scaleY; 110 style.height = scaleY * target.height + "px"; 111 } 112 }else{ 113 var x = target.x, 114 y = target.y, 115 pivotX = target.pivotX, 116 pivotY = target.pivotY, 117 rotation = target.rotation % 360, 118 mask = target.mask; 119 120 if(mask){ 121 mask._render(this); 122 ctx.clip(); 123 } 124 125 //alignment 126 var align = target.align; 127 if(align){ 128 if(typeof align === 'function'){ 129 target.align(); 130 }else{ 131 var parent = target.parent; 132 if(parent){ 133 var w = target.width, h = target.height, 134 pw = parent.width, ph = parent.height; 135 switch(align){ 136 case 'TL': 137 x = 0; 138 y = 0; 139 break; 140 case 'T': 141 x = pw - w >> 1; 142 y = 0; 143 break; 144 case 'TR': 145 x = pw - w; 146 y = 0; 147 break; 148 case 'L': 149 x = 0; 150 y = ph - h >> 1; 151 break; 152 case 'C': 153 x = pw - w >> 1; 154 y = ph - h >> 1; 155 break; 156 case 'R': 157 x = pw - w; 158 y = ph - h >> 1; 159 break; 160 case 'BL': 161 x = 0; 162 y = ph - h; 163 break; 164 case 'B': 165 x = pw - w >> 1; 166 y = ph - h; 167 break; 168 case 'BR': 169 x = pw - w; 170 y = ph - h; 171 break; 172 } 173 } 174 } 175 } 176 177 if(x != 0 || y != 0) ctx.translate(x, y); 178 if(rotation != 0) ctx.rotate(rotation * Math.PI / 180); 179 if(scaleX != 1 || scaleY != 1) ctx.scale(scaleX, scaleY); 180 if(pivotX != 0 || pivotY != 0) ctx.translate(-pivotX, -pivotY); 181 } 182 183 if(target.alpha > 0) ctx.globalAlpha *= target.alpha; 184 }, 185 186 /** 187 * @private 188 * @see Renderer#remove 189 */ 190 remove: function(target){ 191 var drawable = target.drawable; 192 var elem = drawable && drawable.domElement; 193 194 if(elem){ 195 var parentElem = elem.parentNode; 196 if(parentElem){ 197 parentElem.removeChild(elem); 198 } 199 } 200 }, 201 202 /** 203 * @private 204 * @see Renderer#clear 205 */ 206 clear: function(x, y, width, height){ 207 this.context.clearRect(x, y, width, height); 208 }, 209 210 /** 211 * @private 212 * @see Renderer#resize 213 */ 214 resize: function(width, height){ 215 this.canvas.width = width; 216 this.canvas.height = height; 217 } 218 219 });