How to combine transforms in CSS?


Tags: javascript,css,css3,transform,css-animations

Problem :

I have a CSS animation that uses transforms to move around relative to its current position.

CSS

fish {
    animation: fishanimation 4s ease-in-out infinite alternate;
}

@keyframes fishanimation {
  0% {
    transform: translateY(20px);
  }

  100% {
    transform: translateY(80px);
  }
}

Now I want to adjust the scale and rotation dynamically using javascript, but this gets overwritten by the running css animation. The transforms are not combined :(

Javascript

this.div.style.transform = "scale(0.4) rotate(45deg)";

Is it possible to have the scale and rotation apply to the already existing transformation? Something like:

element.transform = element.transform + "scale(0.4) rotate(34deg)";

EDIT:

This is not a duplicate of the question: how to combine css transforms. The point of this question is that an element may already have a transform that I don't want to overwrite. I want to add to it, without actually knowing what the current transform state is.



Solution :

As commented, I recommend you use a library called Velocity JS for this. Click for Velocity JS website.

If a library like suggested is not an option, then read on!

If you were looking to do multiple transforms like that in one on top of your previous transforms, then you'd need to use the matrix value for the transform. Things get a little complicated with the matrix. The parameters for the matrix are in this order: -

matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY());

Let's use the example of starting off with the initial fish animation you mentioned: -

fish {
    animation: fishanimation 4s ease-in-out infinite alternate;
}

@keyframes fishanimation {
  0% {
    transform: matrix(1, 0, 0, 1, 0, 20);
  }

  100% {
    transform: matrix(1, 0, 0, 1, 0, 80);
  }
}

To dynamically change this in JavaScript will require some unpleasant string manipulation and getting the transform property of the element (which is more awkward than you think). Here's an example of how you might do it.

function getTransformValues(obj) {
    var transform = {
        scaleX: 1,
        skewX: 0,
        skewY: 0,
        scaleY: 1,
        translateX: 0,
        translateY: 0
    };

    var matrix = obj.css("-webkit-transform") ||
                 obj.css("-moz-transform")    ||
                 obj.css("-ms-transform")     ||
                 obj.css("-o-transform")      ||
                 obj.css("transform");

    if (matrix && matrix !== 'none') {
        var values = matrix.split('(')[1].split(')')[0].split(',');
        transform.scaleX = parseInt(values[0], 10);
        transform.skewX = parseInt(values[1], 10);
        transform.skewY = parseInt(values[2], 10);
        transform.scaleY = parseInt(values[3], 10);
        transform.translateX = parseInt(values[4], 10);
        transform.translateY = parseInt(values[5], 10);
    }

    return transform;
}

var values = getTransformValues($('#test'));
console.log(values);
// Object {scaleX: 1, skewX: 0, skewY: 0, scaleY: 2, translateX: 50, translateY: 40}

Now you've got those values you can start creating a new matrix by only changing the one you want, for example: -

var old = {
    scaleX: 1,
    skewX: 0,
    skewY: 0,
    scaleY: 2,
    translateX: 50,
    translateY: 40
};

$('#test').css('transform', 'matrix(' + old.scaleX + ', ' + old.skewY + ', ' + old.skewX + ', ' + old.scaleY + ', ' + old.translateX + ', ' + old.translateY + ')');

Bare with me... If you want to start manipulating the rotation angle things get even more complicated. To avoid bogging this answer so much, this part of the question has a solution at the following link: Get element -moz-transform:rotate value in jQuery

Hopefully you can see why adopting libraries such as Velocity JS, at least at the time of writing, is the best way to go for quick, easy, clean and smooth cross-browser animation.


    CSS Howto..

    How do you align two items in the center of a border?

    How to recreate this image using css

    How to use webpack and css-loader to load only specific css class?

    How to look up and combine data in different parts of an XML source document using XSLT to create SVG visualization of a finite element mesh

    How to generate CSS markup for non-designers

    How can I use ellipses in a fluid width table without making each column the same size?

    How to make these scale right in CSS (block with horizontal and vertical attachés)

    All CSS menu when hover show submenu

    How to change the font-size of the part of textarea text in HTML,CSS?

    how to solve css check box checking issue

    I can't get all the div's to show up with the same #id

    How do I invoke a CSS3 transition using JavaScript?

    How to fix html border corner slope with css?

    How can you hide the title tag using CSS?

    How to change the width of css tab according to length of alphabet?

    How to apply css style to custom attributes

    CSS - How to centre a link button

    How to create CSS gradient from the centre? [closed]

    how to add parent class in css file?

    How to align multiple images in “li” on center

    How to change background color for only one bootstrap popover

    How to achieve layout goal - Two Column

    What is the ::content pseudo-element and how does it work?

    How to set hover of the block which contains icon with HTML or CSS?

    How to add css style in php email?

    Fixing GoogleMonkeyR column width issue. How to change a script's CSS?

    How to make a colorful gradient glow around your input-box?

    How to switch css table-cell from left to right?

    @font-face font working fine locally but when pushed to server it just shows up as a default HTML font

    How do I keep sibling divs from pushing each other down when I use “margin-top: 4px” on one of them?