├── example ├── images │ ├── mouse.jpg │ ├── cube_BK.jpg │ ├── cube_DN.jpg │ ├── cube_FR.jpg │ ├── cube_LF.jpg │ ├── cube_RT.jpg │ ├── cube_UP.jpg │ └── zwj │ │ ├── p1.png │ │ ├── p10.png │ │ ├── p11.png │ │ ├── p12.png │ │ ├── p13.png │ │ ├── p14.png │ │ ├── p15.png │ │ ├── p16.png │ │ ├── p17.png │ │ ├── p18.png │ │ ├── p19.png │ │ ├── p2.png │ │ ├── p20.png │ │ ├── p3.png │ │ ├── p4.png │ │ ├── p5.png │ │ ├── p6.png │ │ ├── p7.png │ │ ├── p8.png │ │ └── p9.png ├── pano.html ├── simple.html ├── scene.html ├── space.html ├── cylinder.html └── rubik.html ├── LICENSE ├── README.md ├── 使用范例.md ├── API.md ├── css3d.min.js └── css3d.js /example/images/mouse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/mouse.jpg -------------------------------------------------------------------------------- /example/images/cube_BK.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/cube_BK.jpg -------------------------------------------------------------------------------- /example/images/cube_DN.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/cube_DN.jpg -------------------------------------------------------------------------------- /example/images/cube_FR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/cube_FR.jpg -------------------------------------------------------------------------------- /example/images/cube_LF.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/cube_LF.jpg -------------------------------------------------------------------------------- /example/images/cube_RT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/cube_RT.jpg -------------------------------------------------------------------------------- /example/images/cube_UP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/cube_UP.jpg -------------------------------------------------------------------------------- /example/images/zwj/p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p1.png -------------------------------------------------------------------------------- /example/images/zwj/p10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p10.png -------------------------------------------------------------------------------- /example/images/zwj/p11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p11.png -------------------------------------------------------------------------------- /example/images/zwj/p12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p12.png -------------------------------------------------------------------------------- /example/images/zwj/p13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p13.png -------------------------------------------------------------------------------- /example/images/zwj/p14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p14.png -------------------------------------------------------------------------------- /example/images/zwj/p15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p15.png -------------------------------------------------------------------------------- /example/images/zwj/p16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p16.png -------------------------------------------------------------------------------- /example/images/zwj/p17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p17.png -------------------------------------------------------------------------------- /example/images/zwj/p18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p18.png -------------------------------------------------------------------------------- /example/images/zwj/p19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p19.png -------------------------------------------------------------------------------- /example/images/zwj/p2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p2.png -------------------------------------------------------------------------------- /example/images/zwj/p20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p20.png -------------------------------------------------------------------------------- /example/images/zwj/p3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p3.png -------------------------------------------------------------------------------- /example/images/zwj/p4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p4.png -------------------------------------------------------------------------------- /example/images/zwj/p5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p5.png -------------------------------------------------------------------------------- /example/images/zwj/p6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p6.png -------------------------------------------------------------------------------- /example/images/zwj/p7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p7.png -------------------------------------------------------------------------------- /example/images/zwj/p8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p8.png -------------------------------------------------------------------------------- /example/images/zwj/p9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shrekshrek/css3d-engine/HEAD/example/images/zwj/p9.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Shrek.Wang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # css3d-engine 2 | 3 | 4 | css 3d引擎,为方便工作需要制作 5 | 优势:因为是基于div+css3实现,相对canvas webgl拥有更好的平台兼容性。 6 | 劣势:渲染性能相比canvas webgl要弱,只适合创建较小的三维面片场景。 7 | 但是只有14k,相比那些动辄300-400k的大型3d库,这是个非常小巧实用的辅助支持库。 8 | 9 | 这个库只是基于原生css transform中除了matrix之外的属性,可以使用比较容易理解的欧拉角来控制旋转,建立简单的3D应用,对于3d开发0基础的开发者是个友善简单的入门类库。对于有更高3d要求的开发者建议使用three.js等类库。但同样对开发者的基础要求会更高,这里我整理了一个更通用的3d基础学习案例 10 | https://github.com/shrekshrek/css3d-matrix-es6 11 | 抽取出three中3D核心类库,组织了一个简化版的3D引擎,并做了大量的注释,可以帮助了解3D算法基础中的矢量,矩阵及四元数等的相互关系。 12 | 13 | 有3d问题欢迎加入研讨。QQ群:572807793(webgl技术交流) 14 | 15 | 16 | 注意1:为了节约计算量,transform部分没有使用matrix,只用了最基本的translate,rotation,scale等属性的排列,默认的旋转顺序是rotationX(),rotationY(),rotationZ(),这样无法解决万向锁等问题,所以在使用时需要了解适应这点。如果需要调整可以使用sort()命令调整旋转顺序。 17 | 18 | 注意2:旧版的Cube更新为Box。 19 | 20 | 21 | 实现案例(移动端H5): 22 | 23 | adidas绝不凋谢 https://shrek.imdevsh.com/show/drose/ 24 | 25 | adidas胜势全开 https://shrek.imdevsh.com/show/bbcny/ 26 | 27 | adidas绝不跟随 https://shrek.imdevsh.com/show/crazylight/ 28 | 29 | 淘宝造物节 https://shrek.imdevsh.com/show/zwj/ 30 | 31 | 32 | 这种Interactive 3d motion graphic类型的网站开发,以前都是程序来做动画,需要书写大量的tween代码,开发效率难以提高。从2018年初开始已经改用更先进高效的内部工具套装AEP开发,demo地址如下: 33 | https://github.com/shrekshrek/aep 34 | 35 | 36 | 37 | 38 | * VERSION: 0.1.0 DATE: 2014-11-20 39 | 40 | 41 | 42 | # License 43 | This content is released under the [MIT](http://opensource.org/licenses/MIT) License. -------------------------------------------------------------------------------- /example/pano.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 64 | 65 | -------------------------------------------------------------------------------- /example/simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 68 | 69 | -------------------------------------------------------------------------------- /example/scene.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 83 | 84 | -------------------------------------------------------------------------------- /使用范例.md: -------------------------------------------------------------------------------- 1 | 使用范例 2 | ============ 3 | 4 | 创建stage,stage是舞台,是整个场景的根. 5 | ```js 6 | var s = new C3D.Stage(); 7 | ``` 8 | 9 | 所有的函数都可以链式调用, 10 | ```js 11 | s.size(window.innerWidth, window.innerHeight).material({ 12 | color : "#cccccc" 13 | }).update(); 14 | ``` 15 | 16 | 以上代码也可以等同以下代码 17 | ```js 18 | s.width = window.innerWidth; 19 | s.height = window.innerHeight; 20 | s.material({color : "#cccccc"}); 21 | s.update(); 22 | ``` 23 | 一般在创建元素时使用update(),update中会分别执行updateS(),updateM(),updateT(),updateV(),保证元素创建完整.之后再做其他属性改变时只需要调用相关函数,不用再调用完整功能的update()了. 24 | 25 | 最后将stage的dom元素置入所需位置,el是所有三维元素的属性,包含对应的dom元素 26 | ```js 27 | document.getElementById('main').appendChild(s.el); 28 | ``` 29 | 30 | 31 | 创建一个三维容器,容器没有高宽深和材质信息,只有位置,旋转,缩放等信息. 32 | ```js 33 | var sp = new C3D.Sprite(); 34 | sp.position(0, 0, -500).update(); 35 | s.addChild(sp); 36 | ``` 37 | 38 | 创建一个平面放入场景 39 | ```js 40 | var p = new C3D.Plane(); 41 | p.size(100).position(0, 100, -s.fov).rotation(0, 0, 0).material({ 42 | color : C3D.getRandomColor() 43 | }).update(); 44 | s.addChild(p); 45 | ``` 46 | 47 | 创建一个立方体放入场景 48 | ```js 49 | var c = new C3D.Box(); 50 | c.size(100).position(0, -100, -s.fov).rotation(0, 0, 0).material({ 51 | color : C3D.getRandomColor() 52 | }).update(); 53 | s.addChild(c); 54 | ``` 55 | 这里position中的z设置为s.fov是因为这个值就是摄像头前正好可以原比例显示物体的距离,注意这里的s是stage,不是camera,不要和camera.fov混淆了。 56 | 57 | 58 | 如果希望单独控制立方体各面的素材可以如下方式 59 | ```js 60 | var c = new C3D.Cube(); 61 | c.size(100).position(0, -100, -s.fov).rotation(0, 0, 0).material({ 62 | front : {color:C3D.getRandomColor()}, 63 | back : {color:C3D.getRandomColor()}, 64 | left : {color:C3D.getRandomColor()}, 65 | right : {color:C3D.getRandomColor()}, 66 | up : {color:C3D.getRandomColor()}, 67 | down : {color:C3D.getRandomColor()}, 68 | }).update(); 69 | s.addChild(c); 70 | ``` 71 | 72 | 动画部分结合jstween类库也可以方便的修改 73 | ```js 74 | JT.fromTo(p, 3, {rotationY: 0}, { 75 | rotationY: 90, ease: JT.Quart.In, onUpdate: function () { 76 | // 此处因为是rotationY变化,只需要调用updateT()就可以,如果是alpha活visible变化,需要调用updateV(),材质变化调用updateM(),尺寸变化调用updateS() 77 | this.updateT(); 78 | },onEnd:function(){ 79 | sp.removeChild(this); 80 | } 81 | }); 82 | ``` 83 | 其他类库,比如tweenmax等也可以使用类似方式来处理 84 | 85 | 86 | 其他可以参考example中的几个案例,可以下载到本地查看,在线demo地址如下: 87 | http://shrek.imdevsh.com/demo/css3d/space.html 88 | http://shrek.imdevsh.com/demo/css3d/simple.html 89 | 90 | http://shrek.imdevsh.com/demo/kfc/ 91 | 最后这里有个综合案例,几乎涵盖了常规项目的一般需求,文件没有压缩,可以直接从线上抓取查看。 92 | 93 | -------------------------------------------------------------------------------- /example/space.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 86 | 87 | -------------------------------------------------------------------------------- /example/cylinder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 99 | 100 | -------------------------------------------------------------------------------- /example/rubik.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | # 类 2 | 3 | **C3D.Object** 4 | 三维元素基类,拥有如下方法: 5 | 设置位置,物体坐标原点以旋转中心为准 6 | ```js 7 | obj.position(a,b,c); 8 | //等价于 9 | obj.x = a; 10 | obj.y = b; 11 | obj.z = c; 12 | 13 | obj.position(a,b); 14 | //等价于 15 | obj.x = a; 16 | obj.y = b; 17 | 18 | obj.position(a); 19 | //等价于 20 | obj.x = a; 21 | obj.y = a; 22 | obj.z = a; 23 | ``` 24 | 25 | 26 | 增量移动,在原来基础值上增加 27 | ```js 28 | obj.move(a,b,c); 29 | //等价于 30 | obj.x += a; 31 | obj.y += b; 32 | obj.z += c; 33 | 34 | obj.move(a,b); 35 | //等价于 36 | obj.x += a; 37 | obj.y += b; 38 | 39 | obj.move(a); 40 | //等价于 41 | obj.x += a; 42 | obj.y += a; 43 | obj.z += a; 44 | ``` 45 | 46 | 47 | 设置旋转中心,默认旋转中心是在物体中心 48 | ```js 49 | obj.origin(a,b,c); 50 | //等价于 51 | obj.originX = a; 52 | obj.originY = b; 53 | obj.originZ = c; 54 | 55 | obj.origin(a,b); 56 | //等价于 57 | obj.originX = a; 58 | obj.originY = b; 59 | 60 | obj.origin(a); 61 | //等价于 62 | obj.originX = a; 63 | obj.originY = a; 64 | obj.originZ = a; 65 | ``` 66 | 67 | 68 | 设置旋转角度 69 | ```js 70 | obj.rotation(a,b,c); 71 | //等价于 72 | obj.rotationX = a; 73 | obj.rotationY = b; 74 | obj.rotationZ = c; 75 | 76 | obj.rotation(a,b); 77 | //等价于 78 | obj.rotationX = a; 79 | obj.rotationY = b; 80 | 81 | obj.rotation(a); 82 | //等价于 83 | obj.rotationX = a; 84 | obj.rotationY = a; 85 | obj.rotationZ = a; 86 | ``` 87 | 88 | 89 | 增量旋转 90 | ```js 91 | obj.rotate(a,b,c); 92 | //等价于 93 | obj.rotationX += a; 94 | obj.rotationY += b; 95 | obj.rotationZ += c; 96 | 97 | obj.rotate(a,b); 98 | //等价于 99 | obj.rotationX += a; 100 | obj.rotationY += b; 101 | 102 | obj.rotate(a); 103 | //等价于 104 | obj.rotationX += a; 105 | obj.rotationY += a; 106 | obj.rotationZ += a; 107 | ``` 108 | 109 | 110 | 设置缩放比 111 | ```js 112 | obj.scale(a,b,c); 113 | //等价于 114 | obj.scaleX = a; 115 | obj.scaleY = b; 116 | obj.scaleZ = c; 117 | 118 | obj.scale(a,b); 119 | //等价于 120 | obj.scaleX = a; 121 | obj.scaleY = b; 122 | 123 | obj.scale(a); 124 | //等价于 125 | obj.scaleX = a; 126 | obj.scaleY = a; 127 | obj.scaleZ = a; 128 | ``` 129 | 130 | 131 | 设置尺寸 132 | ```js 133 | obj.size(a,b,c); 134 | //等价于 135 | obj.width = a; 136 | obj.height = b; 137 | obj.depth = c; 138 | 139 | obj.size(a,b); 140 | //等价于 141 | obj.width = a; 142 | obj.height = b; 143 | 144 | obj.size(a); 145 | //等价于 146 | obj.width = a; 147 | obj.height = a; 148 | obj.depth = a; 149 | ``` 150 | 151 | 152 | 设置旋转顺序,默认是.sort('X','Y','Z'),可以根据需要调整,必须是这三个参数,顺序自理 153 | ```js 154 | obj.sort('Y','X','Z'); 155 | ``` 156 | 157 | 设置名称(当该元素有名称的话,被addChild添加进入到别的元素时,可以直接用元素的属性方式访问,比如名称为'b1'的元素被加入到名称为'a1'的元素,之后就可以直接用a1.b1获得该元素.反之,被removeChild移除时也会删除绑定的属性.) 158 | ```js 159 | obj.name(string); 160 | ``` 161 | 162 | 添加删除子节点 163 | ```js 164 | obj.addChild(object3D); 165 | obj.removeChild(object3D); 166 | ``` 167 | 168 | 移除自身,从场景中移除 169 | ```js 170 | obj.remove(); 171 | ``` 172 | 173 | 拥有如下属性 174 | ```js 175 | obj.parent //父节点 176 | obj.children //子节点数组 177 | ``` 178 | 179 | 180 | **C3D.Sprite** 181 | 三维显示元素基类,继承自Object3D,是其他所有显示元素的基类。 182 | 一般用于作为容器使用,自身只会刷新位置,角度,缩放信息。没有高宽深的体积信息。拥有如下方法: 183 | 绑定事件 184 | ```js 185 | obj.on(); 186 | ``` 187 | 188 | 解除绑定事件 189 | ```js 190 | obj.off(); 191 | ``` 192 | 193 | 设置可见性 194 | ```js 195 | obj.visibility({visible:true,alpha:1}); 196 | //等价于 197 | obj.alpha = 1; 198 | obj.visible = true; 199 | ``` 200 | 201 | 设置滤镜(css3滤镜:grayscale,blur,saturate,sepia,hue-rotate,invert,brightness,contrast,opacity) 202 | ```js 203 | obj.filter({filterType:params}); 204 | ``` 205 | 206 | 设置材质(div的background相关的几种属性),在Sprite3D中,因为没有体积, 207 | image即background-image,color即background-color,其他属性以此类推,具体属性值也直接设置css的属性即可。比如size:'100% 100%'。 208 | ```js 209 | obj.material({image:'', color:'', position:'', size:'', repeat:'', origin:'', bothsides:true}); 210 | ``` 211 | 212 | 设置鼠标状态,设置为true就是按钮状态。 213 | ```js 214 | obj.buttonMode(bool); 215 | ``` 216 | 217 | 刷新相应的dom内容,位置,角度,尺寸,材质等信息只有在执行此命令后才会被作用到dom节点,以正常显示。一般只需要根据进行中的属性变化调用相应的update即可,比如只改变了x,y,z坐标就只要调用updateT()即可,不用调用update()这样很重的操作。 218 | ```js 219 | obj.update(); //一般只在创建元件时调用,会刷新所有信息。 220 | //等价于 221 | obj.updateS(); //刷新尺寸 222 | obj.updateO(); //刷新旋转中心 223 | obj.updateT(); //刷新位置,角度 224 | obj.updateM(); //刷新材质 225 | obj.updateV(); //刷新可见性 226 | obj.updateF(); //刷新滤镜 227 | ``` 228 | 229 | 230 | **C3D.Plane** 231 | 平面,顾名思义。 232 | 233 | 234 | **C3D.Stage** 235 | 三维场景,需要首先创建,其他所有内容都通过addchild方法放入场景即可。 236 | 237 | 238 | **C3D.Camera** 239 | 摄像机,最基本的3D摄像机,场景创建时自动创建,通过stage.camera属性获取。 240 | 241 | 242 | **C3D.Box** 243 | 一个立方体,指定材质时可以添加6面的图片定义。 244 | *eg.{front:"",back:"",left:"",right:"",up:"",down:""}* 245 | 246 | 247 | **C3D.Skybox** 248 | 天空盒子,适合用来制作全景背景,指定材质时可以添加6面的图片定义。 249 | *eg.{front:"",back:"",left:"",right:"",up:"",down:""}* 250 | 251 | 252 | 253 | 254 | 其他全局方法: 255 | **C3D.getRandomColor();** 256 | **C3D.rgb2hex();** 257 | **C3D.hex2rgb();** 258 | 259 | **C3D.create(obj);** 260 | 此方法非常有用,可以帮助快速创建场景. 261 | 262 | -------------------------------------------------------------------------------- /css3d.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * GIT: https://github.com/shrekshrek/css3d-engine 3 | **/ 4 | 5 | !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):t.C3D=i()}(this,function(){"use strict";var t,r={},s="",i=document.createElement("div"),e=["Webkit","Moz","Ms","O"];for(t in e)if(e[t]+"Transform"in i.style){s=e[t];break}function n(t){return Math.round(t)}function h(t){return Math.round(100*t)/100}function o(t){return t.replace(/\b(\w)|\s(\w)/g,function(t){return t.toUpperCase()})}r.getRandomColor=function(){return"#"+("00000"+(16777216*Math.random()<<0).toString(16)).slice(-6)},r.rgb2hex=function(t,i,e){return(t<<16|i<<8|e).toString(16)},r.hex2rgb=function(t){t=Math.floor("0x"+t);return[t>>16&255,t>>8&255,255&t]};function a(){this.initialize.apply(this,arguments)}function l(){a.apply(this,arguments)}function u(){l.apply(this,arguments)}function p(){a.apply(this,arguments)}function d(){l.apply(this,arguments)}function c(){l.apply(this,arguments)}function _(){c.apply(this,arguments)}Object.assign(a.prototype,{x:0,y:0,z:0,position:function(t,i,e){if(null==t)throw"position arguments is wrong!";return this.x=t,this.y=null==i?t:i,this.z=null==e?t:e,this},move:function(t,i,e){if(null==t)throw"move arguments is wrong!";return this.x+=t,this.y+=null==i?t:i,this.z+=null==e?t:e,this},rotationX:0,rotationY:0,rotationZ:0,rotation:function(t,i,e){if(null==t)throw"rotation arguments is wrong!";return this.rotationX=t,this.rotationY=null==i?t:i,this.rotationZ=null==e?t:e,this},rotate:function(t,i,e){if(null==t)throw"rotate arguments is wrong!";return this.rotationX+=t,this.rotationY+=null==i?t:i,this.rotationZ+=null==e?t:e,this},scaleX:1,scaleY:1,scaleZ:1,scale:function(t,i,e){if(null==t)throw"scale arguments is wrong!";return this.scaleX=t,this.scaleY=null==i?t:i,this.scaleZ=null==e?t:e,this},width:0,height:0,depth:0,size:function(t,i,e){if(null==t)throw"size arguments is wrong!";return this.width=t,this.height=null==i?t:i,this.depth=null==e?t:e,this},originX:0,originY:0,originZ:0,__orgO:{x:0,y:0,z:0},__orgT:{x:0,y:0,z:0},__orgF:{x:0,y:0,z:0},origin:function(t,i,e){if(null==t)throw"size arguments is wrong!";return this.originX=t,this.originY=null==i?t:i,this.originZ=null==e?t:e,this},__sort:["X","Y","Z"],sort:function(t,i,e){if(3> 16 & 255; 42 | var _g = _n >> 8 & 255; 43 | var _b = _n & 255; 44 | return [_r, _g, _b]; 45 | }; 46 | 47 | 48 | // --------------------------------------------------------------------其他辅助方法 49 | function fixed0(n) { 50 | return Math.round(n); 51 | } 52 | 53 | function fixed2(n) { 54 | return Math.round(n * 100) / 100; 55 | } 56 | 57 | // webkitTransform 转 WebkitTransform 58 | function firstUper(str) { 59 | return str.replace(/\b(\w)|\s(\w)/g, function (m) { 60 | return m.toUpperCase(); 61 | }); 62 | } 63 | 64 | 65 | // --------------------------------------------------------------------Object3D 66 | var Object3D = function () { 67 | this.initialize.apply(this, arguments); 68 | }; 69 | 70 | Object.assign(Object3D.prototype, { 71 | x: 0, 72 | y: 0, 73 | z: 0, 74 | position: function (x, y, z) { 75 | if (x == undefined) { 76 | throw 'position arguments is wrong!'; 77 | } else { 78 | this.x = x; 79 | this.y = y == undefined ? x : y; 80 | this.z = z == undefined ? x : z; 81 | } 82 | return this; 83 | }, 84 | move: function (x, y, z) { 85 | if (x == undefined) { 86 | throw 'move arguments is wrong!'; 87 | } else { 88 | this.x += x; 89 | this.y += y == undefined ? x : y; 90 | this.z += z == undefined ? x : z; 91 | } 92 | return this; 93 | }, 94 | 95 | rotationX: 0, 96 | rotationY: 0, 97 | rotationZ: 0, 98 | rotation: function (x, y, z) { 99 | if (x == undefined) { 100 | throw 'rotation arguments is wrong!'; 101 | } else { 102 | this.rotationX = x; 103 | this.rotationY = y == undefined ? x : y; 104 | this.rotationZ = z == undefined ? x : z; 105 | } 106 | return this; 107 | }, 108 | rotate: function (x, y, z) { 109 | if (x == undefined) { 110 | throw 'rotate arguments is wrong!'; 111 | } else { 112 | this.rotationX += x; 113 | this.rotationY += y == undefined ? x : y; 114 | this.rotationZ += z == undefined ? x : z; 115 | } 116 | return this; 117 | }, 118 | 119 | scaleX: 1, 120 | scaleY: 1, 121 | scaleZ: 1, 122 | scale: function (x, y, z) { 123 | if (x == undefined) { 124 | throw 'scale arguments is wrong!'; 125 | } else { 126 | this.scaleX = x; 127 | this.scaleY = y == undefined ? x : y; 128 | this.scaleZ = z == undefined ? x : z; 129 | } 130 | return this; 131 | }, 132 | 133 | width: 0, 134 | height: 0, 135 | depth: 0, 136 | size: function (x, y, z) { 137 | if (x == undefined) { 138 | throw 'size arguments is wrong!'; 139 | } else { 140 | this.width = x; 141 | this.height = y == undefined ? x : y; 142 | this.depth = z == undefined ? x : z; 143 | } 144 | return this; 145 | }, 146 | 147 | originX: 0, 148 | originY: 0, 149 | originZ: 0, 150 | __orgO: {x: 0, y: 0, z: 0}, 151 | __orgT: {x: 0, y: 0, z: 0}, 152 | __orgF: {x: 0, y: 0, z: 0}, 153 | origin: function (x, y, z) { 154 | if (x == undefined) { 155 | throw 'size arguments is wrong!'; 156 | } else { 157 | this.originX = x; 158 | this.originY = y == undefined ? x : y; 159 | this.originZ = z == undefined ? x : z; 160 | } 161 | return this; 162 | }, 163 | 164 | __sort: ['X', 'Y', 'Z'], 165 | sort: function (s0, s1, s2) { 166 | if (arguments.length > 3) throw 'sort arguments is wrong!'; 167 | this.__sort = [s0, s1, s2]; 168 | return this; 169 | }, 170 | 171 | initialize: function () { 172 | this.x = 0; 173 | this.y = 0; 174 | this.z = 0; 175 | this.rotationX = 0; 176 | this.rotationY = 0; 177 | this.rotationZ = 0; 178 | this.scaleX = 1; 179 | this.scaleY = 1; 180 | this.scaleZ = 1; 181 | this.width = 0; 182 | this.height = 0; 183 | this.depth = 0; 184 | this.originX = '50%'; 185 | this.originY = '50%'; 186 | this.originZ = '0px'; 187 | this.__orgO = {x: '50%', y: '50%', z: '0px'}; 188 | this.__orgT = {x: '-50%', y: '-50%', z: '0px'}; 189 | this.__orgF = {x: 0, y: 0, z: 0}; 190 | this.children = []; 191 | }, 192 | 193 | parent: null, 194 | children: null, 195 | addChild: function (view) { 196 | if (view.parent != null) view.parent.removeChild(view); 197 | if (view.__name != '') { 198 | if (this[view.__name] !== undefined) throw view.__name + ' already exist!'; 199 | this[view.__name] = view; 200 | } 201 | this.children.push(view); 202 | view.parent = this; 203 | return this; 204 | }, 205 | removeChild: function (view) { 206 | for (var i = this.children.length - 1; i >= 0; i--) { 207 | if (this.children[i] === view) { 208 | if (view.__name != '') delete this[view.__name]; 209 | this.children.splice(i, 1); 210 | view.parent = null; 211 | return this; 212 | } 213 | } 214 | return this; 215 | }, 216 | removeAllChild: function () { 217 | for (var i = this.children.length - 1; i >= 0; i--) { 218 | var view = this.children[i]; 219 | if (view.__name != '') delete this[view.__name]; 220 | view.parent = null; 221 | } 222 | this.children = []; 223 | return this; 224 | }, 225 | remove: function () { 226 | if (this.parent != null) { 227 | this.parent.removeChild(this); 228 | } 229 | return this; 230 | } 231 | 232 | }); 233 | 234 | 235 | // --------------------------------------------------------------------Sprite3D 236 | var Sprite3D = function () { 237 | Object3D.apply(this, arguments); 238 | }; 239 | 240 | Sprite3D.prototype = Object.assign(Object.create(Object3D.prototype), { 241 | constructor: Sprite3D, 242 | 243 | el: null, 244 | alpha: 1, 245 | visible: true, 246 | initialize: function (params) { 247 | Object3D.prototype.initialize.apply(this, [params]); 248 | 249 | this.__name = ''; 250 | this.__id = ''; 251 | this.__class = ''; 252 | 253 | this.alpha = 1; 254 | this.visible = true; 255 | 256 | var _dom; 257 | 258 | if (params && params.el) { 259 | switch (typeof params.el) { 260 | case 'string': 261 | _dom = document.createElement('div'); 262 | _dom.innerHTML = params.el; 263 | break; 264 | case 'object': 265 | if (params.el.nodeType === 1) { 266 | _dom = params.el; 267 | } 268 | break; 269 | } 270 | } 271 | 272 | if (!_dom) { 273 | _dom = document.createElement('div'); 274 | } 275 | 276 | _dom.style.position = 'absolute'; 277 | _dom.style[prefix + 'Transform'] = 'translateZ(0px)'; 278 | _dom.style[prefix + 'TransformStyle'] = 'preserve-3d'; 279 | this.el = _dom; 280 | _dom.le = this; 281 | 282 | }, 283 | 284 | __name: '', 285 | name: function (str) { 286 | this.__name = str; 287 | if (str == '') delete this.el.dataset.name; 288 | else this.el.dataset.name = str; 289 | return this; 290 | }, 291 | 292 | __id: '', 293 | id: function (str) { 294 | this.__id = str; 295 | this.el.id = str; 296 | return this; 297 | }, 298 | 299 | __class: '', 300 | class: function (str) { 301 | this.__class = str; 302 | this.el.className = str; 303 | return this; 304 | }, 305 | 306 | update: function () { 307 | this.updateS(); 308 | this.updateM(); 309 | this.updateO(); 310 | this.updateT(); 311 | this.updateV(); 312 | return this; 313 | }, 314 | 315 | updateS: function () { 316 | //this.el.style[prefix + 'TransformOrigin'] = '50% 50%'; 317 | return this; 318 | }, 319 | 320 | updateM: function () { 321 | if (!this.__mat) return this; 322 | 323 | for (var i in this.__mat) { 324 | switch (i) { 325 | case 'bothsides': 326 | this.el.style[prefix + 'BackfaceVisibility'] = this.__mat[i] ? 'visible' : 'hidden'; 327 | break; 328 | case 'image': 329 | this.el.style['background' + firstUper(i)] = this.__mat[i] !== '' ? ('url(' + this.__mat[i] + ')') : ''; 330 | break; 331 | default: 332 | this.el.style['background' + firstUper(i)] = this.__mat[i]; 333 | break; 334 | } 335 | } 336 | 337 | return this; 338 | }, 339 | 340 | updateO: function () { 341 | if (typeof (this.originX) == 'number') { 342 | var _x = fixed0(this.originX - this.__orgF.x); 343 | this.__orgO.x = _x + 'px'; 344 | this.__orgT.x = -_x + 'px'; 345 | } else { 346 | this.__orgO.x = this.originX; 347 | this.__orgT.x = '-' + this.originX; 348 | } 349 | 350 | if (typeof (this.originY) == 'number') { 351 | var _y = fixed0(this.originY - this.__orgF.y); 352 | this.__orgO.y = _y + 'px'; 353 | this.__orgT.y = -_y + 'px'; 354 | } else { 355 | this.__orgO.y = this.originY; 356 | this.__orgT.y = '-' + this.originY; 357 | } 358 | 359 | if (typeof (this.originZ) == 'number') { 360 | var _z = fixed0(this.originZ - this.__orgF.z); 361 | this.__orgO.z = _z + 'px'; 362 | this.__orgT.z = -_z + 'px'; 363 | } else { 364 | this.__orgO.z = this.__orgT.z = '0px'; 365 | } 366 | 367 | this.el.style[prefix + 'TransformOrigin'] = this.__orgO.x + ' ' + this.__orgO.y + ' ' + this.__orgO.z; 368 | 369 | return this; 370 | }, 371 | 372 | updateT: function () { 373 | var _S0 = this.__sort[0]; 374 | var _S1 = this.__sort[1]; 375 | var _S2 = this.__sort[2]; 376 | this.el.style[prefix + 'Transform'] = 'translate3d(' + this.__orgT.x + ', ' + this.__orgT.y + ', ' + this.__orgT.z + ') ' + 'translate3d(' + fixed2(this.x) + 'px,' + fixed2(this.y) + 'px,' + fixed2(this.z) + 'px) ' + 'rotate' + _S0 + '(' + fixed2(this['rotation' + _S0]) % 360 + 'deg) ' + 'rotate' + _S1 + '(' + fixed2(this['rotation' + _S1]) % 360 + 'deg) ' + 'rotate' + _S2 + '(' + fixed2(this['rotation' + _S2]) % 360 + 'deg) ' + 'scale3d(' + fixed2(this.scaleX) + ', ' + fixed2(this.scaleY) + ', ' + fixed2(this.scaleZ) + ')'; 377 | return this; 378 | }, 379 | 380 | updateV: function () { 381 | this.el.style.opacity = this.alpha; 382 | this.el.style.display = this.visible ? 'block' : 'none'; 383 | return this; 384 | }, 385 | 386 | addChild: function (view) { 387 | Object3D.prototype.addChild.apply(this, [view]); 388 | if (this.el && view.el) 389 | this.el.appendChild(view.el); 390 | return this; 391 | }, 392 | 393 | removeChild: function (view) { 394 | for (var i = this.children.length - 1; i >= 0; i--) { 395 | if (this.children[i] === view) { 396 | if (view.__name != '') delete this[view.__name]; 397 | this.children.splice(i, 1); 398 | view.parent = null; 399 | this.el.removeChild(view.el); 400 | return this; 401 | } 402 | } 403 | return this; 404 | }, 405 | 406 | removeAllChild: function () { 407 | for (var i = this.children.length - 1; i >= 0; i--) { 408 | var view = this.children[i]; 409 | if (view.__name != '') delete this[view.__name]; 410 | view.parent = null; 411 | this.el.removeChild(view.el); 412 | } 413 | this.children = []; 414 | return this; 415 | }, 416 | 417 | on: function (events) { 418 | if (typeof (events) === 'object') { 419 | for (var i in events) { 420 | this.el.addEventListener(i, events[i], false); 421 | } 422 | } else if (arguments.length === 2) { 423 | this.el.addEventListener(arguments[0], arguments[1], false); 424 | } else if (arguments.length === 3) { 425 | this.el.addEventListener(arguments[0], arguments[1], arguments[2]); 426 | } 427 | return this; 428 | }, 429 | off: function (events) { 430 | if (typeof (events) === 'object') { 431 | for (var i in events) { 432 | this.el.removeEventListener(i, events[i], false); 433 | } 434 | } else if (arguments.length === 2) { 435 | this.el.removeEventListener(arguments[0], arguments[1], false); 436 | } 437 | return this; 438 | }, 439 | 440 | buttonMode: function (bool) { 441 | if (bool) { 442 | this.el.style.cursor = 'pointer'; 443 | } else { 444 | this.el.style.cursor = 'auto'; 445 | } 446 | return this; 447 | }, 448 | 449 | __mat: null, 450 | material: function (obj) { 451 | this.__mat = obj; 452 | return this; 453 | }, 454 | 455 | visibility: function (obj) { 456 | if (obj.visible !== undefined) 457 | this.visible = obj.visible; 458 | 459 | if (obj.alpha !== undefined) 460 | this.alpha = obj.alpha; 461 | 462 | return this; 463 | } 464 | 465 | }); 466 | 467 | 468 | // --------------------------------------------------------------------Stage3D 469 | var Stage3D = function () { 470 | Sprite3D.apply(this, arguments); 471 | }; 472 | 473 | Stage3D.prototype = Object.assign(Object.create(Sprite3D.prototype), { 474 | constructor: Stage3D, 475 | 476 | camera: null, 477 | fov: null, 478 | __rfix: null, 479 | __pfix: null, 480 | initialize: function (params) { 481 | Sprite3D.prototype.initialize.apply(this, [params]); 482 | 483 | if (!(params && params.el)) { 484 | this.el.style.top = '0px'; 485 | this.el.style.left = '0px'; 486 | this.el.style.width = '0px'; 487 | this.el.style.height = '0px'; 488 | } 489 | this.el.style[prefix + 'Perspective'] = '800px'; 490 | this.el.style[prefix + 'TransformStyle'] = 'flat'; 491 | this.el.style[prefix + 'Transform'] = ''; 492 | this.el.style.overflow = 'hidden'; 493 | 494 | this.__rfix = new C3D.Sprite(); 495 | this.el.appendChild(this.__rfix.el); 496 | 497 | this.__pfix = new C3D.Sprite(); 498 | this.__rfix.el.appendChild(this.__pfix.el); 499 | 500 | this.setCamera(new C3D.Camera()); 501 | }, 502 | 503 | updateS: function () { 504 | this.el.style.width = fixed0(this.width) + 'px'; 505 | this.el.style.height = fixed0(this.height) + 'px'; 506 | return this; 507 | }, 508 | updateT: function () { 509 | this.fov = fixed0(0.5 / Math.tan((this.camera.fov * 0.5) / 180 * Math.PI) * this.height); 510 | this.el.style[prefix + 'Perspective'] = this.fov + 'px'; 511 | this.__rfix.position(fixed0(this.width / 2), fixed0(this.height / 2), this.fov).rotation(-this.camera.rotationX, -this.camera.rotationY, -this.camera.rotationZ).updateT(); 512 | this.__pfix.position(-this.camera.x, -this.camera.y, -this.camera.z).updateT(); 513 | return this; 514 | }, 515 | 516 | addChild: function (view) { 517 | this.__pfix.addChild(view); 518 | return this; 519 | }, 520 | removeChild: function (view) { 521 | this.__pfix.removeChild(view); 522 | return this; 523 | }, 524 | removeAllChild: function () { 525 | this.__pfix.removeAllChild(); 526 | return this; 527 | }, 528 | setCamera: function (cam) { 529 | if (this.camera) { 530 | this.camera.stage = null; 531 | } 532 | this.camera = cam; 533 | this.camera.stage = this; 534 | return this; 535 | } 536 | 537 | }); 538 | 539 | 540 | // --------------------------------------------------------------------Camera3D 541 | var Camera3D = function () { 542 | Object3D.apply(this, arguments); 543 | }; 544 | 545 | Camera3D.prototype = Object.assign(Object.create(Object3D.prototype), { 546 | constructor: Camera3D, 547 | 548 | fov: null, 549 | stage: null, 550 | initialize: function (params) { 551 | Object3D.prototype.initialize.apply(this, [params]); 552 | this.fov = 75; 553 | }, 554 | update: function () { 555 | this.updateT(); 556 | return this; 557 | }, 558 | updateS: function () { 559 | return this; 560 | }, 561 | updateM: function () { 562 | return this; 563 | }, 564 | updateT: function () { 565 | if (this.stage) this.stage.updateT(); 566 | return this; 567 | }, 568 | updateV: function () { 569 | return this; 570 | } 571 | 572 | }); 573 | 574 | 575 | // --------------------------------------------------------------------Plane3D 576 | var Plane3D = function () { 577 | Sprite3D.apply(this, arguments); 578 | }; 579 | 580 | Plane3D.prototype = Object.assign(Object.create(Sprite3D.prototype), { 581 | constructor: Plane3D, 582 | 583 | initialize: function (params) { 584 | Sprite3D.prototype.initialize.apply(this, [params]); 585 | }, 586 | 587 | update: function () { 588 | Sprite3D.prototype.update.apply(this); 589 | this.updateF(); 590 | return this; 591 | }, 592 | 593 | updateS: function () { 594 | this.el.style.width = fixed0(this.width) + 'px'; 595 | this.el.style.height = fixed0(this.height) + 'px'; 596 | return this; 597 | }, 598 | 599 | updateF: function () { 600 | if (!this.__flt) return this; 601 | 602 | var _flt = ''; 603 | for (var i in this.__flt) { 604 | _flt += (this.__flt[i] !== '' ? (i + '(' + this.__flt[i].join(',') + ')') : ''); 605 | } 606 | if (_flt !== '') this.el.style[prefix + 'Filter'] = _flt; 607 | 608 | return this; 609 | }, 610 | 611 | __flt: null, 612 | filter: function (obj) { 613 | this.__flt = obj; 614 | return this; 615 | } 616 | 617 | }); 618 | 619 | // --------------------------------------------------------------------Box3D 620 | var Box3D = function () { 621 | Sprite3D.apply(this, arguments); 622 | }; 623 | 624 | Box3D.prototype = Object.assign(Object.create(Sprite3D.prototype), { 625 | constructor: Box3D, 626 | 627 | front: null, 628 | back: null, 629 | left: null, 630 | right: null, 631 | up: null, 632 | down: null, 633 | initialize: function (params) { 634 | Sprite3D.prototype.initialize.apply(this, [params]); 635 | 636 | this.front = new C3D.Plane(); 637 | this.front.name = 'front'; 638 | this.addChild(this.front); 639 | 640 | this.back = new C3D.Plane(); 641 | this.back.name = 'back'; 642 | this.addChild(this.back); 643 | 644 | this.left = new C3D.Plane(); 645 | this.left.name = 'left'; 646 | this.addChild(this.left); 647 | 648 | this.right = new C3D.Plane(); 649 | this.right.name = 'right'; 650 | this.addChild(this.right); 651 | 652 | this.up = new C3D.Plane(); 653 | this.up.name = 'up'; 654 | this.addChild(this.up); 655 | 656 | this.down = new C3D.Plane(); 657 | this.down.name = 'down'; 658 | this.addChild(this.down); 659 | }, 660 | 661 | update: function () { 662 | Sprite3D.prototype.update.apply(this); 663 | this.updateF(); 664 | return this; 665 | }, 666 | 667 | updateS: function () { 668 | var _w = fixed0(this.width); 669 | var _h = fixed0(this.height); 670 | var _d = fixed0(this.depth); 671 | 672 | this.__orgF.x = this.width / 2; 673 | this.__orgF.y = this.height / 2; 674 | this.__orgF.z = this.depth / 2; 675 | 676 | this.front.size(_w, _h, 0).position(0, 0, _d / 2).rotation(0, 0, 0).updateS().updateT(); 677 | this.back.size(_w, _h, 0).position(0, 0, -_d / 2).rotation(0, 180, 0).updateS().updateT(); 678 | this.left.size(_d, _h, 0).position(-_w / 2, 0, 0).rotation(0, -90, 0).updateS().updateT(); 679 | this.right.size(_d, _h, 0).position(_w / 2, 0, 0).rotation(0, 90, 0).updateS().updateT(); 680 | this.up.size(_w, _d, 0).position(0, -_h / 2, 0).rotation(90, 0, 0).updateS().updateT(); 681 | this.down.size(_w, _d, 0).position(0, _h / 2, 0).rotation(-90, 0, 0).updateS().updateT(); 682 | 683 | return this; 684 | }, 685 | 686 | updateM: function () { 687 | if (!this.__mat) return this; 688 | 689 | var _unique = true; 690 | for (var i in this.__mat) { 691 | switch (i) { 692 | case 'front': 693 | case 'back': 694 | case 'left': 695 | case 'right': 696 | case 'up': 697 | case 'down': 698 | if (this.__mat[i].bothsides == undefined) this.__mat[i].bothsides = false; 699 | this[i].material(this.__mat[i]).updateM(); 700 | _unique = false; 701 | break; 702 | } 703 | } 704 | 705 | if (_unique) { 706 | if (this.__mat.bothsides == undefined) this.__mat.bothsides = false; 707 | this.front.material(this.__mat).updateM(); 708 | this.back.material(this.__mat).updateM(); 709 | this.left.material(this.__mat).updateM(); 710 | this.right.material(this.__mat).updateM(); 711 | this.up.material(this.__mat).updateM(); 712 | this.down.material(this.__mat).updateM(); 713 | } 714 | 715 | return this; 716 | }, 717 | 718 | updateF: function () { 719 | if (!this.__flt) return this; 720 | 721 | this.front.filter(this.__flt).updateF(); 722 | this.back.filter(this.__flt).updateF(); 723 | this.left.filter(this.__flt).updateF(); 724 | this.right.filter(this.__flt).updateF(); 725 | this.up.filter(this.__flt).updateF(); 726 | this.down.filter(this.__flt).updateF(); 727 | 728 | return this; 729 | }, 730 | 731 | __flt: null, 732 | filter: function (obj) { 733 | this.__flt = obj; 734 | return this; 735 | } 736 | 737 | }); 738 | 739 | // --------------------------------------------------------------------Skybox3D 740 | var Skybox3D = function () { 741 | Box3D.apply(this, arguments); 742 | }; 743 | 744 | Skybox3D.prototype = Object.assign(Object.create(Box3D.prototype), { 745 | constructor: Skybox3D, 746 | 747 | updateS: function () { 748 | var _w = fixed0(this.width); 749 | var _h = fixed0(this.height); 750 | var _d = fixed0(this.depth); 751 | 752 | this.__orgF.x = this.width / 2; 753 | this.__orgF.y = this.height / 2; 754 | this.__orgF.z = this.depth / 2; 755 | 756 | this.front.size(_w, _h, 0).position(0, 0, -_d / 2).rotation(0, 0, 0).updateS().updateT(); 757 | this.back.size(_w, _h, 0).position(0, 0, _d / 2).rotation(0, 180, 0).updateS().updateT(); 758 | this.left.size(_d, _h, 0).position(-_w / 2, 0, 0).rotation(0, 90, 0).updateS().updateT(); 759 | this.right.size(_d, _h, 0).position(_w / 2, 0, 0).rotation(0, -90, 0).updateS().updateT(); 760 | this.up.size(_w, _d, 0).position(0, -_h / 2, 0).rotation(-90, 0, 0).updateS().updateT(); 761 | this.down.size(_w, _d, 0).position(0, _h / 2, 0).rotation(90, 0, 0).updateS().updateT(); 762 | 763 | return this; 764 | } 765 | 766 | }); 767 | 768 | Object.assign(C3D, { 769 | Object: Object3D, 770 | Sprite: Sprite3D, 771 | Stage: Stage3D, 772 | Camera: Camera3D, 773 | Plane: Plane3D, 774 | Box: Box3D, 775 | Skybox: Skybox3D 776 | }); 777 | 778 | 779 | // --------------------------------------------------------------------创建场景 780 | function createObj(obj) { 781 | var _o; 782 | switch (obj.type) { 783 | case 'sprite': 784 | _o = new C3D.Sprite(obj.el ? {el: obj.el} : undefined); 785 | break; 786 | case 'plane': 787 | _o = new C3D.Plane(obj.el ? {el: obj.el} : undefined); 788 | break; 789 | case 'box': 790 | _o = new C3D.Box(obj.el ? {el: obj.el} : undefined); 791 | break; 792 | case 'skybox': 793 | _o = new C3D.Skybox(obj.el ? {el: obj.el} : undefined); 794 | break; 795 | } 796 | 797 | if (obj.size != undefined) _o.size.apply(_o, obj.size); 798 | if (obj.position != undefined) _o.position.apply(_o, obj.position); 799 | if (obj.rotation != undefined) _o.rotation.apply(_o, obj.rotation); 800 | if (obj.scale != undefined) _o.scale.apply(_o, obj.scale); 801 | if (obj.origin != undefined) _o.origin.apply(_o, obj.origin); 802 | if (obj.visibility != undefined) _o.visibility.apply(_o, obj.visibility); 803 | if (obj.material != undefined) _o.material.apply(_o, obj.material); 804 | if (obj.filter != undefined) _o.filter.apply(_o, obj.filter); 805 | if (obj.name != undefined) _o.name.apply(_o, [obj.name]); 806 | if (obj.id != undefined) _o.id.apply(_o, [obj.id]); 807 | if (obj.class != undefined) _o.class.apply(_o, [obj.class]); 808 | 809 | _o.update(); 810 | 811 | if (obj.children) { 812 | for (var i = 0, _len = obj.children.length; i < _len; i++) { 813 | var _obj = obj.children[i]; 814 | var _o2 = createObj(_obj); 815 | _o.addChild(_o2); 816 | } 817 | } 818 | 819 | return _o; 820 | } 821 | 822 | C3D.create = function (obj) { 823 | if (typeof (obj) == 'object') { 824 | var _obj = obj instanceof Array ? {type: 'sprite', children: obj} : obj; 825 | return createObj(_obj); 826 | } else { 827 | throw 'create arguments is wrong!'; 828 | } 829 | }; 830 | 831 | return C3D; 832 | 833 | }))); --------------------------------------------------------------------------------