Jump to content
GreenSock

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

'Rotation' value from Draggable overwritten by timeline

Recommended Posts

Greetings,

 

I have a question related to Draggable and my main timeline.  To put this in some context, I create e-learning courses where the user has to drag a knob to select their answer (cooler than radio buttons, right?). No matter what the user answers, my main timeline will advance and always point the knob to the correct answer.  This works fine for question #1.

 

After question #1, the main timeline will move the knob back to a rotation of 0, and show question #2. However, when the user answers question #2, the knob will first reset back to rotation 0 and then tween to the correct rotation.  It makes the knob animation twitch and look bad.  I instead want it to tween from the point where the user left the knob.

 

Hopefully the Codepen makes this more clear.  Check the JS box for a couple comments starting on line 30.

 

I have tried a huge number of workarounds, including clearProps, overwrites of all kinds, Draggable update(), fromTo's, and combinations of all of the above.  Nothing has been effective except "overwrite: all", but that causes its own share of problems.  I feel like I'm on the right track but can't wrap my head around how to make the Draggable's tweens play nicely with my timeline.

 

Thank you for reading and please let me know if I can provide any more info.

See the Pen yeYeWg by gem0303 (@gem0303) on CodePen

Link to comment
Share on other sites

The rotation value is different than what was recorded, so the easiest way to handle this is to not use it in a timeline.

 

This is reminds me of some educational games I used to make. Here's a quickie version of how I used to setup questions.

 

See the Pen e99870e37890f49455854a2f6ce1ecbf by osublake (@osublake) on CodePen

  • Like 2
Link to comment
Share on other sites

The rotation value is different than what was recorded, so the easiest way to handle this is to not use it in a timeline.

 

This is reminds me of some educational games I used to make. Here's a quickie version of how I used to setup questions.

 

See the Pen e99870e37890f49455854a2f6ce1ecbf by osublake (@osublake) on CodePen

 

Thank you for the extremely detailed Codepen, I am definitely bookmarking that for later reference!  I figured the easiest answer would be to move the rotation tweens out of the main/master timeline, and have the knob working perfectly now that I've done that.

 

It would be nice to know more about how the timeline "records" values and possible ways to reset or override those values.  Reason being, we allow users to jump backward and forward between different parts of the training, and therefore need to reset a bunch of things every time they jump, including anything we've manually tweened.  In this particular case, resetting the knob to rotation: 0 is simple, but more complex interactive sections take a gob of extra tweens.

 

Do you know of any write-ups that discuss how timelines record values in more detail? The Greensock documentation is excellent but I think I'm looking for information that's a bit more technical (and possibly going to be way over my head). :)

Link to comment
Share on other sites

In the TweenMax Docs, as well as the TimelineMax docs.

 

For example the special property overwrite .. auto is default

  • "auto" (2) - when the tween renders for the first time, it will analyze tweens of the same target that are currently active/running and only overwrite individual tweening properties that overlap/conflict. Tweens that haven't begun yet are ignored. For example, if another active tween is found that is tweening 3 properties, only 1 of which it shares in common with the new tween, the other 2 properties will be left alone. Only the conflicting property gets overwritten/killed. This is the default mode and typically the most intuitive for developers.
overwrite : String (or integer) - Controls how (and if) other tweens of the same target are overwritten. There are several modes to choose from, but "auto" is the default (although you can change the default mode using theTweenLite.defaultOverwrite property):
  • "none" (0) (or false) - no overwriting will occur.
  • "all" (1) (or true) - immediately overwrites all existing tweens of the same target even if they haven't started yet or don't have conflicting properties.
  • "auto" (2) - when the tween renders for the first time, it will analyze tweens of the same target that are currently active/running and only overwrite individual tweening properties that overlap/conflict. Tweens that haven't begun yet are ignored. For example, if another active tween is found that is tweening 3 properties, only 1 of which it shares in common with the new tween, the other 2 properties will be left alone. Only the conflicting property gets overwritten/killed. This is the default mode and typically the most intuitive for developers.
  • "concurrent" (3) - when the tween renders for the first time, it kills only the active (in-progress) tweens of the same target regardless of whether or not they contain conflicting properties. Like a mix of "all" and "auto". Good for situations where you only want one tween controling the target at a time.
  • "allOnStart" (4) - Identical to "all" but waits to run the overwrite logic until the tween begins (after any delay). Kills tweens of the same target even if they don't contain conflicting properties or haven't started yet.
  • "preexisting" (5) - when the tween renders for the first time, it kills only the tweens of the same target that existed BEFORE this tween was created regardless of their scheduled start times. So, for example, if you create a tween with a delay of 10 and then a tween with a delay of 1 and then a tween with a delay of 2 (all of the same target), the 2nd tween would overwrite the first but not the second even though scheduling might seem to dictate otherwise. "preexisting" only cares about the order in which the instances were actually created. This can be useful when the order in which your code runs plays a critical role.

But Jack and Carl would be the best to discuss how timeline record values in more depth! :)

Link to comment
Share on other sites

@Jonathan

 

Thank you for posting the overwrite info.  I tried all of these, both in the master timeline and in a couple cases as standalone tweens. Only overwrite 'all' worked, but, as expected, this broke the course when I reset the section to play through it again (I described why this functionality is needed in my response to OSUblake's post).

 

I think what I'm struggling with is that Draggable essentially has its own set of animations/tweens that occur when the user clicks the knob and moves it around. If there was some way of adding an overwrite to those 'invisible' tweens, perhaps that would solve the issue. What seems to happen is that as soon as the user answers question 2, the master timeline ignores where the user has just positioned the knob and resets it to the last place it 'should be', which is rotation 0 (as set on JS line 25 of the Codepen demo).

 

I tried grabbing the final rotation of the knob after question 2 and immediately using a .set in the master timeline (and tested various overwrite settings) to override the rotation 0, but it still twitched and looked funny.  Also tried a fromTo with similar code but that didn't work out either.

Link to comment
Share on other sites

A tween only calculates the values to use once for performance reasons. Having it check and re-record stuff every time it played would slow your animations down.

 

So if you create a tween to move something from 0-100 and then immediately change it's start position to 25 using some other means, the original tween is not aware of this change nor will it check because it already recorded it. Do you see what's going to happen when you play the tween now? It's going to go from it's current position of 25, immediately to 0 because that is what was recorded at it's starting position.

 

Link to comment
Share on other sites

Hi gmullinix :)

 

if you just want to use timeline , you can do like this :

//.to("#knob",1,{rotation: 42})

.add(function(){ TweenLite.to("#knob",1,{rotation: 42}) })
Link to comment
Share on other sites

You are trying to add logic to a timeline, which is not what they are designed to do. Timelines are for playing animations in a sequence. Not for playing your animations out like some Choose Your Own Adventure Book. Yes, it's possible to do it that way and I know it can seem like a good idea, but it's probably not worth it as it's very easy to run into problems like the one you are experiencing.

 

And you're not alone when it comes to creating some master timeline like that. Trust me, EVERYBODY tries that. But don't worry, that demo I made is very flexible, allowing you to do everything you described. Here's another version where you can skip to any question you want. It also plays a simple animation on the current button to show how you can go back and play some animation.

 

See the Pen MKKJXL by osublake (@osublake) on CodePen

  • Like 2
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.
×