如何在速记rotate3d()中组合rotateX(50deg) rotateY(20deg) rotateZ(15deg)
发布于 2013-03-05 02:51:06
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, α),你有一个矩阵

哪里

现在,您将获得3个rotate3d转换中每个转换的矩阵,并将它们相乘。并且得到的矩阵是对应于得到的单个rotate3d的矩阵。不知道如何轻松地从中提取rotate3d的值,但对于单个matrix3d提取这些值肯定很容易。
在第一种情况下(rotateX(50deg)或rotate3d(1, 0, 0, 50deg)),您需要:
x = 1、y = 0、z = 0、α = 50deg
所以在本例中,矩阵的第一行是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矩阵,您需要将它们相乘,才能得到得到的单个rotate3d变换的4x4矩阵。正如我已经说过的,我不确定提取这4个值有多容易,但是4x4矩阵中的16个元素正是链式转换的matrix3d等效项的16个参数。
编辑
实际上,事实证明这很容易……您可以计算rotate3d矩阵的矩阵的迹(对角线元素的和)。
4 - 2*2*(1 - cos(α))/2 = 4 - 2*(1 - cos(α)) = 2 + 2*cos(α)
然后计算三个4x4矩阵乘积的迹,将结果等同于提取α的2 + 2*cos(α)。然后计算x,y,z。
在这种特殊情况下,如果我计算正确,由三个4x4矩阵的乘积得到的矩阵的迹将是:
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)。
发布于 2013-03-05 01:39:17
语法:
rotate3d(x, y, z, a)值:
x是描述表示轴的向量的x坐标的<number>,是描述表示轴的向量的y坐标的<number>,rotation.a是描述表示轴的向量的z坐标的<number>,<number>是表示旋转角度的<number>。正角度表示顺时针旋转,负角度表示逆时针旋转。如下所示:
.will-distort{
transform:rotate3d(10, 10, 10, 45deg);
}Fiddled here
Caniuse it here
More docs about it
发布于 2015-03-07 12:27:51
这取决于你正在尝试做什么,这个“hack”可以帮助你。假设你正在做动画,你想在转换之后添加转换,等等,你不想让CSS看起来像是在做100个转换:
这在chrome中有效: 1.对元素应用任何你想要的变换。2.下次要添加转换时,将其添加到计算出的转换中:"window.getComputedStyle(element).transform“-但请确保将新转换放在左侧。3.现在你的转换将看起来像"rotateZ(30deg) matrix3d (……). 4.下次你想添加另一个转换时,重复这个过程- Chrome总是将转换减少为matrix3d符号。
DR-应用你想要的任何变换,然后得到计算出的matrix3d变换。
这个技巧还可以让你快速地(也就是说,不需要自己做任何数学运算)创建一个功能,使对象相对于你的参考系在任何方向上旋转。请看下面的示例:
编辑:我也添加了xyz翻译。使用此功能,可以很容易地将对象放置在特定的3d位置,并记住特定的方向。Or...imagine一个立方体,反弹并改变它的旋转轴与每次反弹取决于它如何落地!
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>
https://stackoverflow.com/questions/15207351
复制相似问题