animate scale and rotate separately with css3 and jquery

15,810

Solution 1

You really have 2 options, but I think nested div's will most likely be your best option. You can use jQuery to control the timing of certain animations, but it will require a decent amount of coding to get it right.

Per Andrea Ligios comment, you should set a delay on the two class so that the transition starts after 0.5s

HTML

<div id="rotate" class="half rotate">
    <div id="scale" class="two grow">Rotate</div>
</div>

CSS

.half {
    transition: all 0.5s ease-in-out;
    -webkit-transition: all 0.5s ease-in-out;
}

.two {
    transition: all 2s ease-in-out 0.5s;
    -webkit-transition: all 2s ease-in-out 0.5s;
}

#rotate, #scale {
    height: 150px;
    width: 100px;
    text-align: center;
    margin: 0 auto;    
}

#scale {
    border: 1px blue solid; /*for visualization*/
}

.rotate:hover {
    transform: rotateZ(180deg);
    -webkit-transform: rotateZ(180deg);
}

.grow:hover {
    transform: scale(2.0);
    -webkit-transform: scale(2.0);
}

Here is a CSS demo fiddle : http://jsfiddle.net/adjit/w4kgP/5/

Your jQuery option involves setting timeouts, the only thing is the reverse animation doesn't go exactly in the reverse order. It will shrink and un-rotate with an interval of .5s. You can ofcourse also set a timeout for mouseout

jQuery Option

$('#rotate-scale').hover(function(){
    clearTimeout(timeout);

    $this = $(this);
    $this.addClass('rotate');
    timeout = setTimeout(function(){
        $this.css("-webkit-transition", "all 2s ease-in-out");
        $this.addClass('grow');
    }, 500);
}, function(){
    clearTimeout(timeout);
    $(this).css("-webkit-transition", "all 0.5s ease-in-out");
    $(this).removeClass('rotate');
    $(this).removeClass('grow');
});

Here is a jQuery demo fiddle : http://jsfiddle.net/adjit/tR7EY/1/

Solution 2

Short answer: Use GSAP.

Long answer: CSS3 transform properties cannot really be individually animated, unless you happen to be good with transformation matrixes and are ready to write a lot of supporting code for a better animation system. Not only would you have to deal with converting the transform properties into transforms matrices, but you'd also need some sort of system to dynamically mix different matrix states to be actually able to decouple timings. This requires a lot of advanced mathematics and development time, which would most likely be better spent elsewhere.

EDIT: Further reading: How to read individual transform values in js

EDIT2: Depending on what exactly you're trying to do, you might be able to separate the animations by splitting them across several nested divs. Eg. The outermost div handles the scale animation and within it is a div with a rotation animation. CSSdeck example

Share:
15,810
Dr.YSG
Author by

Dr.YSG

PhD (CS) working in a broad area of technologies: Big Data GPU computing &amp; Non-Von-Neumann programming Cloud Computing Massive distributed gaming (scientific simulations) Computer Vision, Robotics Augmented Reality Mobile GIS 2D/3D Simulation &amp; Virtual Reality serious games 3D Graphics HTML5 for offline mobile apps Data &amp; Info Visualization MultiMedia Real-time collaboration (mobile tech) User Interfaces (video and NUI) as well as Human Centered Design NodeJS,Express, OGMA, Neo4j Graph Database React, Redux, Redux-Thunk, Redux-Form, Electron, the Redux Ecosystem

Updated on June 15, 2022

Comments

  • Dr.YSG
    Dr.YSG almost 2 years

    UPDATED and CLARIFIED

    I need to execute some jquery that does an immediate rotate (using css3 transform) on an icon. And then once the icon is rotated I want to animate and scale to 200% of the size. However, since scale and rotate are both one CSS3 property (transform) I am seeing that both of the transitions are occurring as an animation for 0.5s. (in the JQUERY code I also update the location (top, left), but since that is not in the transition: tag, it happens immediately as required).

    What I want is the rotate to happen immediately, and the scale to happen over 2s. Any ideas?

    CSS:

    transition: transform 0.5s;
    -webkit-transition: -webkit-transform 0.5s;
    

    JQUERY:

    self.pick = function (cmd) {
        var pt = Tools.cmdToPoint(cmd);
        $(self.bbox).css("position", "fixed");
        $(self.bbox).css("top", pt.y - 32);
        $(self.bbox).css("left", pt.x - 32);
        $(self.bbox).css("opacity", "1");
        var theta = self.angle(cmd);
        $(self.bbox).css("transform", "rotate(" + theta + "deg) scale(2.0)");
        $(self.bbox).css("-webkit-transform", "rotate(" + theta + "deg) scale(2.0)");
    }
    

    What happens is that since transition on the item, both the scale and the rotate occur in an animation over 0.5s.

  • TheNorthWes
    TheNorthWes almost 10 years
    That second edit looks like a possible answer. Think you could tweak this JSFiddle to make it work?
  • Andrea Ligios
    Andrea Ligios almost 10 years
    Why is this still at -1 ? I see effort and a bit of value in the answer, +1.
  • Andrea Ligios
    Andrea Ligios almost 10 years
    +1. But note that he wants to start the second animation after the first is over, while in your CSS example they're starting at the same time. You have to set a delay to the second transform of the length of the first transform: transition: all 2s ease-in-out 0.5s; where 0.5s is the delay before starting the animation.