Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
essentialtoils

Relative Scale animation causes elements (<use>) to lose original scale/orientation

Go to solution Solved by GreenSock,

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Having problems scaling an element up and then back down to original value, if there is transform="matrix()" applied. The particular case of <use> element with transformation applied loses the transformation in the process of animation.

 

Is there a way to respect original scale values in order to programmatically create this hover effect without the objects flipping? Thanks in advance!

See the Pen BLoGEG by IGaMbLeRI (@IGaMbLeRI) on CodePen

Link to comment
Share on other sites

As far as I can tell, it's behaving as it should. You've got a matrix applied that has a negative scaleY value. The 1st number is scaleX and 4th number is scaleY: 

matrix(1 0 0 -1.5 2176.0781 647.8819)

So you're starting with a scaleX of 1 and scaleY of -1.5. So scale:"+=0.1" would make scaleX 1.1 and scaleY -1.4. Then, you've got a tween to scale:1 on mouseout, so you're flipping the scaleY to positive there (that's why it appears to flip vertically). 

 

Does that make more sense now? As far as GSAP is concerned (unless I'm missing something), it's doing exactly what you're asking it to do. 

 

If you don't want it to flip, you could just do this in your mouseout:

TweenMax.to(this, 0.5, {scaleX:1, scaleY:-1.5});
  • Like 2
Link to comment
Share on other sites

Thank you for a thorough explanation.

As I have gathered, yes, GSAP is doing exactly what it should. However, how would I go about storing the original transformation (prior to any tweens) to then return to that transformation after scaling up? So instead of returning to "scale":1, I would like to return to "scaleX":originalScaleX and "scaleY":originalScaleY.

Is parsing the attribute property "transform" to get matrix values really the best way?

Link to comment
Share on other sites

Right. So I thought to take a slightly different approach:

var Hoverable = $("#to-be-scaled");
Hoverable.hover(function(){
    this.CurrentAnimation = new TimelineLite();
    this.CurrentAnimation.to(this, 0.5, {"scale":"+=0.1"});
}, function(){
    this.CurrentAnimation.pause().reverse();
});

Does seem to be a bit "sluggish", but seems to work perfectly otherwise. Anyone has better suggestions?

Link to comment
Share on other sites

Said too early... It seems to progressively increase the scale when hovered quickly. What am I missing?

Link to comment
Share on other sites

  • Solution

That's because you keep creating a new tween that's relative on every hover, thus if you roll over/out/over/out quickly, you could end up going much further than 0.1 greater. I think you meant to do something like this: 

$("#to-be-scaled").hover(function(){
    if (this.tween) {
        this.tween.play();
    } else {
        this.tween = TweenLite.to(this, 0.5, {scale:"+=0.1"});
    }
}, function(){
    this.tween.reverse();
});

You mentioned that it was "sluggish", but I bet that's just because of the easing. Remember, the default ease is Power1.easeOut and when you run that backwards, it looks like a Power1.easeIn meaning it'd start out slow. That's not a performance thing at all - it's just literally how you coded it to ease, that's all. If you want it to easeOut in both directions, you could do something a little more advanced:

$("#to-be-scaled").hover(function(){
    if (!this.animation) {
        this.animation = new TimelineMax({paused:true});
        this.animation.to(this, 0.5, {scale:"+=0.1", ease:Linear.easeNone});
    }
    this.animation.tweenTo(this.animation.duration(), {ease:Power2.easeOut});
}, function(){
    this.animation.tweenTo(0, {ease:Power2.easeOut});
});

That's creating a timeline that's paused and uses a linear ease. Then, you just do a tweenTo() with whatever ease you want - that basically creates a tween that's animating the playhead of that timeline itself. 

  • Like 3
Link to comment
Share on other sites

Sorry, I'm still getting to grips with the simplicity and robustness of the engine :) It's just when something is THAT simple to use, I sometimes have a hard time seeing the solution, if you know what I mean. Thank you for your time and effort to help nonetheless!

 

Anyhow, your answer works perfectly. It's totally the easing! Thanks again!

  • Like 1
Link to comment
Share on other sites

Excellent. Love hearing that, @essentialtoils. Happy tweening!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×