Controlling CSS cube rotation(transform) and extracting values from 3d matrix

后端 未结 2 430
[愿得一人]
[愿得一人] 2020-12-09 20:51

I made CSS cube that I\'m rotating using up/down and left/right keys but I\'m having problems regarding rotation direction.

Attempt #1

DEMO

Using t

相关标签:
2条回答
  • 2020-12-09 21:16

    The problem with the attempt 2 is that rotateAxisAngle does the matrix multiplication in the oposite order of what you want. And, worse still, there is no function in the class to do the multiplication in the order that you want.

    As an alternate way, I have choose to use the browser itself to do the math. I create a div that will be hidden, and where I will apply the transforms to get the new matrix.

    With this approach, the javascript gets even shorter:

    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,
            arrow = {left: 37, up: 38, right: 39, down: 40},
            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);
    
    });
    

    I think that the code is quite self explanatory: I apply the transform to the element as a composite of the new transform and the current transform (you don't need to extract the values from the matrix, can be applied as is)

    demo

    (I don't know why, it didn't work in codepen. have moved it to fiddle ...)

    Finally I got the * Firefox to behave !

    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,
            arrow = {left: 37, up: 38, right: 39, down: 40},
            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);
    
    });
    

    A little bit more complex code, but makes to the browser perfectly clear what you want it to do ... Works fine as long as you wait till the transition is over.

    0 讨论(0)
  • 2020-12-09 21:28

    Demo 2 is almost there. Your problem is that you're using the intermediate animation state of the cube to calculate the new position:

    var matrix = new WebKitCSSMatrix(cube.css('webkitTransform'));
    

    Instead, you should store and update an internal target matrix:

    Additionally, it seems that this snippet of code:

    var vector = matrix.transformVector(vector);
    var newMatrix = matrix.rotateAxisAngle(vector.x, vector.y, vector.z, angle);
    

    Doesn't work as intended. This does what you're looking for:

    var newMatrix = new WebKitCSSMatrix().rotateAxisAngle(...).multiply(matrix)
    

    http://codepen.io/eric-wieser/pen/BoeyD

    0 讨论(0)
提交回复
热议问题