1 /** 2 * Hilo 3 * Copyright 2015 alibaba.com 4 * Licensed under the MIT License 5 */ 6 7 var win = window, 8 doc = document, 9 docElem = doc.documentElement, 10 uid = 0; 11 12 var hasWarnedDict = {}; 13 14 /** 15 * @namespace Hilo The underlying core set of methods. 16 * @static 17 * @module hilo/core/Hilo 18 * @requires hilo/util/browser 19 * @requires hilo/util/util 20 */ 21 var Hilo = { 22 /** 23 * Hilo version 24 * @type String 25 */ 26 version: '{{$version}}', 27 /** 28 * Gets a globally unique id. Such as Stage1, Bitmap2 etc. 29 * @param {String} prefix Generated id's prefix. 30 * @returns {String} Globally unique id. 31 */ 32 getUid: function(prefix) { 33 var id = ++uid; 34 if (prefix) { 35 var charCode = prefix.charCodeAt(prefix.length - 1); 36 if (charCode >= 48 && charCode <= 57) prefix += "_"; //0至9之间添加下划线 37 return prefix + id; 38 } 39 return id; 40 }, 41 42 /** 43 * Generates a string representation that contains a path to the specified visual object. Such as Stage1.Container2.Bitmap3. 44 * @param {View} view Specified visual object. 45 * @returns {String} String representation of the visual object. 46 */ 47 viewToString: function(view) { 48 var result, obj = view; 49 while (obj) { 50 result = result ? (obj.id + '.' + result) : obj.id; 51 obj = obj.parent; 52 } 53 return result; 54 }, 55 56 /** 57 * Simple shallow copy objects. 58 * @deprecated use Hilo.util.copy instead 59 * @param {Object} target Target object to copy to. 60 * @param {Object} source Source object to copy. 61 * @param {Boolean} strict Indicates whether replication is undefined property, default is false, i.e., undefined attributes are not copied. 62 * @returns {Object} Object after copying. 63 */ 64 copy: function(target, source, strict) { 65 util.copy(target, source, strict); 66 if (!hasWarnedDict.copy) { 67 hasWarnedDict.copy = true; 68 console.warn('Hilo.copy has been Deprecated! Use Hilo.util.copy instead.'); 69 } 70 return target; 71 }, 72 73 /** 74 * Browser feature set includes: 75 * @see browser 76 */ 77 browser: browser, 78 79 /** 80 * Event enumeration objects include: 81 * <ul> 82 * <li><b>POINTER_START</b> - Mouse or touch start event. Corresponds to touchstart or mousedown.</li> 83 * <li><b>POINTER_MOVE</b> - Mouse or touch move event. Corresponds to touchmove or mousemove.</li> 84 * <li><b>POINTER_END</b> - Mouse or touch end event. Corresponds to touchend or mouseup.</li> 85 * </ul> 86 */ 87 event: { 88 POINTER_START: browser.POINTER_START, 89 POINTER_MOVE: browser.POINTER_MOVE, 90 POINTER_END: browser.POINTER_END 91 }, 92 93 /** 94 * Visual object alinment enumeration objects include: 95 * <ul> 96 * <li><b>TOP_LEFT</b> - Align the top left corner.</li> 97 * <li><b>TOP</b> - Top center alignment.</li> 98 * <li><b>TOP_RIGHT</b> - Align the top right corner.</li> 99 * <li><b>LEFT</b> - Left center alignment.</li> 100 * <li><b>CENTER</b> - Align center.</li> 101 * <li><b>RIGHT</b> - Right center alignment.</li> 102 * <li><b>BOTTOM_LEFT</b> - Align the bottom left corner.</li> 103 * <li><b>BOTTOM</b> - Bottom center alignment.</li> 104 * <li><b>BOTTOM_RIGHT</b> - Align the bottom right corner.</li> 105 * </ul> 106 */ 107 align: { 108 TOP_LEFT: 'TL', //top & left 109 TOP: 'T', //top & center 110 TOP_RIGHT: 'TR', //top & right 111 LEFT: 'L', //left & center 112 CENTER: 'C', //center 113 RIGHT: 'R', //right & center 114 BOTTOM_LEFT: 'BL', //bottom & left 115 BOTTOM: 'B', //bottom & center 116 BOTTOM_RIGHT: 'BR' //bottom & right 117 }, 118 119 /** 120 * Get DOM element content in the page display area. 121 * @param {HTMLElement} elem DOM elements. 122 * @returns {Object} Viewable area DOM elements. Format is: {left:0, top:0, width:100, height:100}. 123 */ 124 getElementRect: function(elem) { 125 var bounds; 126 try { 127 //this fails if it's a disconnected DOM node 128 bounds = elem.getBoundingClientRect(); 129 } catch (e) { 130 bounds = { 131 top: elem.offsetTop, 132 left: elem.offsetLeft, 133 right: elem.offsetLeft + elem.offsetWidth, 134 bottom: elem.offsetTop + elem.offsetHeight 135 }; 136 } 137 138 var offsetX = ((win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)) || 0; 139 var offsetY = ((win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0)) || 0; 140 var styles = win.getComputedStyle ? getComputedStyle(elem) : elem.currentStyle; 141 var parseIntFn = parseInt; 142 143 var padLeft = (parseIntFn(styles.paddingLeft) + parseIntFn(styles.borderLeftWidth)) || 0; 144 var padTop = (parseIntFn(styles.paddingTop) + parseIntFn(styles.borderTopWidth)) || 0; 145 var padRight = (parseIntFn(styles.paddingRight) + parseIntFn(styles.borderRightWidth)) || 0; 146 var padBottom = (parseIntFn(styles.paddingBottom) + parseIntFn(styles.borderBottomWidth)) || 0; 147 148 var top = bounds.top || 0; 149 var left = bounds.left || 0; 150 var right = bounds.right || 0; 151 var bottom = bounds.bottom || 0; 152 153 return { 154 left: left + offsetX + padLeft, 155 top: top + offsetY + padTop, 156 width: right - padRight - left - padLeft, 157 height: bottom - padBottom - top - padTop 158 }; 159 }, 160 161 /** 162 * Create a DOM element. You can specify properties and styles. 163 * @param {String} type DOM element type to be created. Such as: 'div'. 164 * @param {Object} properties Properties and styles for DOM element. 165 * @returns {HTMLElement} A DOM element. 166 */ 167 createElement: function(type, properties) { 168 var elem = doc.createElement(type), 169 p, val, s; 170 for (p in properties) { 171 val = properties[p]; 172 if (p === 'style') { 173 for (s in val) elem.style[s] = val[s]; 174 } else { 175 elem[p] = val; 176 } 177 } 178 return elem; 179 }, 180 181 /** 182 * Gets a DOM element according to the parameter id. This method is equivalent to document.getElementById(id). 183 * @param {String} id id of the DOM element you want to get. 184 * @returns {HTMLElement} A DOM element. 185 */ 186 getElement: function(id) { 187 return doc.getElementById(id); 188 }, 189 190 /** 191 * Set visual object DOM element CSS style. 192 * @param {View} obj Specifies the CSS style to set the visual object. 193 * @private 194 */ 195 setElementStyleByView: function(obj) { 196 var drawable = obj.drawable, 197 style = drawable.domElement.style, 198 stateCache = obj._stateCache || (obj._stateCache = {}), 199 prefix = Hilo.browser.jsVendor, 200 px = 'px', 201 flag = false; 202 203 if (this.cacheStateIfChanged(obj, ['visible'], stateCache)) { 204 style.display = !obj.visible ? 'none' : ''; 205 } 206 if (this.cacheStateIfChanged(obj, ['alpha'], stateCache)) { 207 style.opacity = obj.alpha; 208 } 209 if (!obj.visible || obj.alpha <= 0) return; 210 211 if (this.cacheStateIfChanged(obj, ['width'], stateCache)) { 212 style.width = obj.width + px; 213 } 214 if (this.cacheStateIfChanged(obj, ['height'], stateCache)) { 215 style.height = obj.height + px; 216 } 217 if (this.cacheStateIfChanged(obj, ['depth'], stateCache)) { 218 style.zIndex = obj.depth + 1; 219 } 220 if (obj.transform){ 221 var transform = obj.transform; 222 if (flag = this.cacheStateIfChanged(obj, ['pivotX', 'pivotY'], stateCache)) { 223 style[prefix + 'TransformOrigin'] = '0 0'; 224 } 225 style[prefix + 'Transform'] = 'matrix3d(' + transform.a + ', '+ transform.b + ', 0, 0, '+ transform.c + ', '+ transform.d + ', 0, 0, 0, 0, 1, 0, '+ transform.tx + ', '+ transform.ty + ', 0, 1)'; 226 } 227 else{ 228 if (flag = this.cacheStateIfChanged(obj, ['pivotX', 'pivotY'], stateCache)) { 229 style[prefix + 'TransformOrigin'] = obj.pivotX + px + ' ' + obj.pivotY + px; 230 } 231 232 if (this.cacheStateIfChanged(obj, ['x', 'y', 'rotation', 'scaleX', 'scaleY'], stateCache) || flag) { 233 style[prefix + 'Transform'] = this.getTransformCSS(obj); 234 } 235 } 236 237 if (this.cacheStateIfChanged(obj, ['background'], stateCache)) { 238 style.backgroundColor = obj.background; 239 } 240 if (!style.pointerEvents) { 241 style.pointerEvents = 'none'; 242 } 243 244 //render image as background 245 var image = drawable.image; 246 if (image) { 247 var src = image.src; 248 if (src !== stateCache.image) { 249 stateCache.image = src; 250 style.backgroundImage = 'url(' + src + ')'; 251 } 252 253 var rect = drawable.rect; 254 if (rect) { 255 var sx = rect[0], 256 sy = rect[1]; 257 if (sx !== stateCache.sx) { 258 stateCache.sx = sx; 259 style.backgroundPositionX = -sx + px; 260 } 261 if (sy !== stateCache.sy) { 262 stateCache.sy = sy; 263 style.backgroundPositionY = -sy + px; 264 } 265 } 266 } 267 268 //render mask 269 var mask = obj.mask; 270 if (mask) { 271 var maskImage = mask.drawable.domElement.style.backgroundImage; 272 if (maskImage !== stateCache.maskImage) { 273 stateCache.maskImage = maskImage; 274 style[prefix + 'MaskImage'] = maskImage; 275 style[prefix + 'MaskRepeat'] = 'no-repeat'; 276 } 277 278 var maskX = mask.x, 279 maskY = mask.y; 280 if (maskX !== stateCache.maskX || maskY !== stateCache.maskY) { 281 stateCache.maskX = maskX; 282 stateCache.maskY = maskY; 283 style[prefix + 'MaskPosition'] = maskX + px + ' ' + maskY + px; 284 } 285 } 286 }, 287 288 /** 289 * @private 290 */ 291 cacheStateIfChanged: function(obj, propNames, stateCache) { 292 var i, len, name, value, changed = false; 293 for (i = 0, len = propNames.length; i < len; i++) { 294 name = propNames[i]; 295 value = obj[name]; 296 if (value != stateCache[name]) { 297 stateCache[name] = value; 298 changed = true; 299 } 300 } 301 return changed; 302 }, 303 304 /** 305 * Generated visual object CSS style transformation. 306 * @param {View} obj Specifies visual object whose CSS style must be got. 307 * @returns {String} String representation of the CSS style. 308 */ 309 getTransformCSS: function(obj) { 310 var use3d = this.browser.supportTransform3D, 311 str3d = use3d ? '3d' : ''; 312 313 return 'translate' + str3d + '(' + (obj.x - obj.pivotX) + 'px, ' + (obj.y - obj.pivotY) + (use3d ? 'px, 0px)' : 'px)') + 314 'rotate' + str3d + (use3d ? '(0, 0, 1, ' : '(') + obj.rotation + 'deg)' + 315 'scale' + str3d + '(' + obj.scaleX + ', ' + obj.scaleY + (use3d ? ', 1)' : ')'); 316 } 317 };