Получить значение поворота 3D CSS из matrix3d() с помощью JavaScript

У меня есть 3D-элемент, преобразованный примерно так:

.foo {
  transform: rotateX(-30deg) rotateY(35deg);
}

Теперь я хочу получить эти значения через javascript. Получить 3D-матрицу легко:

var matrix = $('.foo').css('transform');
// return:
// matrix3d(0.819152, -0.286788, -0.496732, 0, 0, 0.866025, -0.5, 0, 0.573576, 0.409576, 0.709406, 0, 0, 0, 0, 1)

Но можно ли с помощью этой матрицы вычислить CSS, подобные значениям -30 и 35? Я только что нашел способы сделать это для 2D-преобразований .


person Philipp Kühn    schedule 24.12.2015    source источник
comment
Несмотря на то, что вопрос прямолинейный, ответ кажется очень широким и сложным для объема одного ответа. Вы можете найти эти ссылки полезными: 1 - W3C Spec, 2 — Gist by jsfiiii, 3 - Математика трехмерного вращения.   -  person Harry    schedule 25.12.2015


Ответы (1)


Хорошо понял!

var _getTransform = function($element) {

    var matrix = $element.css('transform'),
        rotateX = 0,
        rotateY = 0,
        rotateZ = 0;

    if (matrix !== 'none') {

        // do some magic
        var values = matrix.split('(')[1].split(')')[0].split(','),
            pi = Math.PI,
            sinB = parseFloat(values[8]),
            b = Math.round(Math.asin(sinB) * 180 / pi),
            cosB = Math.cos(b * pi / 180),
            matrixVal10 = parseFloat(values[9]),
            a = Math.round(Math.asin(-matrixVal10 / cosB) * 180 / pi),
            matrixVal1 = parseFloat(values[0]),
            c = Math.round(Math.acos(matrixVal1 / cosB) * 180 / pi);

        rotateX = a;
        rotateY = b;
        rotateZ = c;

    }

    return {
        rotateX: rotateX,
        rotateY: rotateY,
        rotateZ: rotateZ
    };

}
person Philipp Kühn    schedule 28.12.2015
comment
Эй, спасибо за функцию. Однако у меня есть вопрос: возвращаемые значения, очевидно, находятся в диапазоне от 0 до 90 градусов. Как мы можем получить значение от 0 до 360? - person Andrea Silvestri; 28.10.2016
comment
от 0 до 360: c = Math.round(Math.atan2(values[1], values[0]) * 180 / pi); if (c < 0) { c = 360 + c; } - person devdev_dev; 22.12.2019