问题是似乎没有可能从this jsfiddle的起始位置旋转CSS3以显示’4’面(向左旋转一周).
JSFiddle的基本指令:’x’键使用CSS3 rotateX:90deg对多维数据集进行样式设置,对于rotateY为’y’设置样式,为rotateZ设置’z’.单击“重置”按钮返回起始位置.注意*无论旋转(x,y或z),我都不能让立方体向左旋转一个位置.
我正在使用CSS3 rotate3d属性rotateX,rotateY和rotateZ以及影响transform属性的CSS3过渡.
此外,值得一提的是,使用rotateX / Y / Z属性允许立方体在几乎所有其他位置/方向上向上,向左,向右或向下旋转.
问题:
这里有什么问题?这种轮换不可能吗? CSS3旋转有问题,还是我的代码/逻辑中存在问题?
最好的答案将解释CSS3 rotate3d转换如何工作(幕后;数学上).
这里发生的变换是复合变换(因为变换矩阵经历矩阵级联).例如,当您围绕其x轴旋转元素时,其他轴将旋转90度,因此围绕y轴的旋转不再具有它最初所做的右到左效果.相反,它现在表现得像一个倒Z轴.请考虑以下图表:问题的基础是:当你对一个点应用多个变换时,它们的所有变换矩阵都与点本身相乘,按应用顺序从左到右.因此,例如,假设关于x的90度旋转的矩阵是Rx,关于y的90度旋转的矩阵是Ry,关于z的90度旋转的矩阵是Rz.
让我们说我们按两次z和x一次.现在,对于元素中的任何点P,其新位置P’将计算为:
P‘ = Rz . Rz . Rx . P
不幸的是,这个问题是每个后续转换将应用于最后一次计算产生的参考帧.因此,在这种情况下,x轴将在我们围绕它旋转时指向完全相反的方向.
这个问题的解决方案(我将不讨论的数学)是以相反的顺序乘以矩阵.如果这样做,每个连续变换将相对于固定轴,而不是相对于先前变换离开轴的任何状态.因此我们的计算将如下所示:
P‘ = Rx . Rz . Rz . 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‘ = Rnew . Rold . P
这计算相对于世界坐标的新点矢量,而不是相对于变换后的坐标.
作为奖励,这也消除了对全局变量的需求,因为元素的当前变换矩阵是我们需要的唯一信息.
TL; DR
我在下面列出了一个更新的小提琴.按y将立方体向右旋转90度.
这是一个演示:http://jsfiddle.net/guruB/
(和以前一样,使用z,x和y围绕相应的轴旋转)
注意:您可以了解如何计算旋转矩阵here.