1 2 /** 3 * @namespace Hilo的基础核心方法集合。 4 * @static 5 * @module hilo/core/Hilo 6 */ 7 var Hilo = (function(){ 8 9 var win = window, doc = document, docElem = doc.documentElement, 10 uid = 0; 11 12 return { 13 /** 14 * 获取一个全局唯一的id。如Stage1,Bitmap2等。 15 * @param {String} prefix 生成id的前缀。 16 */ 17 getUid: function(prefix){ 18 var id = ++uid; 19 if(prefix){ 20 var charCode = prefix.charCodeAt(prefix.length - 1); 21 if (charCode >= 48 && charCode <= 57) prefix += "_"; // 0至9之间添加下划线 22 return prefix + id; 23 } 24 return id; 25 }, 26 27 /** 28 * 为指定的可视对象生成一个包含路径的字符串表示形式。如Stage1.Container2.Bitmap3。 29 * @param {View} view 指定的可视对象。 30 */ 31 viewToString: function(view){ 32 var result, obj = view; 33 while(obj){ 34 result = result ? (obj.id + '.' + result) : obj.id; 35 obj = obj.parent; 36 } 37 return result; 38 }, 39 40 /** 41 * 简单的浅复制对象。 42 * @param {Object} target 要复制的目标对象。 43 * @param {Object} source 要复制的源对象。 44 * @param {Boolean} strict 指定是否覆盖已有属性,默认为false,即不覆盖。 45 */ 46 copy: function(target, source, strict){ 47 for(var key in source){ 48 if(!strict || target.hasOwnProperty(key) || target[key] !== undefined){ 49 target[key] = source[key]; 50 } 51 } 52 return target; 53 }, 54 55 /** 56 * 浏览器特性。 57 */ 58 browser: (function(){ 59 var ua = navigator.userAgent; 60 var data = { 61 iphone: /iphone/i.test(ua), 62 ipad: /ipad/i.test(ua), 63 ipod: /ipod/i.test(ua), 64 android: /android/i.test(ua), 65 webkit: /webkit/i.test(ua), 66 chrome: /chrome/i.test(ua), 67 safari: /safari/i.test(ua), 68 firefox: /firefox/i.test(ua), 69 ie: /msie/i.test(ua), 70 opera: /opera/i.test(ua), 71 supportTouch: 'ontouchstart' in win, 72 supportCanvas: doc.createElement('canvas').getContext != null, 73 supportStorage: false, 74 supportOrientation: 'orientation' in win, 75 supportDeviceMotion: 'ondevicemotion' in win 76 }; 77 78 //`localStorage` is null or `localStorage.setItem` throws error in some cases (e.g. localStorage is disabled) 79 try{ 80 var value = 'hilo'; 81 localStorage.setItem(value, value); 82 localStorage.removeItem(value); 83 data.supportStorage = true; 84 }catch(e){ }; 85 86 //vendro prefix 87 var jsVendor = data.jsVendor = data.webkit ? 'webkit' : data.firefox ? 'Moz' : data.opera ? 'O' : data.ie ? 'ms' : ''; 88 var cssVendor = data.cssVendor = '-' + jsVendor + '-'; 89 90 //css transform/3d feature dectection 91 var testElem = doc.createElement('div'), style = testElem.style; 92 var supportTransform = style[jsVendor + 'Transform'] != undefined; 93 var supportTransform3D = style[jsVendor + 'Perspective'] != undefined; 94 if(supportTransform3D){ 95 testElem.id = 'test3d'; 96 style = doc.createElement('style'); 97 style.textContent = '@media ('+ cssVendor +'transform-3d){#test3d{height:3px}}'; 98 doc.head.appendChild(style); 99 100 docElem.appendChild(testElem); 101 supportTransform3D = testElem.offsetHeight == 3; 102 doc.head.removeChild(style); 103 docElem.removeChild(testElem); 104 }; 105 data.supportTransform = supportTransform; 106 data.supportTransform3D = supportTransform3D; 107 108 return data; 109 })(), 110 111 /** 112 * 事件类型枚举对象。 113 */ 114 event: (function(){ 115 var supportTouch = 'ontouchstart' in win; 116 return { 117 POINTER_START: supportTouch ? 'touchstart' : 'mousedown', 118 POINTER_MOVE: supportTouch ? 'touchmove' : 'mousemove', 119 POINTER_END: supportTouch ? 'touchend' : 'mouseup' 120 }; 121 })(), 122 123 /** 124 * 获取DOM元素在页面中的内容显示区域。 125 * @param {HTMLElement} elem DOM元素。 126 * @returns {Object} DOM元素的现实区域。格式为:{left:0, top:0, width:100, height:100}。 127 */ 128 getElementRect: function(elem){ 129 try{ 130 //this fails if it's a disconnected DOM node 131 var bounds = elem.getBoundingClientRect(); 132 }catch(e){ 133 bounds = {top: elem.offsetTop, left: elem.offsetLeft, width:elem.offsetWidth, height:elem.offsetHeight}; 134 } 135 136 var offsetX = (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0); 137 var offsetY = (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0); 138 var styles = win.getComputedStyle ? getComputedStyle(elem) : elem.currentStyle; 139 var parseIntFn = parseInt; 140 var padLeft = parseIntFn(styles.paddingLeft) + parseIntFn(styles.borderLeftWidth); 141 var padTop = parseIntFn(styles.paddingTop) + parseIntFn(styles.borderTopWidth); 142 var padRight = parseIntFn(styles.paddingRight) + parseIntFn(styles.borderRightWidth); 143 var padBottom = parseIntFn(styles.paddingBottom) + parseIntFn(styles.borderBottomWidth); 144 145 return { 146 left: bounds.left + offsetX + padLeft, 147 top: bounds.top + offsetY + padTop, 148 width: bounds.right - padRight - bounds.left - padLeft, 149 height: bounds.bottom - padBottom - bounds.top - padTop 150 }; 151 }, 152 153 /** 154 * 创建一个DOM元素。可指定属性和样式。 155 * @param {String} type 要创建的DOM元素的类型。比如:'div'。 156 * @param {Object} properties 指定DOM元素的属性和样式。 157 * @returns {HTMLElement} 一个DOM元素。 158 */ 159 createElement: function(type, properties){ 160 var elem = doc.createElement(type), p, val, s; 161 for(p in properties){ 162 val = properties[p]; 163 if(p === 'style'){ 164 for(s in val) elem.style[s] = val[s]; 165 }else{ 166 elem[p] = val; 167 } 168 } 169 return elem; 170 }, 171 172 /** 173 * 根据参数id获取一个DOM元素。此方法等价于document.getElementById(id)。 174 * @param {String} 要获取的DOM元素的id。 175 * @returns {HTMLElement} 一个DOM元素。 176 */ 177 getElement: function(id){ 178 return doc.getElementById(id); 179 }, 180 181 /** 182 * 设置可视对象DOM元素的CSS样式。 183 * @param {View} obj 指定要设置CSS样式的可视对象。 184 */ 185 setElementStyleByView: function(obj){ 186 var drawable = obj.drawable, 187 image = drawable.image, 188 rect = drawable.rect, 189 style = drawable.domElement.style, 190 prefix = Hilo.browser.jsVendor, px = 'px'; 191 192 style.pointerEvents = 'none'; 193 style.display = (!obj.visible || obj.alpha <= 0) ? 'none' : ''; 194 style.width = obj.width + px; 195 style.height = obj.height + px; 196 style.opacity = obj.alpha; 197 style.zIndex = obj.depth; 198 style[prefix + 'TransformOrigin'] = obj.pivotX + px + ' ' + obj.pivotY + px; 199 style[prefix + 'Transform'] = this.getTransformCSS(obj); 200 if(obj.bgFill) style.backgroundColor = obj.bgFill.style; 201 202 if(image){ 203 if(style.backgroundImage.indexOf(image.src) != 4){ 204 style.backgroundImage = 'url(' + image.src + ')'; 205 } 206 if(rect){ 207 style.backgroundPosition = -rect[0] + px + ' ' + -rect[1] + px; 208 } 209 } 210 211 if(obj.mask){ 212 style[prefix + 'MaskImage'] = obj.mask.drawable.domElement.style.backgroundImage; 213 style[prefix + 'MaskRepeat'] = 'no-repeat'; 214 style[prefix + 'MaskPosition'] = obj.mask.x + px + ' ' + obj.mask.y + px; 215 } 216 }, 217 218 /** 219 * 生成可视对象的CSS变换样式。 220 * @param {View} obj 指定生成CSS变换样式的可视对象。 221 * @returns {String} 生成的CSS样式字符串。 222 */ 223 getTransformCSS: function(obj){ 224 var use3d = this.browser.supportTransform3D, 225 str3d = use3d ? '3d' : ''; 226 227 return 'translate' + str3d + '(' + (obj.x - obj.pivotX) + 'px, ' + (obj.y - obj.pivotY) + (use3d ? 'px, 0px)' : 'px)') 228 + 'rotate' + str3d + (use3d ? '(0, 0, 1, ' : '(') + obj.rotation + 'deg)' 229 + 'scale' + str3d + '(' + obj.scaleX + ', ' + obj.scaleY + (use3d ? ', 1)' : ')'); 230 } 231 }; 232 233 })();