1 /** 2 * Hilo 3 * Copyright 2015 alibaba.com 4 * Licensed under the MIT License 5 */ 6 7 /** 8 * @language=zh 9 * @class canvas画布渲染器。所有可视对象将渲染在canvas画布上。舞台Stage会根据参数canvas选择不同的渲染器,开发者无需直接使用此类。 10 * @augments Renderer 11 * @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。 12 * @module hilo/renderer/CanvasRenderer 13 * @requires hilo/core/Class 14 * @requires hilo/core/Hilo 15 * @requires hilo/renderer/Renderer 16 * @property {CanvasRenderingContext2D} context canvas画布的上下文。只读属性。 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 });