我的示例是一个使用CSS3转换和转换的旋转动画多维数据集。
问题是 this jsfiddle 中的起始位置似乎没有可能的CSS3旋转来显示'4'面(左一个旋转) )。
JSFiddle的基本说明:'x'键为CSS3 rotateX:90deg
设置多维数据集,为旋转设置'y',为rotateZ设置'z'。单击“重置”按钮返回起始位置。 注意* 无论旋转(x,y或z),我都无法将立方体向左旋转一个位置。
我正在使用CSS3 rotate3d属性rotateX
,rotateY
和rotateZ
以及影响transition
属性的CSS3 transform
。
另外,值得一提的是,使用rotateX / Y / Z属性可以让立方体在几乎所有其他位置/方向上向上,向左,向右或向下旋转。
问题:
这是什么问题?这种轮换不可能吗? CSS3旋转有问题,还是我的代码/逻辑中存在问题?
最佳答案将解释CSS3 rotate3d转换的工作原理(幕后;数学上)。
答案 0 :(得分:8)
这里发生的变换是复合变换(因为变换矩阵经历矩阵级联)。例如,当您围绕其x轴旋转元素时,其他轴将旋转90度,因此围绕y轴的旋转不再具有它最初所做的右到左效果。相反,它现在表现得像一个倒Z轴。请考虑以下图表:
问题的基础是:当你对一个点应用多个变换时,它们的所有变换矩阵都与点本身相乘,按照应用的顺序从左到右。因此,例如,假设关于x的90度旋转的矩阵是R x ,关于y的90度旋转的矩阵是R y 和用于90度旋转的矩阵关于z是R z 。
让我们说我们按两次 z 和 x 一次。现在,对于元素中的任何点P,其新位置P '将计算为:
P ' = R z 。 R z 。 R x 。 P
不幸的是,这个问题是每个后续转换都将应用于上次计算产生的参考帧。因此,在这种情况下,x轴将在我们围绕它旋转时指向完全相反的方向。
这个问题的解决方案(我不会参与其中的数学)是将矩阵以相反的顺序相乘。如果这样做,每个连续的变换将相对于固定轴,而不是相对于前一个变换离开轴的任何状态。所以我们的计算将如下所示:
P ' = R x 。 R z 。 R z 。 P
稍微调整WebKitCSSMatrix
之后,我设法提出以下解决方案:
// Make a matrix out of the transformation currently in effect
var oldMatrix = new WebKitCSSMatrix(cube[0].style.webkitTransform);
//Make a matrix that applies the new rotation
var extraRotate = (new WebKitCSSMatrix()).rotate(anglex, angley, anglez);
//Multiply them (with the new one on the left)
var final = extraRotate.multiply(oldMatrix);
//I need to extract the elements of the final matrix into an array.
//They are stored like this: 1st row 1st column in key m11, 2nd row
//1st column in key m12, etc.
var finalstring = [];
for (var i = 1; i < 5; i++) {
for (var j = 1; j < 5; j++) {
finalstring.push(Math.round(final['m' + i + j]));
}
}
//Make a new style rule out of our final matrix and apply it to the element
cube[0].style.webkitTransform = 'matrix3d(' + finalstring.join(',') + ')';
通过预 - 将现有的变换矩阵与所需的额外旋转相乘,设法解决旋转参考系的问题。注意我如何首先计算extraRotate
矩阵,然后将其乘以现有变换,有效地将矩阵与应用程序的逆序相乘:
P ' = R new 。 R old 。 p 的
计算相对于世界坐标的新点矢量,而不是相对于变换后的坐标。
作为奖励,这也消除了对全局变量的需求,因为元素的当前变换矩阵是我们需要的唯一信息。
我在下面添加了一个更新的小提琴。按y
将您的立方体向右旋转90度。
以下是演示:http://jsfiddle.net/guruB/
(如前所述,使用 z , x 和 y 围绕相应的轴旋转)
注意:您可以了解如何计算旋转矩阵here.
答案 1 :(得分:-1)
看看这个demo
它使用此代码向左旋转:
#cube.show-left {
-webkit-transform: translateZ( -100px ) rotateY( 90deg );
-moz-transform: translateZ( -100px ) rotateY( 90deg );
-o-transform: translateZ( -100px ) rotateY( 90deg );
transform: translateZ( -100px ) rotateY( 90deg );