Jump to content
GreenSock

da2020

achieving predictable speed of bezier tween when easing is used

Recommended Posts

My app uses a series of bezier tweens that, together, form one motion path for an animated object -- these tweens are back to back within a timeline, and the end point of one tween is the starting point for the next. Being able to maintain constant speed across the path is important. When all the bezier tweens are linear (no easing), constant speed can be achieved by calculating the length of each bezier and then setting the duration of each tween to get the same desired speed across all the tweens.

My current challenge is how to maintain that constant speed at the boundary of a bezier tween that uses easing... For example, if the last tween in the path uses an ease-out for smooth deceleration to a stop at the end of the path, the speed at the beginning of that final tween needs to match the speed of the preceeding tween.  Simply setting the duration of this final tween based on its length no longer works because that duration includes the slower ease-out portion of the tween, which, of course, will drive up speed at the start of that tween to some indeterminate value (indeterminate to my brain, that is) -- so the speed will suddenly jump from that of the preceeding tweens to some higher speed when entering the final tween.

 

I realize that there is some duration value that would result in the desired  initial starting speed for a given easing function and bezier length, but determining that value would seem to require quite a bit of easing-specific math magic.

 

Or, if there were a way to set a max speed limit on the tween without breaking the easing effect, that could be a possible solution (I think),  but how?... Could the bezier's onUpdate handler be used to force the "progress" setting back to some max increment to achieve this speed limit, without impacting the proper operation of the easing effect?

 

There is also the option of tweening the time/progress of the timeline that contains the series of bezier tweens, rather than the approach above, with an ease-out used on that top level tween -- that effectively applies easing to the entire path, but does not seem practical because if the path was long and the constant speed was desired across 95% of that path -- the easing would tend to kick in much earlier than desired.  The typical use case I have in mind is one that has several bezier tweens in a row, all running at a constant speed, with deceleration only occuring in a relatively short distance, typically within the span of the last tween --- plus, the problem remains of how to set the speed for the first 95% of the path...

 

 

Ideas/suggestions welcome.

 

 

- Doug

Link to comment
Share on other sites

Yeah, this is a bit tricky, but being that you understand the process of tweening the time/progress, think of tweening timeScale. 

 

Since a timeline normally plays with a timeScale(1) when you easeOut the timeScale() to 0 you don't have to worry so much about abrupt speed changes since timeScale() will be 1 immediately before the tween starts and that will be the start value used in the tween.

 

Take a look at this demo.

http://codepen.io/GreenSock/pen/kdlbC

 

Imagine bezTimeline was your timeline that had a dozen or so separate Bezier tweens that you glued together with constant speed.

 

Right now it holds a single Linear ease-d Bezier tween.

1 second before the bezTimeline ends I use a callback to ease the timeScale down to 0.

 

The tricky part is finding the right duration for the timeScale tween. 

 

You'll see though that the easeOut only happens at the very end and it is quite smooth.

 

I'm guessing there is still a solution I'm overlooking.

Link to comment
Share on other sites

Carl,

 

That's a very cool approach... Not sure it covers all the bases I'm looking at, but could probably get me close, at least for the the path-ending deceleration scenario.  Seems like the beauty of tweening timescale is that it avoids the concern about matching speeds, because it simply slows down from whatever speed exists at the time its invoked...  

When you say finding the right duration for the timescale tween is still "tricky", at first I couldn't see the problem... I was thinking that in order to get the last bezier to match initial speed with the preceding bezier, it would just be a matter of still using my current constant speed approach of plugging in a duration that yields the speed desired, given the length of the bezier (I think that would still hold up using this scheme)... but then I realized you were probably referring to the need to pick a number for the timescale tween that hits the sweetspot....meaning it reaches timescale of 0 just when the object is reaching its final point of the bezier... if the timescale tween is too long, I guess the object would stop abruptly/prematurely when the final bezier point was reached (?), and if its too short, the object would come to a smooth stop but short of the final destination.... am I thinking about that the right way?

 

Also need to cover the opposite end of the path -- ie, a means to smoothly speed up from the path's starting point, and transition with a constant speed from bezier 1 to bezier 2...  I'm looking at your approach and wondering if it would work in that way too --- seems like it might (?)

 

It will be interesting to see if Jack has any other ideas, but your suggestion of using a callback to a timescale tween has a lot of merit and gives me a new option I had not thought of..  It makes me wonder whether, perhaps as general structural approach of my motion path, I'd be better off wrapping each bezier's timeline in such a timescale tween, and then putting these timescale tweens back to back for main path's outer timeline, such that if ANY bezier in the series needed easing, the easing could be done to the timescale instead of the bezier, to preserve speed matching at the boundaries.... if that makes any sense...  I'm finding that it's fairly easy for my mind to blow when thinking about how to best use timescaling...   

 

Many thanks for this tip!

 

- Doug

Link to comment
Share on other sites

Yes, you are exactly right about the "tricky" part.

As you decrease the timeScale() you are also increasing the duration(), so yes if you use the wrong duration for the tween that is decreasing the timeScale() the animation will not complete or it will stop abruptly at the end.

 

Mess with the duration OR the ease of timeScale tween in the demo and you'll see.

 

----

 

And yes, my demo illustrates the concept of tweening the timeScale() but its not great it you want to reverse the timeline OR add the easing in the beginning too. For that I would build another timeline that first tweens the timeScale() from to 0 to 1 and then at the end from 1 to 0. Totally possible but the "tricky" timing would come into play here too.

 

 

-----

 

Fortunately a MUCH better solution hit me. 

 

Just to beat Jack to the punch I'm going to say "SlowMo Ease". *redacted*

 

Demo to follow shortly

 

-c

Link to comment
Share on other sites

Alright, I jumped the gun. Scratch the SlowMo idea:) it works the opposite of what you need.

Although it allows you to fine-tune eases on either side of a Linear ease... it goes easeOut > Linear > easeIn... whereas you need easeIn > Linear > easeOut.

Link to comment
Share on other sites

I don't have time right now to experiment with this, but here's an idea for you: use ThrowPropsPlugin on the time or totalTime. The beauty of that tool is that it handles a lot of that complex math for you and you can simply tell it an initial velocity (change per second which in teh case of our timeline's "time" property would be exactly 1) and feed it an end position (in this case, the duration() of your entire timeline) and it'll figure out the appropriate duration based on the ease you supply (which should always be some sort of easeOut). For example:

timeline.pause(); //we'll let the tween handle the movement of the playhead
ThrowPropsPlugin.to(timeline, {throwProps:{time:{velocity:1, end:timeline.duration()}}, ease:Power2.easeOut});

So like Carl suggested, you just make sure all your Bezier tweens use a Linear.easeNone and let the ThrowPropsPlugin tween handle the ease out at the end (in theory at least - again, I haven't experimented). As far as the ease in goes, you could simply tween the timeScale from 0 to 1.

 

Does that help?

Link to comment
Share on other sites

Nice one, Jack. Yup, ThrowProps works as you suggested.

 

It worked quite well when I tried just using a loose tween to ease the timeScale from 0 to 1 at the beginning, and a callback towards the end to ThrowProps the time to 0.

http://codepen.io/GreenSock/pen/kwdmG

 

BTW, I hadn't considered that the velocity of time is 1 second per second. Nice.

 

Trying to implement a "cleaner" solution where are the time-shifting of the Bezier timeline was handled in a single timeline I ran into a few challenges.

 

Below it works great forwards:

 

http://codepen.io/GreenSock/pen/dwzAn

 

But since the first tween is a timeScale 0 to 1 tween, playing that backwards does not drive the playhead backwards. So if reversing is a requirement, a little more mad-science may be necessary. 

Link to comment
Share on other sites

Thanks for the great brainstorming guys...

 

I had read about and thought about throwProps earlier when thinking about options (due to its ability to pick up with whatever initial object speed existed), but sort of abandoned that train of thought because I didn't expect it to be able to drive a bezier, and didn't consider the concept of  throwing to a "time" value (in contrast to the more standard use of throwing to a position) -- wow, this thing needs more inspired examples in the docs to show off more of the non-standard possibilities.

Velocity of time is 1... interesting...I probably would never have pulled that out of the air on my own... I guess that's really saying the timescale is 1 at that point, right?

 

Carl -- spent a lot of time staring at that mega statement in your second "cleaner" example -- powerful  consolidation of stuff being declared there all in one place --- I couldn't quite get a grip on the how that pulls off the same thing as example 1, especially the middle part -- obviously it does though :)  What is the significance/purpose of duration()-2.5?   I think maybe my problem is that I need to look into the nature of the "set" method, which I've not used before...

 

Being able to reverse/yoyo would be nice for this general purpose motion path editor/engine... Is the problem of not being able to reverse the playhead limited to just tweens that involve timescale? What if if the front-end ease-in was done by tweening to a certain progress or time value using an ease-in, instead of timescale?

 

Thanks again for all the suggestions and demos.

Link to comment
Share on other sites

Yeah, I can see how some of those values can be a bit mysterious.

Hopefully this helps:

Screen Shot 2014-03-06 at 12.38.27 AM.png

Link to comment
Share on other sites

Yeah, you should be able to build a timeline that does all that you're talking about and can be reversed...just gotta think outside the box a little...

  1. Build your main bezier timeline with all linear easing just like we've talked about (I'll call this mainTimeline)
  2. pause() it.
  3. Build ANOTHER timeline whose sole purpose is to control the playhead of the first timeline (I'll call this controllerTimeline). Essentially you'll create eases that control the "time" property/method of mainTimeline (or the timeScale)
  4. controllerTimeline would be populated kinda like this:
var totalDuration:Number = mainTimeline.duration();
var easeInDuration:Number = 2; //or whatever
var easeOutDuration:Number = 2; //or whatever
controllerTimeline.add( TweenLite.to(mainTimeline, easeInDuration, {throwProps:{time:{velocity:-1, end:0}}, startAt:{time:easeInDuration}, ease:Power3.easeOut}).reverse() )
  .to(mainTimeline, totalDuration - easeInDuration - easeOutDuration, {time:totalDuration - easeOutDuration, ease:Linear.easeNone})
  .to(mainTimeline, easeOutDuration, {throwProps:{time:{velocity:1, end:totalDuration}}, ease:Power3.easeOut});

Then you can simply play/reverse/seek the controllerTimeline and it should work perfectly (at least in theory - I haven't tested this). The most funky thing you'll notice about the code above is that for the easeIn tween, I'm using a reversed throwProps tween. I'm basically doing a normal tween from a time of 2, with a negative velocity so that it would make the playhead move toward the beginning of the timeline and gradually come to a stop - that's precisely the time of movement we want, but in reverse (hence the reason I created it that way and reversed it). That way, we get the smooth velocity hand-off of throwProps and we don't have to deal with the funky speed-jerk of going from a normal easeOut to a linear tween. 

 

Again, I haven't really tested all this but hopefully the theory holds up and/or it nudges you in the right direction. 

Link to comment
Share on other sites

EDIT: this response below was to Carl's last posting, had not yet seen Jack's latest post when I posted this:

 

Thanks Carl,

interesting... and helpful graphic btw.   I think I was struggling with interpreting the more compact syntax of the method "chaining" that's going on in the statement -- I tend to use discrete statements to set up the individual tweens within a timeline (just the way I got comfortable using/understanding  gs, I guess, since most all the examples/tutorials are done that way)

So am I correct in interpreting this as each chained method effectively gets applied as an action on completion of the previous tween/timeline action, basically as if each of these actions were separately appended to a timeline? 

In other words:

the ".fromTo" runs on the instant result of setting bezTimeline to 0 time...

the ".to" runs the bezTimeline from the "inherited" starting time of 2 seconds out to a target time of 7.5 (5 sec duration)....

the ".add" effectively appends the final throwProps tween to the end of the "adjusted" timeline, which is at time 7.5 where the linear tween left off...

Is that the way this operates?  It's cool that it can be laid out this efficiently, I was just not aware you could get such things operating sequentially simply by stringing the methods together like this... I would have assumed that discrete declarations (adds) would have been needed for each operation... Live and learn..  You probably have examples of this technique all over the place.. I just haven't looked at them -- haven't seen this in any of the doc examples...I assume AS3 can use the exact same syntactical approach?

Link to comment
Share on other sites

Method chaining works by having functions return their caller, so the next function in the chain will be called on the the same caller. Most timeline functions return the timeline itself e.g.

var mytimeline = new TimelineLite();

mytimeline.to(...);   // returns mytimeline
mytimeline.from(...); // returns mytimeline
mytimeline.to(...);   // returns mytimeline

does entirely the same thing as

var mytimeline = new TimelineLite();

mytimeline.to(...)    // returns mytimeline
          .from(...)  // returns mytimeline
          .to(...);   // returns mytimeline

The only functions that prevent chaining would be getters like duration() or time() - since they don't return the timeline, you can't chain after one of those. Not sure how often you'd need to do it, but it allows you to write things like this though:

var mytimeline = new TimelineLite();

var myduration = mytimeline.to(...)
                           .to(...)
                           .duration();

And yep, JavaScript and AS3 work the same way here =D

  • Like 1
Link to comment
Share on other sites

Jack -- thanks very much for thinking that through and explaining it-- very clever way to get the benefits of throwprops auto-speed matching on both the front and back ends..  I guess, since reverse() is specified,  it would force the pre-evaluation of the middle linear tween to determine the speed it needs to match to when initially running forward.

This certainly appears to be the most flexible and universal approach... 

 

By the way, if someone were trying to make the original constant speed approach (assigning each bezier a duration needed for a constant speed based on bezier length) work when easing was added to the final or beginning beziers of a series, the thought struck me yesterday that a  fixed factor could be arrived at (I think) for each type of ease, that could be used to reduce the eased tween's calculated duration such that the entry/exit speed would match up with the adjacent non-eased tweens.. In other words, whatever the length of the eased tween, that one factor would always work when multiplied by the calculated duration, for a given ease-type... of course that "one" factor would have to be arrived at by some sort of trial and error for each ease type offered, but at least there would be no need for a complex dynamic runtime calculation. 

Nonetheless, the throwprops approach you suggest should be much better in terms of easy design, general flexibility, and in being able to set ease in and out durations that can cross over bezier tween boundaries if need be (the eased portions of the path don't even care where the individual bezier tweens begin and end  -- which is nice).

Link to comment
Share on other sites

Jamie -- yep, thanks for the clarification on the chaining conventions/capability --- makes sense.. I've seen it used elsewhere in js/as for various types of methods, but I guess I just assumed that tweening operations would not lend themselves to that... now that I see it laid out, and think about it, not sure why I felt that way :)

Link to comment
Share on other sites

Oh yeah.... the old reversed, negative time-velocity, throwProps-tween trick. 

I was just about to try that but wanted to give Jack time to figure it out;)

 

Shouldn't be surprised, it works great:

http://codepen.io/GreenSock/pen/usoyj

 

My only adjustment was changing the easeIn/Out eases from Power3 to Power1 which appeared a bit smoother.

 

---

 

@da2020,

 

Yes, it seems like your understanding of what I was doing is very good, and Jamie's explanation is perfect.

 

In addition, I'd recommend you watch this short video:

http://www.greensock.com/sequence-video/

 

Although it uses JavaScript the exact same principles and syntax apply.

  • Like 2
Link to comment
Share on other sites

Thanks for putting that pen together, Carl. It actually exposed a flaw in my logic - the durations of those throwProps tweens needed to be adjusted according to whatever ease is used. Here is the adjusted codepen:

http://codepen.io/GreenSock/pen/usoyj

 

And here's the code:

var bezTimeline = new TimelineMax({paused:true});
bezTimeline.to("#creature", 8, {
    bezier:{
      type:"soft", 
      values:[{x:150, y:300}, {x:300, y:30}, {x:500, y:320}, {x:650, y:320}, {x:900, y:100}, {x:970, y:370}],
      autoRotate:true
    },
  ease:Linear.easeNone})

var controllerTimeline = new TimelineMax({repeat:-1, repeatDelay:0.5, yoyo:true});
var totalDuration = bezTimeline.duration();
var ease = Power2.easeOut;
var easeInDuration = 2; //or whatever
var easeOutDuration = 2; //or whatever

//now we adjust the duration according to the ease to make it a smooth velocity at the transition
var adjustedEaseInDuration = ThrowPropsPlugin.calculateDuration(0, easeInDuration, 1, ease);
var adjustedEaseOutDuration = ThrowPropsPlugin.calculateDuration(0, easeOutDuration, 1, ease);

controllerTimeline.add( TweenLite.to(bezTimeline, adjustedEaseInDuration, {throwProps:{time:{velocity:-1, end:0}}, startAt:{time:easeInDuration}, ease:ease}).reverse() )
  .to(bezTimeline, totalDuration - easeInDuration - easeOutDuration, {time:totalDuration - easeOutDuration, ease:Linear.easeNone})
  .to(bezTimeline, adjustedEaseOutDuration, {throwProps:{time:{velocity:1, end:totalDuration}}, ease:ease});

You should notice now that regardless of what power you make the ease, the transition between the intro ease and the main linear movement and the extro ease are basically seamless.

 

Is that what you were looking for da2020?

  • Like 2
Link to comment
Share on other sites

yep -- i can run with that -- very cool and impressive. I may even incorporate this down at the individual bezier timeline level to give flexibility on how motion easing can be optionally used for each of the bezier "segments" in the path. After seeing this, thowProps is probably one of the most underrated plugins as far as solution potential :)

 

Thanks to everyone for the thought, demos, and explanations!

 

- Doug

  • Like 1
Link to comment
Share on other sites

Hi Jack and all,

 

Wanted to provide some updates, and ask a question, after incorporating Jack's general solution, described above, in my app.  The approach does work very well in terms of providing a seamless ease in and out with no undesired jumps in speed at the borders of the eases and the central part of the timeline. 

 

One practical issue I've been grappling with in my application is the user experience aspect of selecting the ease-in and ease-out durations. If the user is editing a path that is 10 seconds long, and wants the speed to ramp up  in 2 seconds, and ramp down in 2 seconds at the end, they would enter these as the desired durations for ease-in and out (and would also selected a desired easing power). The "problem" is that, since the actual duration of the easing periods has to be calculated due to the slowing caused by any given power of easing, the ACTUAL duration of the ramp up and ramp down periods isn't just a little different than the 2 seconds desired, but can be a LOT different, like around 2-3 times as long... So, one might be expecting, or wanting,  2 seconds to ramp with some easing power selected, then 6 seconds at the constant "linear" speed, then a 2 second deceleration using some easing power; but, if they choose a stronger ease, like power3, they'll actually get a ramp-up and ramp down duration of around 4-5 seconds each, leaving almost no time for the middle constant speed period.

 

I was able to solve this using the crude "goal seek" loop code shown below (this code is for the path's starting ease-in... similar code was used for setting up the ending ease-out).  This simply determines the approximate adjusted, and non-adjusted ease duration values (both are needed) to produce an ACTUAL duration that is close to the desired/entered value (where easeInDuration is initialized to the user's desired time value)

While this works, I'm wondering if Jack or anyone can see a more direct way of arriving at this target value for a user-specified actual duration (entered at runtime)?

 

 

//when added before Jack's code above, this loop provides an easeInDuration value and adjustedEaseInDuration value that will approximate the actual duration of the ease period (again. a crude approach, happy to improve based on suggestions):

 

for (var d:int = 11; d > 0; d--)  //number of loops is just a matter of how much precision is needed in the approximation

{
    testDuration = easeInDuration / d; //easeInDuration equals user-specified actual duration target
    adjustedEaseInDuration = ThrowPropsPlugin.calculateDuration(0, testDuration, 1, ease);
    if (adjustedEaseInDuration > easeInDuration)
    {
        easeInDuration = testDuration;
        break;
     }

}

 

 

P.S.  These 2 items are  other things I'm grappling with, using  the new throwProps approach:

 

1) I'm also still piecing together how to adjust to an actual total path duration (also user-specified), given any user-entered ease-in and out durations and ease powers... this would require dynamically adjusting the linear constant speed for the middle to achieve the needed overall duration -- I suppose it could be done by calculating a factor based on how much "over" the actual total duration is relative to the desired total duration, and then applying that to overall timeline's timescale.. not sure.. any thoughts on that welcome also).

2) Also, per a prior thread, I'm using a timeline.time(.0001) (or similarly small value) to set the initial rotation of the object, when timeline is still paused and object is sitting at the starting position, so that it aligns with path when the bezier's autoRotate property is enabled. I'm finding that with the new reverse throwProps trick for accomplishing ease-in, this approach to setting the initial pre-motion rotation of the object no longer works unless I use a much larger value, like timeline.time(.1), which make the object move off its initial position by a noticeable amount under some situations..  I think this is because with higher ease-in powers, the motion at that very early point remains so close to 0 that no autorotation is calculated... I say this because only higher easing powers need a higher initial time value to set rotation... My workaround may need be running the original timeline.time(.0001) against a straight timeline without the ease-in applied (just for setting object's initial rotation if AR enabled) and then immediately replace that straight timeline with the throwProps version that adds the easing...  I think this will work. but clunky... do any cleaner alternative approaches come to mind?

 

.

Thanks,

 

Doug

Link to comment
Share on other sites

We really try to keep these forums focused on very specific GSAP-related problems (we just don't have time to offer free consulting services to everyone), but I'll offer this for your first query: You could try...

adjustedEaseInDuration = easeInDuration / ease.getRatio(0.05) / 0.05;

Regarding the autoRotate 0.0001 thing, it'd be helpful if you provided a simple FLA we could publish or sample code that demonstrates the issue. In theory, 0.0001 should be fine, although maybe your actual path has that initial rotation that looks straight (not sure - I'd need to see your stuff). 

 

You are using the latest BezierPlugin, right? The old v11 one used a completely different (and less accurate) algorithm for figuring out the rotation that sounds like what you're describing - it's important that you're using the latest one to get the best results. 

Link to comment
Share on other sites

Thanks Jack.  I'll give the getRatio approach a go  -- the issue is really just one of being able to set up a predictable duration for the throwProps-based easing period.

 

Yeah, everything is v12, as purchased and downloaded last November. Actually, I was running fine with an initial time value as small as .00001 for setting the AR-driven rotation when the timeline was running beziers linearly. It's only when the up front ease is introduced to that same bezier timeline (per the throwProps code exactly as above)  that this threshold needs to be raised significantly... and the amount it needs to be raised is proportional to the power of the ease (ie, the extent to which "near-0 motion"  persists at the start of the timeline).  The AR works fine in all other respects once the timeline begins playing.

I think I can get by with the workaround I alluded to above -- just set the orientation using a non-eased timeline, then swap in the eased version.

Link to comment
Share on other sites

Jack,

 

Think I isolated a contributing factor as to why my timeline.time(.00001) approach for initializing the autorotation of an object was no longer working when using throwProps-based ease-in at the start of the path (as described above):

 

When you asked just above if I was using v12, and I answered yes, it slipped my mind that I was actually using a bezierPlugin v12+ version that you supplied me 2 weeks ago.  In one of my earlier threads ( http://forums.greensock.com/topic/9103-bezier-tween-autorotate-behavior-when-in-a-timeline-series/ ), you supplied that special bezierPlugin build (February 26)  for me to fix an issue that you agreed was leading to counter-intuitive autorotate behavior when restarting a timeline. I had a hunch this might be causing the AR initialization problem above, since you seemed pretty confident that vanilla v12 should not have this problem.  Sure enough, when I swapped back in the baseline v12 bezierPlugin (v12 as of Nov 2013), the initial AR rotation scheme ( using time of .00001) then worked fine for all types of throwProps-based eases. It would seem that the fix to save and restore initial object properties when restarting is interfering with the ability of the small time values to set the object's AR rotation.

It's up to you -- if you can see a simple remedy in the plugin design, that's great, otherwise I can live with my current solution, which is conditional logic that uses timeline.time(.2) to set AR rotation when higher power eases are involved (that's how far into the timeline you have to go to get AR rotation when power3 or 4 is used).

In any case, I appreciate the Feb 26 fix, since it solved a different, potentially more important problem in how AR is initialized after a restart.

 

Thanks,

 

Doug

Link to comment
Share on other sites

Ah yes, I think I know why. Very minor adjustment needed - would you try the attached version and let me know if it solves things for you? 

BezierPlugin.as.zip

Link to comment
Share on other sites

Jack,

 

With the new plugin, it does still solve the February problem (restoring proper initial position after a timeline restart despite downstream beziers with AR enabled), but the recent problem of not responding to very small initial time values to set the AR angle is still there.   Meaning, with .00001 (which works with all easing powers in the baseline v12 plugin),  the starting AR rotation is still not getting set with any ease power from 1-4 -- it does work, though, with linear power0.   With some quick tests, I had to run the timeline.time() value up to around .01 just to get power1 to work, but even then powers 2-4 would still not work... so that behavior seems to still be similar to the that of Feb 26 version.

In case you're wondering, the test case would be just like what you have set up in your throwProps easing codepen above, but with the controllerTimeline paused at the start, setting controllerTimeline.time(.00001)  (or whatever very small number) and then observing that the object is oriented to point down the path while still sitting at the starting gate... if you do that, you should see that linear ease works, but if an easing power of 1-4 is used the object does not get set to the AR value with that small time setting, unless you jack it up into the .01 - .2 range, depending on the power... hope that makes sense..

(as a reminder of why, the author that uses this tool is able to drag the points and thus curve shape around, while the timeline is "paused", and see the object's rotation track the path's departure angle from the starting point, and this also sets the object's position in the "published" runtime mode such that the object will be pointed in the right direction even before it's launched to travel down the path)

 

If the solution isn't obvious or too much of a pain to pursue, no sweat, I can make do with the workaround I've got...  I realize that the combination of things I'm trying to do is probably very unique to my application.

Link to comment
Share on other sites

Hm, I tried that value in the codepen as you suggested and it seemed to work great. I'm a little confused - could you provide a super simple FLA that I can publish on my end that demonstrates the issue? FYI, to avoid rounding errors in Flash (and browsers), any duration of less than 0.0000001 is rounded to 0, but you said you were using a value of 0.00001 so that should be fine.

 

[EDIT: nevermind, I think I found a sample. Stand by...]

Link to comment
Share on other sites

Sure, I can provide a sample if you still need it.  Yes, the value is .00001, and the problem with powers 2-4 persists with values all the way up to .01 or even higher.  And, remember that it all works great at .00001  if I use the standard v12 bezierPlugin, as of Nov-2013 (without the restart saved value init fix)...  The reason I need something closer to .00001 rather than much larger values is that, with longer paths, and with higher path speeds, that time percentage can be big enough for the the object to jump off the starting point by 10's of pixels (especially if it's a linear no-ease case), causing a noticeable jump away from the actual starting point.

Standing by....

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.
×