1 /** 2 * Hilo 3 * Copyright 2015 alibaba.com 4 * Licensed under the MIT License 5 */ 6 7 /** 8 * @language=zh 9 * @class DOM+CSS3渲染器。将可视对象以DOM元素方式渲染出来。舞台Stage会根据参数canvas选择不同的渲染器,开发者无需直接使用此类。 10 * @augments Renderer 11 * @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。 12 * @module hilo/renderer/DOMRenderer 13 * @requires hilo/core/Class 14 * @requires hilo/core/Hilo 15 * @requires hilo/renderer/Renderer 16 * @requires hilo/view/Drawable 17 */ 18 var DOMRenderer = (function(){ 19 20 return Class.create({ 21 Extends: Renderer, 22 constructor: function(properties){ 23 DOMRenderer.superclass.constructor.call(this, properties); 24 }, 25 renderType:'dom', 26 /** 27 * @private 28 * @see Renderer#startDraw 29 */ 30 startDraw: function(target){ 31 //prepare drawable 32 var drawable = (target.drawable = target.drawable || new Drawable()); 33 drawable.domElement = drawable.domElement || createDOMDrawable(target, drawable); 34 return true; 35 }, 36 37 /** 38 * @private 39 * @see Renderer#draw 40 */ 41 draw: function(target){ 42 var parent = target.parent, 43 targetElem = target.drawable.domElement, 44 currentParent = targetElem.parentNode; 45 46 if(parent){ 47 var parentElem = parent.drawable.domElement; 48 if(parentElem != currentParent){ 49 parentElem.appendChild(targetElem); 50 } 51 //fix image load bug 52 if(!target.width && !target.height){ 53 var rect = target.drawable.rect; 54 if(rect && (rect[2] || rect[3])){ 55 target.width = rect[2]; 56 target.height = rect[3]; 57 } 58 } 59 } 60 else if(target === this.stage && !currentParent){ 61 targetElem.style.overflow = 'hidden'; 62 this.canvas.appendChild(targetElem); 63 } 64 }, 65 66 /** 67 * @private 68 * @see Renderer#transform 69 */ 70 transform: function(target){ 71 Hilo.setElementStyleByView(target); 72 if(target === this.stage){ 73 var style = this.canvas.style, 74 oldScaleX = target._scaleX, 75 oldScaleY = target._scaleY, 76 scaleX = target.scaleX, 77 scaleY = target.scaleY; 78 79 if((!oldScaleX && scaleX != 1) || (oldScaleX && oldScaleX != scaleX)){ 80 target._scaleX = scaleX; 81 style.width = scaleX * target.width + "px"; 82 } 83 if((!oldScaleY && scaleY != 1) || (oldScaleY && oldScaleY != scaleY)){ 84 target._scaleY = scaleY; 85 style.height = scaleY * target.height + "px"; 86 } 87 } 88 }, 89 90 /** 91 * @private 92 * @see Renderer#remove 93 */ 94 remove: function(target){ 95 var drawable = target.drawable; 96 var elem = drawable && drawable.domElement; 97 98 if(elem){ 99 var parentElem = elem.parentNode; 100 if(parentElem){ 101 parentElem.removeChild(elem); 102 } 103 } 104 }, 105 106 /** 107 * @private 108 * @see Renderer#hide 109 */ 110 hide: function(target){ 111 var elem = target.drawable && target.drawable.domElement; 112 if(elem) elem.style.display = 'none'; 113 }, 114 115 /** 116 * @private 117 * @see Renderer#resize 118 */ 119 resize: function(width, height){ 120 var style = this.canvas.style; 121 style.width = width + 'px'; 122 style.height = height + 'px'; 123 if(style.position != "absolute") { 124 style.position = "relative"; 125 } 126 } 127 }); 128 129 /** 130 * @language=zh 131 * 创建一个可渲染的DOM,可指定tagName,如canvas或div。 132 * @param {Object} view 一个可视对象或类似的对象。 133 * @param {Object} imageObj 指定渲染的image及相关设置,如绘制区域rect。 134 * @return {HTMLElement} 新创建的DOM对象。 135 * @private 136 */ 137 function createDOMDrawable(view, imageObj){ 138 var tag = view.tagName || "div", 139 img = imageObj.image, 140 w = view.width || (img && img.width), 141 h = view.height || (img && img.height), 142 elem = Hilo.createElement(tag), style = elem.style; 143 144 if(view.id) elem.id = view.id; 145 style.position = "absolute"; 146 style.left = (view.left || 0) + "px"; 147 style.top = (view.top || 0) + "px"; 148 style.width = w + "px"; 149 style.height = h + "px"; 150 151 if(tag == "canvas"){ 152 elem.width = w; 153 elem.height = h; 154 if(img){ 155 var ctx = elem.getContext("2d"); 156 var rect = imageObj.rect || [0, 0, w, h]; 157 ctx.drawImage(img, rect[0], rect[1], rect[2], rect[3], 158 (view.x || 0), (view.y || 0), 159 (view.width || rect[2]), 160 (view.height || rect[3])); 161 } 162 }else{ 163 style.opacity = view.alpha != undefined ? view.alpha : 1; 164 if(view === this.stage || view.clipChildren) style.overflow = "hidden"; 165 if(img && img.src){ 166 style.backgroundImage = "url(" + img.src + ")"; 167 var bgX = view.rectX || 0, bgY = view.rectY || 0; 168 style.backgroundPosition = (-bgX) + "px " + (-bgY) + "px"; 169 } 170 } 171 return elem; 172 } 173 174 })(); 175