Я сделал куб CSS, который я вращаю, используя клавиши вверх/вниз и влево/вправо, но у меня возникают проблемы с направлением вращения.
Попытка # 1
Используя в этой статье Мне удалось привязать ключи и применить поворот к кубу. Моя первая проблема заключалась в том, что функция CSS transform
вращает оси элементов так, когда, т.е. Я нажимаю вверх, место смены оси 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
Я сделал еще одну версию, используя методы из этой статьи, которая пытается решить ту же проблему, разлагая, а затем обновляя 3d-матрицу css, но она имеет другую проблемы. После многократного нажатия стрелок в случайных направлениях куб меняет угол обзора (видится сразу одна сторона).
Было бы здорово, если бы я смог вернуть повернутые значения или векторное направление из 3d-матрицы, но ни один из решений, которые я нашел, похоже, не работает. Я предполагаю, потому что 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,
arrow = {left: 37, up: 38, right: 39, down: 40},
v,
a;
switch(key) {
case arrow.left:
v = new Vector(0,1,0),
a = -90;
break;
case arrow.right:
v = new Vector(0,1,0),
a = 90;
break;
case arrow.up:
v = new Vector(1,0,0),
a = 90;
break;
case arrow.down:
v = new Vector(1,0,0),
a = -90;
break;
}
applyRotation(v, a);
});
Попытка # 3
Третья версия, которую я сделал, поворачивает каждую сторону отдельно и меняет классы после вращения, поэтому я всегда поворачиваю X и Y в правильном направлении, но когда происходит поворот, куб разлагается, и я думаю, что вращение вверх и вниз неверно (плюс код - раздутый и уродливый). Только плюсовая сторона этого подхода - большая совместимость между браузерами для браузеров, которые не поддерживают свойство preserve-3d
.
JavaScript
$(document).keyup(function(e) {
e.preventDefault();
var key = e.which,
arrow = {left: 37, up: 38, right: 39, down: 40},
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;
}
});
СПРАВОЧНЫЙ МАТЕРИАЛ: