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