rotate3d简写

如何结合rotateX(50deg) rotateY(20deg) rotateZ(15deg)以简写方式rotate3d()

rotate3d(1, 0, 0, 50deg) rotateX(50deg)相当于rotate3d(1, 0, 0, 50deg)

rotateY(20deg)相当于rotate3d(0, 1, 0, 20deg)

rotateZ(15deg)相当于rotate3d(0, 0, 1, 15deg)

所以…

rotateX(50deg) rotateY(20deg) rotateZ(15deg)

相当于

rotate3d(1, 0, 0, 50deg) rotate3d(0, 1, 0, 20deg) rotate3d(0, 0, 1, 15deg)


对于一个通用的rotate3d(x, y, z, α) ,你有matrix

通用旋转矩阵

哪里

说明


你现在得到每个3个rotate3d变换的matrix,并将它们相乘。 所得到的matrix是与产生的单个rotate3d相对应的matrix。 不知道如何轻松地提取rotate3d的值,但它很容易提取单个matrix3d


在第一种情况下( rotate3d(1, 0, 0, 50deg) rotateX(50deg)rotate3d(1, 0, 0, 50deg) ),您有:

x = 1y = 0z = 0α = 50deg

所以在这种情况下matrix的第一行是1 0 0 0

第二个是0 cos(50deg) -sin(50deg) 0

第三个0 sin(50deg) cos(50deg) 0

而第四个显然是0 0 0 1


在第二种情况下,你有x = 0y = 1z = 0α = 20deg

第一行: cos(20deg) 0 sin(20deg) 0

第二行: 0 1 0 0

第三行: -sin(20) 0 cos(20deg) 0

第四: 0 0 0 1


在第三种情况下,你有x = 0y = 0z = 1α = 15deg

第一行: cos(15deg) -sin(15deg) 0 0

第二行sin(15deg) cos(15deg) 0 0

第三和第四行分别是0 0 1 00 0 0 1


注意 :您可能已经注意到rotateY变换的sin值的符号与另外两个变换的不同。 这不是一个计算错误。 原因是,对于屏幕,你有Y轴指向下,而不是。


所以这些就是三个4x4matrix,你需要相乘才能得到4x4matrix的单rotate3d变换。 正如我所说的,我不知道得到4个值是多么容易,但是4x4matrix中的16个元素恰好是链式变换的matrixmatrix3d的16个参数。


编辑

实际上,事实certificate这非常简单…您可以计算rotate3dmatrix的matrix的轨迹(对angular线元素的总和)。

4 - 2*2*(1 - cos(α))/2 = 4 - 2*(1 - cos(α)) = 2 + 2*cos(α)

然后,计算三个4x4matrix乘积的轨迹,将结果与2 + 2*cos(α)等同,即可提取出α 。 然后你计算xyz

在这种特殊情况下,如果我计算正确,由三个4x4matrix的乘积产生的matrix的轨迹将是:

 T = cos(20deg)*cos(15deg) + cos(50deg)*cos(15deg) - sin(50deg)*sin(20deg)*cos(15deg) + cos(50deg)*cos(20deg) + 1 

所以cos(α) = (T - 2)/2 = T/2 - 1 ,这意味着α = acos(T/2 - 1)

句法:

 rotate3d(x, y, z, a) 

价值观:

  • x<number>描述表示旋转轴向量的x坐标。
  • y是描述表示旋转轴向量的y坐标的<number>
  • z描述表示旋转轴向量的z坐标的<number>
  • a是代表旋转angular度的<angle> 。 正angular度表示顺时针旋转,负angular度表示逆时针旋转。

像 :

 .will-distort{ transform:rotate3d(10, 10, 10, 45deg); } 

在这里摆弄

可以在这里使用

更多关于它的文档

取决于你想做什么,这个“黑客”可以帮助你。 比方说,你正在做animation,而且你想在转换之后添加转换等等,而你不希望CSS看起来像是在做100多个转换:

这在铬中工作:1.将所需的任何变换应用到元素。 2.下次要添加变换时,将其添加到计算的变换:“window.getComputedStyle(element).transform” – 但要确保将新的变换放在左侧。 3.现在你的变换看起来像是“rotateZ(30deg)ma​​trix3d(……)”。4.下一次你想添加另一个变换,重复这个过程–Chrome总是将变换减less到matrix3d记法。

TL; DR-应用你想要的任何变换,然后得到计算的matrix变换。

这个技巧还可以让你快速(也就是说,不需要自己做任何的math运算)做一个相对于你的参考框架向任何方向旋转一个对象的function。 看下面的例子:

编辑 :我也添加了xyz翻译。 使用这种方法,将物体放置在特定的三维位置并考虑到特定的方向会非常容易。 或者…想象一个立方体,它会根据它如何着地而弹跳并改变它的旋转轴。

  var boxContainer = document.querySelector('.translator'), cube = document.getElementById('cube'), optionsContainer = document.getElementById('options'); var dims = ['x', 'y', 'z']; var currentTransform; var currentTranslate; var init = function () { optionsContainer.querySelector('.xRotation input') .addEventListener('input', function (event) { if (currentTransform != 'none') { var newTransform = 'rotateX(' + (360 - event.target.value) + 'deg) ' + currentTransform; } else { var newTransform = 'rotateX(' + (360 - event.target.value) + 'deg)'; } cube.style.transform = newTransform; }, false); optionsContainer.querySelector('.yRotation input') .addEventListener('input', function (event) { if (currentTransform != 'none') { var newTransform = 'rotateY(' + (360 - event.target.value) + 'deg) ' + currentTransform; } else { var newTransform = 'rotateY(' + (360 - event.target.value) + 'deg)'; } cube.style.transform = newTransform; }, false); optionsContainer.querySelector('.zRotation input') .addEventListener('input', function (event) { if (currentTransform != 'none') { var newTransform = 'rotateZ(' + (360 - event.target.value) + 'deg) ' + currentTransform; } else { var newTransform = 'rotateZ(' + (360 - event.target.value) + 'deg)'; } cube.style.transform = newTransform; }, false); optionsContainer.querySelector('.xTranslation input') .addEventListener('input', function (event) { if (currentTranslate != 'none') { var newTransform = 'translateX(' + (100 - event.target.value) + 'px) ' + currentTranslate; } else { var newTransform = 'translateX(' + (100 - event.target.value) + 'px)'; } boxContainer.style.transform = newTransform; }, false); optionsContainer.querySelector('.yTranslation input') .addEventListener('input', function (event) { if (currentTranslate != 'none') { var newTransform = 'translateY(' + (100 - event.target.value) + 'px) ' + currentTranslate; } else { var newTransform = 'translateY(' + (100 - event.target.value) + 'px)'; } boxContainer.style.transform = newTransform; }, false); optionsContainer.querySelector('.zTranslation input') .addEventListener('input', function (event) { if (currentTranslate != 'none') { var newTransform = 'translateZ(' + (500 - event.target.value) + 'px) ' + currentTranslate; } else { var newTransform = 'translateZ(' + (500 - event.target.value) + 'px)'; } boxContainer.style.transform = newTransform; }, false); reset(); }; function reset() { currentTransform = window.getComputedStyle(cube).transform; currentTranslate = window.getComputedStyle(boxContainer).transform; optionsContainer.querySelector('.xRotation input').value = 360; optionsContainer.querySelector('.yRotation input').value = 360; optionsContainer.querySelector('.zRotation input').value = 360; optionsContainer.querySelector('.xTranslation input').value = 100; optionsContainer.querySelector('.yTranslation input').value = 100; optionsContainer.querySelector('.zTranslation input').value = 500; } window.addEventListener('DOMContentLoaded', init, false); document.addEventListener('mouseup', reset, false); 
 .translator { height: 200px; position: absolute; width: 200px; transform-style: preserve-3d; } .threeSpace { height: 200px; moz-perspective: 1200px; o-perspective: 1200px; perspective: 200px; position: absolute; transform-origin: 50px 50px 100px; webkit-perspective: 1200px; width: 100px; perspective-origin: 100px 25px; transform-style: preserve-3d; } #pointer{ position:relative; height:2px; width:2px; top:25px; left:100px; background:blue; z-index:9999; } #cube { height: 100%; moz-transform-origin: 90px 110px 0px; moz-transform-style: preserve-3d; o-transform-origin: 90px 110px 0px; o-transform-style: preserve-3d; position: absolute; transform-origin: 90px 110px 0px; transform-style: preserve-3d; webkit-transform-origin: 90px 110px 0px; webkit-transform-style: preserve-3d; width: 100%; } #cube .midPoint{ position:absolute; top:48px; left:48px; height:1px; width:1px; background:green; } #cube figure { border: 2px solid black; color: white; display: block; font-size: 60px; font-weight: bold; height: 96px; line-height: 96px; position: absolute; text-align: center; width: 96px; /* transform-style: preserve-3d; */ } #cube .front { background: hsl(0, 100%, 50%); } #cube .back { background: hsl(60, 100%, 50%); } #cube .right { background: hsl(120, 100%, 50%); } #cube .left { background: hsl(180, 100%, 50%); } #cube .top { background: hsl(240, 100%, 50%); } #cube .bottom { background: hsl(300, 100%, 50%); } #cube .front { moz-transform: translateZ(50px); o-transform: translateZ(50px); transform: translateZ(50px); webkit-transform: translateZ(50px); } #cube .back { moz-transform: rotateX(-180deg) translateZ(50px); o-transform: rotateX(-180deg) translateZ(50px); transform: rotateX(-180deg) translateZ(50px); webkit-transform: rotateX(-180deg) translateZ(50px); } #cube .right { moz-transform: rotateY(90deg) translateZ(50px); o-transform: rotateY(90deg) translateZ(50px); transform: rotateY(90deg) translateZ(50px); webkit-transform: rotateY(90deg) translateZ(50px); } #cube .left { moz-transform: rotateY(-90deg) translateZ(50px); o-transform: rotateY(-90deg) translateZ(50px); transform: rotateY(-90deg) translateZ(50px); webkit-transform: rotateY(-90deg) translateZ(50px); } #cube .top { moz-transform: rotateX(90deg) translateZ(50px); o-transform: rotateX(90deg) translateZ(50px); transform: rotateX(90deg) translateZ(50px); webkit-transform: rotateX(90deg) translateZ(50px); } #cube .bottom { moz-transform: rotateX(-90deg) translateZ(50px); o-transform: rotateX(-90deg) translateZ(50px); transform: rotateX(-90deg) translateZ(50px); webkit-transform: rotateX(-90deg) translateZ(50px); } #options{ position:absolute; width:80%; top:40%; } #options input { width: 60%; } 
 <body> <div class="threeSpace"> <div id="pointer"></div> <div class="translator"> <div id="cube"> <figure class="front"><div class='midPoint'></div></figure> <figure class="back"></figure> <figure class="right"></figure> <figure class="left"></figure> <figure class="top"></figure> <figure class="bottom"></figure> </div> </div> </div> <section id="options"> <p class="xRotation"> <label>xRotation</label> <input type="range" min="0" max="720" value="360" data-units="deg" /> </p> <p class="yRotation"> <label>yRotation</label> <input type="range" min="0" max="720" value="360" data-units="deg" /> </p> <p class="zRotation"> <label>zRotation</label> <input type="range" min="0" max="720" value="360" data-units="deg" /> </p> <p class="xTranslation"> <label>xTranslation</label> <input type="range" min="0" max="200" value="100" data-units="deg" /> </p> <p class="yTranslation"> <label>yTranslation</label> <input type="range" min="0" max="200" value="100" data-units="deg" /> </p> <p class="zTranslation"> <label>zTranslation</label> <input type="range" min="0" max="1000" value="500" data-units="deg" /> </p> </section> </body> 

确切的数值是rotate3d(133,32,58,58deg)

看小提琴 (对于Chrome和Safari,使用-webkit转换)