尝试#1
使用this article我设法绑定键并将旋转应用于多维数据集.我的第一个问题是CSS变换函数旋转元素轴,所以当,即.我按下,Y和Z轴更换位置.我调整了这种情况下的原始代码,但另一个问题是,由于轴是向量,当我按下2次X和Z回到原位,但向量被反转(左键开始向右旋转立方体,反之亦然)所以现在我必须旋转立方体相反的方向,以获得所需的结果,我不知道如何检测轮轴是倒置的.
JavaScript的
var xAngle = 0,yAngle = 0,zAngle = 0,cube = $("#cube"); $(document).keydown(function(e) { //keyup maybe better? e.preventDefault(); var key = e.which,arrow = {left: 37,up: 38,right: 39,down: 40},x = xAngle/90,y = yAngle/90; switch(key) { case arrow.left: if (x%2 == 0) yAngle -= 90; else zAngle += 90; break; case arrow.up: if (y%2 == 0) xAngle += 90; else zAngle -= 90; break; case arrow.right: if (x%2 == 0) yAngle += 90; else zAngle -=90; break; case arrow.down: if (y%2 == 0) xAngle -= 90; else zAngle += 90; break; } var rotate = "rotateX(" + xAngle + "deg) rotateY(" + yAngle + "deg) rotateZ(" + zAngle + "deg)"; cube.css({"transform":rotate}); });
尝试#2
我使用this article的方法制作了另一个版本,试图通过分解和更新css 3d矩阵来解决同样的问题,但是还有其他问题.反复按箭头随机方向立方体改变观察角度(多于一侧可见).
当我可以从3d矩阵获得旋转值或向量方向,但是没有solutions I found似乎可以工作,这将是巨大的.我猜,因为3D矩阵是通过将来自所有传递的函数(rotateX,rotateY和translateZ)的值相乘得出的,而且那种数学方法可以超出我的头脑.
JavaScript的
var Vector = function(x,y,z) { this.x = x; this.y = y; this.z = z; } WebKitCSSMatrix.prototype.transformVector = function(v) { var xOut = this.m11*v.x + this.m12*v.y + this.m13*v.z; var yOut = this.m21*v.x + this.m22*v.y + this.m23*v.z; var zOut = this.m31*v.x + this.m32*v.y + this.m33*v.z; return new Vector(xOut,yOut,zOut); }; function applyRotation(vector,angle) { var cube = $('#cube'); var matrix = new WebKitCSSMatrix(cube.css('webkitTransform')); var vector = matrix.transformVector(vector); var newMatrix = matrix.rotateAxisAngle(vector.x,vector.y,vector.z,angle); cube.get(0).style.webkitTransform = newMatrix; } // rotate using arrow keys $(document).keyup(function(e) { e.preventDefault(); var key = e.which,v,a; switch(key) { case arrow.left: v = new Vector(0,1,0),a = -90; break; case arrow.right: v = new Vector(0,a = 90; break; case arrow.up: v = new Vector(1,a = 90; break; case arrow.down: v = new Vector(1,a = -90; break; } applyRotation(v,a); });
尝试#3
第三个版本我单独旋转,旋转后改变类,所以我总是只是旋转X和Y在正确的方向,但是当旋转发生时,立方体被分解,我认为上下旋转是错误的(加代码有点blo肿和丑陋).对于不支持preserve-3d属性的浏览器,这种方法的另一方面是跨浏览器兼容性更大.
JavaScript的
$(document).keyup(function(e) { e.preventDefault(); var key = e.which,front = "rotateX(0deg) translateZ(100px)",back = "rotateX(180deg) translateZ(100px)",right = "rotateY(90deg) translateZ(100px)",left = "rotateY(-90deg) translateZ(100px)",top = "rotateX(90deg) translateZ(100px)",bottom = "rotateX(-90deg) translateZ(100px)"; switch(key) { case arrow.left: $(".front").css({"transform":left}); $(".back").css({"transform":right}); $(".left").css({"transform":back}); $(".right").css({"transform":front}); var front = $(".front"); var back = $(".back"); var left = $(".left"); var right = $(".right"); front.removeClass("front").addClass("left"); back.removeClass("back").addClass("right"); right.removeClass("right").addClass("front"); left.removeClass("left").addClass("back"); break; case arrow.up: $(".front").css({"transform":top}); $(".back").css({"transform":bottom}); $(".top").css({"transform":back}); $(".bottom").css({"transform":front}); var front = $(".front"); var back = $(".back"); var top = $(".top"); var bottom = $(".bottom"); front.removeClass("front").addClass("top"); back.removeClass("back").addClass("bottom"); top.removeClass("top").addClass("back"); bottom.removeClass("bottom").addClass("front"); break; case arrow.right: $(".front").css({"transform":right}); $(".back").css({"transform":left}); $(".left").css({"transform":front}); $(".right").css({"transform":back}); var front = $(".front"); var back = $(".back"); var left = $(".left"); var right = $(".right"); front.removeClass("front").addClass("right"); back.removeClass("back").addClass("left"); right.removeClass("right").addClass("back"); left.removeClass("left").addClass("front"); break; case arrow.down: $(".front").css({"transform":bottom}); $(".back").css({"transform":top}); $(".top").css({"transform":front}); $(".bottom").css({"transform":back}); var front = $(".front"); var back = $(".back"); var top = $(".top"); var bottom = $(".bottom"); front.removeClass("front").addClass("bottom"); back.removeClass("back").addClass("top"); top.removeClass("top").addClass("front"); bottom.removeClass("bottom").addClass("back"); break; } });
参考资料:
> Creating basic CSS cube
> MDN docs on transform
property
> W3.org documentation on 3D transforms
> 3dmatrix
documentation
> webkitCSSMatrix
documentation
解决方法
作为一种替代方式,我选择使用浏览器本身来做数学.
我创建一个将被隐藏的div,我将在哪里应用转换来获取新的矩阵.
使用这种方法,javascript变得更短:
function applyTransform (transform) { var cubeCalculator = $('.cubecalculator'); var cube = $('#cube'); var matrix = cubeCalculator.css('webkitTransform'); var composite = transform + ' ' + matrix; cubeCalculator.get(0).style.webkitTransform = composite; matrix = cubeCalculator.css('webkitTransform'); cube.get(0).style.webkitTransform = matrix; } // rotate using arrow keys $(document).keyup(function(e) { e.preventDefault(); var key = e.which,t; switch(key) { case arrow.left: t = 'rotateY(-90deg)'; break; case arrow.right: t = 'rotateY(90deg)'; break; case arrow.up: t = 'rotateX(90deg)'; break; case arrow.down: t = 'rotateX(-90deg)'; break; } applyTransform (t); });
我认为代码是非常自明的:我将转换应用到元素作为新变换和当前变换的组合(您不需要从矩阵中提取值,可以按原样应用)
(我不知道为什么,它没有在codepen工作,已经把它移动到…)
最后我得到了* Firefox的行为!
function applyTransform (transform1,transform2) { var matrix,composite1,composite2; var cubeCalculator = $('.cubecalculator'); var cube = $('#cube'); matrix = cubeCalculator.css('transform'); composite1 = transform1 + ' ' + matrix; composite2 = transform2 + ' ' + matrix; cubeCalculator.get(0).style.transform = composite2; cube.get(0).style.transition = 'none'; cube.get(0).style.transform = composite1; window.setTimeout (function() { cube.get(0).style.transform = composite2; cube.get(0).style.transition = 'transform 1s'; },10 ); } // rotate using arrow keys $(document).keyup(function(e) { e.preventDefault(); var key = e.which,t1,t2; switch(key) { case arrow.left: t1 = 'rotateY(0deg)'; t2 = 'rotateY(-90deg)'; break; case arrow.right: t1 = 'rotateY(0deg)'; t2 = 'rotateY(90deg)'; break; case arrow.up: t1 = 'rotateX(0deg)'; t2 = 'rotateX(90deg)'; break; case arrow.down: t1 = 'rotateX(0deg)'; t2 = 'rotateX(-90deg)'; break; } applyTransform (t1,t2); });
一些更复杂的代码,但使浏览器完全清楚你想要做什么…只要你等到过渡结束,工作正常.