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