1、陀螺仪,x、y、z轴
2、3D全景制作
3、立方体的制作
1. 陀螺仪,规定了x、y、z的旋转角度,手机平放的话,水平方向是x轴,沿x轴旋转的角度叫beta角,范围是(-180,180),沿y轴旋转的角度叫gamma,范围是(-90,90),沿z轴旋转的角度叫alpha,范围是(0, 360),这个旋转是平面内旋转。
陀螺仪的使用:
手机旋转会触发三个事件:
a. deviceorientation 设备的物理方向信息,表示一系列本地坐标系的旋角
window.addEventListener('deviceorientation', function(event){
//处理event.alpha(z), event.beta(x), event.gamma(y)
},true)
b. compassneedscalibration 获取罗盘校准
widnow.addEventListener('compassneedscalibration', function(event){
alert('')
},true)
有一个很重要的概念需要明白,一个立方体,每个面在旋转的时候,旋转的坐标轴会根据旋转而变动,面在哪,坐标轴就在哪。
首先要明白transform的属性:
transform-style: flat | preserve-3d
transform-origin: 默认是中间点,50% 50% 0
可以理解为元素左下角是原点坐标值,向上向右为正值,z轴在原点为止可以理解为始终是0。
3D旋转需要用到5个值,rotateX、rotateY、rotateZ,translateZ,这四个是transform的值,前三个是表示旋转的角度,
x轴向上旋转是正值(顺时针),y轴向里旋转是正值(逆时针),z轴顺时针是正值,逆时针是负值,z轴旋转不具有空间性,x和y是围绕坐标原点做3D旋转
第四个表示透视的距离,所以还有一个透视的值perspective: 201px; 即假设的眼睛离物体的距离。translateZ的值越小,说明离得越远,根据近大远小的原理,物体也就越小,translateZ的值越大,物体越大,超过201后物体就消失了,因为跑到眼睛后面去了,所以看不到了。
立方体的代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> .box{ position: relative; width: 160px; height: 160px; margin: 40px auto 0 auto; transform-style: preserve-3d; transform-origin: 80px 80px 0; -webkit-animation-name: animation; -webkit-animation-timing-function: ease-in-out; -webkit-animation-iteration-count: infinite; -webkit-animation-duration: 6s; margin:80; } .box div{ position: absolute; width: 160px; height: 160px; text-align: center; background-color: rgba(230,219,116,0.8); font-size: 120px; border: 4px solid #ccc; } .box .one{ transform: translateZ(80px); } .box .two{ transform: rotateX(-90deg) translateZ(80px); } .box .three{ transform: rotateY(90deg) rotateX(90deg) translateZ(80px); } .box .four{ transform: rotateY(180deg) translateZ(80px); } .box .five{ transform: rotateY(-90deg) translateZ(80px); } .box .six{ transform: rotateY(90deg) translateZ(80px); } @keyframes animation{ 16% { -webkit-transform: rotateY(-90deg);} 33% { -webkit-transform: rotateY(-90deg) rotateZ(135deg);} 50% { -webkit-transform: rotateY(225deg) rotateZ(135deg);} 66% { -webkit-transform: rotateY(135deg) rotateX(135deg);} 83% { -webkit-transform: rotateX(135deg);} } </style> </head> <body> <div class="box"> <div class="one">A</div> <div class="two">B</div> <div class="three">C</div> <div class="four">D</div> <div class="five">E</div> <div class="six">F</div> </div> </body> </html>
还有另一种实现方式,这个直接修改每个元素的transform-origin,更容易理解
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>css3 动画</title> <style type="text/css"> .container{ margin: 30px; position: relative; width: 100px; height: 100px; box-sizing: border-box; /*border: 1px solid #ccc;*/ /*-webkit-perspective: 200;*/ transform-style: preserve-3d; /*transform: perspective(100);*/ animation: rotate 3s infinite; } .container div{ position: absolute; width: 100px; height: 100px; font-size: 80px; background: rgba(80,80,80,0.5); border: 1px solid #ccc; } .a{ /*transform: translateZ(50px);*/ } .b{ transform-origin: 100% 100%; transform: rotateY(-90deg); } .c{ transform-origin: 0 0; transform: rotateX(-90deg); } .d{ transform-origin: 100% 100%; transform: rotateX(90deg); } .e{ transform-origin: 0 0; transform: rotateY(90deg); } .f{ transform: translateZ(-100px); /*transform-origin: 0 0;*/ /*transform: rotateY(90deg);*/ /*transform-origin: 100% 100%;*/ /*transform: rotateZ(90deg);*/ } @keyframes rotate{ 16% { -webkit-transform: rotateY(-90deg);} 33% { -webkit-transform: rotateY(-90deg) rotateZ(135deg);} 50% { -webkit-transform: rotateY(225deg) rotateZ(135deg);} 66% { -webkit-transform: rotateY(135deg) rotateX(135deg);} 83% { -webkit-transform: rotateX(135deg);} } </style> </head> <body> <div class="container"> <div class="a">A</div> <div class="b">B</div> <div class="c">C</div> <div class="d">D</div> <div class="e">E</div> <div class="f">F</div> </div> </body> </html>
淘宝造物节,3D全景的代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /> <title>css3d造物节</title> <style> html,body{ padding: 0; margin: 0; } body{ background: url(img/bg.jpg); } #container{ margin: 0 auto 0 auto; width: 8.0625rem; perspective: 25rem; /*这个是根据半径算出来的,按常规的16px的字体,半径是401,就是下面js中算的radius 约等于25rem */ } #box{ height: 100%; transform-style: preserve-3d; transform-origin: 50% 50% 0; } #box > div{ position: absolute; width: 8.0625rem; height: 73.125rem; } </style> </head> <body> <div id="container"> <div id="box"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div> </div> <script type="text/javascript"> var box = document.getElementById('box'); var div = box.getElementsByTagName('div'); var radius = calculateR(129, 20); console.log(radius); //添加背景图和初始化位置 for(let i = 0; i < div.length; i++){ div[i].style.background = 'url("img/p' + (i+1) + '.png") no-repeat center'; div[i].style.transform = 'rotateY(' + 360/div.length*i + 'deg) translateZ(' + radius + 'px)'; } function calculateR(length, num){ return Math.round(length / (2 * Math.tan(Math.PI/num)))-6; } //添加事件 var startx = 0, x = 0, endx = 0, flag = true; box.addEventListener('touchstart', function(e){ e.preventDefault(); //这里需要注意,每次要减去x值,为什么要减呢 //因为rotate的值变化了,它的坐标也相应的变化了,否则每次都是在相同的位置变化 var touch = e.targetTouches[0].pageX startx = touch - x; }) box.addEventListener('touchmove', function(e){ if(flag){ e.preventDefault(); endx = e.targetTouches[0].pageX; x = endx - startx; box.style.transform = 'rotateY(' + x + 'deg)'; }else{ return false; } }) box.addEventListener('touchend', function(e){ e.preventDefault(); }) //手机运动,touch失效 window.addEventListener('deviceoriention', function(e){ var gamma = e.gamma; if(Math.abs(gamma) > 0){ flag = false; box.style.transform = 'rotateY('+ gamma *3 +'deg)'; }else{ flag = true; } }) //以上是简单的效果,还有x轴beta运动,z轴alpha运动 </script> </body> </html>