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 = 1
, y = 0
, z = 0
, α = 50deg
所以在这种情况下matrix的第一行是1 0 0 0
。
第二个是0 cos(50deg) -sin(50deg) 0
。
第三个0 sin(50deg) cos(50deg) 0
。
而第四个显然是0 0 0 1
。
在第二种情况下,你有x = 0
, y = 1
, z = 0
, α = 20deg
。
第一行: cos(20deg) 0 sin(20deg) 0
。
第二行: 0 1 0 0
。
第三行: -sin(20) 0 cos(20deg) 0
。
第四: 0 0 0 1
在第三种情况下,你有x = 0
, y = 0
, z = 1
, α = 15deg
。
第一行: cos(15deg) -sin(15deg) 0 0
。
第二行sin(15deg) cos(15deg) 0 0
。
第三和第四行分别是0 0 1 0
和0 0 0 1
。
注意 :您可能已经注意到rotateY变换的sin值的符号与另外两个变换的不同。 这不是一个计算错误。 原因是,对于屏幕,你有Y轴指向下,而不是。
所以这些就是三个4x4
matrix,你需要相乘才能得到4x4
matrix的单rotate3d
变换。 正如我所说的,我不知道得到4个值是多么容易,但是4x4matrix中的16个元素恰好是链式变换的matrixmatrix3d
的16个参数。
编辑 :
实际上,事实certificate这非常简单…您可以计算rotate3d
matrix的matrix的轨迹(对angular线元素的总和)。
4 - 2*2*(1 - cos(α))/2 = 4 - 2*(1 - cos(α)) = 2 + 2*cos(α)
然后,计算三个4x4
matrix乘积的轨迹,将结果与2 + 2*cos(α)
等同,即可提取出α
。 然后你计算x
, y
, z
。
在这种特殊情况下,如果我计算正确,由三个4x4
matrix的乘积产生的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)matrix3d(……)”。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转换)