Jump to content
GreenSock

da2020

Members
  • Posts

    35
  • Joined

  • Last visited

Everything posted by da2020

  1. Update - interesting observation/discovery: I used the generic object as tween target object approach suggested to get the high precision values for x and y, to support the point to point distance calculations in this bezier "flow" animation. It did work fine and yielded the high precision values expected from a non-display object, and it did marginally improve some of the "dithering" I had before on the scaling being performed. But, the most noticeable scaling fluctuations were still present in places where this should not have been occuring. In certain portions of the path, the animated graphic objects would gracefully shrink and then grow (technically they were slightly slowing down and speeding up, but my scaling was masking that visually). So rather than the shrinking only occurring in tight turns/sharp corners of the path as intended, it was also occurring in shallow parts of the curve where it should not, specifically in areas where there was a transition from a straight path into a shallow curve (before reaching the most curvy zone where the anchor points were located). Since I'm using timeline.time() to set the evenly spaced animated graphic positions along the path on each frame, it was as if there were some slight non-linearities in the time vs distance-down-path relationship. Which then made the thought of the bezier's "time resolution" pop in my head. I had set this value to 10 long ago, thinking that was a "very high" value that would assure near-perfect time/speed linearity throughout the bezier paths (and it appeared to when I was just bezier-tweening single objects down the path -- so have not concerned myself with it since). But, with these closely, and precisely space objects used in this "flow" animation, the value of 10 turned out to be not high enough. Long story short, I needed to kick it up to the 25-30 range for these fluctuations to no longer be noticeable --- now it appears rock solid, and the scaling only occurs where it's supposed to (which actually means the time-distance linearity is now close enough to "perfect". I would never have guessed that values above 10 for time-resolution would have ever been necessary, but they were in this case. It was also fascinating (to me) to see how predictable/repeatable the locations of the non-linear "distortion zones" were with the value at 10 -- always in areas where there was a transition from straight to slight curve or vice versa, but not really noticeable anywhere else... Anyway, I think the problem is solved with these changes, and for anyone looking to use timeline time settings to position a series of closely spaced graphics in an animation, it's good to know that time-resolution can have noticeable influence at values well above 10. I was concerned that the higher values (30) that I ended up needing to use would increase the processing time/cpu load, but I have not noticed a significant difference in cpu load so far (most of the load is from vector engine work involved in moving the many pre-drawn objects along the path, with smoothing to avoid a horrible look, and transforms for rotation (path orientation) and scaling). - Doug
  2. Thanks Jack -- very simple and effective solution, where the flexibility of the tween exceeded the flexibility of my brain I had a blindspot in my thinking that the bezier's tweening of "x" and "y" properties needed to be the standard x and y coordinate properties of display objects. Turns out I'm already using a proxy tween object, and tracking via onUpdate as above, for registration point offset/centering purposes, but both those objects need to be display objects since the proxy has to serve as a container for the target. Nonetheless, I should be able to just make use of the generic object as you suggest as a proxy for the proxy.
  3. This is beyond the scope of normal tween use cases (yeah, I know, what a surprise), but I have a need to precisely measure the straight-line distance between two points (ie, two timeline "time" values) along a bezier tween (which is nested in a timeline). I'm doing it now by setting timeline's "time" to point A, and then to point B, and recording the x y properties of the invisible tween target object at each point -- then it's just a matter of doing arctan2 on the diff y and diff x -- works great generally, but.... This distance calculation's accuracy is limited by the .05 pixel "twip" resolution (hence, round off error) that any flash display object's x and y properties are subject to. This resolution is fine for most purposes, but, in this case, that distance value is being used to dynamically alter the length (via scaling) of objects as they move along the bezier path ---- the .05 round-off error on these two points results in small, but noticeable (and undesired) fluctuations in the length of the objects moving along the path where sharp turns don't even exist (due to this random round off variation at various positions). Using a threshold to be less sensitive to this variation is one solution (but this has other issues). Anyway, I'm pretty sure that I could eliminate this problem if I was using the high precision Number type values that I suspect the tween uses internally to drive the tweened object's position. So, wondering if there is, without much fuss, a recommendation as to how these values could be accessed. Or, I'm certainly also open to a better way with the regular API, if there is one. For anyone that might be wondering, the purpose of all this is to make a series of graphical shapes that are following a bezier path (where "flow" is being simulated), such that, when these objects encounter a tight turning radius or sharp "point" in that path, they gracefully "shrink" (length-wise) in order to better track the path at that sharp turn point, and then grow back to full length as they come out of the sharp turn.. Essentially, I'm populating a bezier with evenly spaced graphics that "flow" down a path, like the 2D path plugins provide built-in support for when using circles, ellipses, and rectangles -- but since the bezier plugin does not support such populating and animation, I'm rolling my own solution based on the bezier plugin. As I said, this scheme already works fine except for the issue above, so there's really no need to worry about why I'm doing this if you don't follow my "purpose" explanation... I'm just looking for a suggestion on getting to those high precision x/y tween positioning values. Thanks, Doug
  4. Jack - I take your points as to why it "won't work" for the case where there are VERY few samples (frames) over the period where timescale tweening occurs. But, for what it's worth, I've actually got this approach working reasonably well for my purposes -- my goal was to be able to determine a decent estimate of the timeline's duration by taking no more than a second or so for the estimation processing (a reasonable "processing" delay from a UX standpoint in this path editor app) for longer motion paths that might otherwise take 15-30 seconds (painfully long) to run at normal speed. You may have thought that I was looking to do it in "near-0" time. Here's an example pen that shows an object moving along a bezier, with 3 consecutive tweening operations -- in each operation, the object rotates 180 as it eases into and out of a "slo-mo" mode (via a nested timescale tween) while it's inverted. The pen allows you to run at normal speed to see the actual duration (approx 17 seconds, which would be only 10 seconds if the timescale tweening was not applied). Then, you can run at 10X or 20X, and the estimated duration and % error are displayed for each run. At 20X, the estimate run is less than 1 second (my goal) and the accuracy of the duration estimate is typically within 1% or so (not super-accurate, and not good enough for rocket science, but good enough for editing a path for visual effects on presentation content).. http://codepen.io/anon/pen/xbgpj Part of the trick here was to adjust the timescale tween target to maintain the same ratio with the higher speed timescale setting used for high speed duration estimating (which is fixed for any given run). That way, the faster the timeline was made to run for estimating purposes, the higher the timescale target used in the nested tween. To your points, the accuracy would/does fall apart if going for substantially higher speeds (like 50X) or if working with paths with very short durations.... But, since I plan to adjust the speed increase factor for estimating based on the untweened path's duration, I would not need to increase speed very much (if at all) for very short paths in order to get under my 1 second goal for estimating time. I suspect that a good part of the inaccuracy that does exist is due to the variation in the time to reach the point where the timer is started and stopped in the first and last frames, since the error seems to be mostly in the ballpark of +/- 1 frame interval. And, as you said, there will also be some additional errors, even with a 1 second run, due to fewer overall samples. If there were a way to more tightly sync the the initial time recording, and the measurement at completion, with the start of a frame, that might reduce some of the error that does exist. I noticed also that browser type had a significant effect on accuracy, at least in the pen, where Chrome was most accurate (usually within 0.5% at 20X) and IE11 was the worst, at almost double the average error. FF was in the middle. Anyway, this is truly a "for what it's worth" posting, as this is certainly not a perfect solution. It's only useful if applied understanding the limits in how it can be used, as mentioned above -- just wanted to pass it along in case others were faced with a need to approximate long durations in some programmatic way without having to run the timeline at regular speed. I'd love to find a better way, but can't see a better way to crack this... Thought of moving the timescale tweening sequence to outside of the targeted timeline (to at least eliminate the added math headache of having the timescale tween slowing down its own timebase), but I can't see a way to be able to drop in these speed transition effects as gracefully as is done here, with the precise positioning (and syncing with other nested tweens) that the nested tween approach provides. Doug
  5. yeah, that's understandable.. Your snippet's OK for accounting for fixed timescale adjustments outside the timeline, but of course, my need has the dynamic, mathematical challenges you refer to.. Bottom line is I'm just trying to use time-based-tweening for slo-mo type effects that are superimposed on all the other things going on in the timeline -- it's just too cool not to pursue... and, yes, my nested timescale tween is getting eased by its own action by virtue of being in the timeline that's being dynamically time-scaled (yikes)--- I knew that would be calculus-bomb of great proportions, but you never cease to amaze me, so had to ask. The only Doug-like crude work around I could envision was setting the timescale to make the timeline run super-fast, then run it, and measure the time it took with the nested tween and all, and then scale that measured time back down to its "real" value... Definitely crude, but since this is an editor and not something that happens in "production runtime", it might work... Thanks
  6. I have a timeline that contains a number of tweens running in parallel/concurrently. One of those tweens is tweening the timeScale property of that parent timeline. With a single yoyo on that tween, it works great as a way to introduce "slo-mo" style effects at various points along the timeline (similar to the effect of the slo-mo plugin, but with more control on placement, etc). For various reasons, before running that timeline, I look at the timeline's duration, which generally reflects the overall combined duration of the tweens it contains. If there is a target duration being requested for the timeline, I adjust the timeline's timescale property so its actual duration will match the requested duration. This works fine too, generally. Just one catch that I've not been able to find a solution for: Since the above mentioned tween is tweening the timescale of its parent timeline, I've found that the duration property of the timeline does NOT reflect the lengthening of the timeline's actual runtime duration caused by this tween, even though that timescale tween is contained within the timeline (I guess that's because the duration is always given in terms of the timescale always being 1, which is fine usually, but not what's needed in this case). So, wondering if there is a way to determine the duration (before running it of course) of that timeline that DOES reflect the ACTUAL time that it will run, inclusive of the timescale tweening?
  7. Jack, The "to" helper definitely was not working in the fla (same surrounding code as the fla I posted above) -- there was no movement/tweening whatsoever. Anyway, I just found and fixed the problem - it appears. I vaguely remembered reading/hearing somewhere that the "to" helper uses tweenLite, not tweenMax (a "lightness" design choice I suppose). Well, since I was using tweenMax in my "add" statement, I didn't need to have a BezierPlugin activation statement. When I switched to the "to" helper statement, apparently the tween did not run because tweenLite does not automatically activate the plugin.. so simply adding the activation statement did the trick. Let me know if that theory isn't right. Weird that no kind of error was thrown though. Great news on the throwProps initial value solution.. thanks for getting to the bottom of that. I mentioned early on that I felt it probably had something to do with the math being too close to 0, for too long, with powers greater than 0, but had no idea where it was breaking down internally. I'll check it out, but I'm sure it will be fine as your explanation sounds very solid. Thanks much. So, given this solution approach, is the March 12 version of the bezierPlugin you provided still a better choice than the Feb 26 version? For future reference, what/when causes the uploaded file size limit to reset for a user on this forum? I thought about posting another FLA but saw that I only had 40KB left over from the 460K that was uploaded in a prior post... does that reset by day, by thread, or something else? (I had assumed the 500KB limit was per post, but apparently not). EDIT: I see in my settings that it looks like I have a total of 500KB, period, and will need to delete attachments to free up space when needed... no problem. Doug
  8. By the way, a baffling side issue I ran into when preparing the demo fla above. Like was used on your codepen (that obviously works fine), I initially used the "to" helper as shown below, instead of the add method that works fine in my attachments above (all other code is the same). This "to" statement just will not work in my fla...I get no errors, but the tween simply doesn't run when the restart is issued, or at all even if not paused. I stared at the syntax... can't see anything wrong with it... is this not supported in AS3 or am I missing something obvious? bezTimeline.to(pathObject, 8, {bezier:{ type:"thru", values:[{x:150, y:200}, {x:300, y:90}, {x:500, y:320}, {x:650, y:150}], autoRotate:["x", "y", "rotation", 90, false]}, ease:Linear.easeNone});
  9. Jack, If it's still helpful, I've attached a greatly simplified fla, and swf (compiled with your latest plugin version) that demonstrates the AR rotation initialization problem, exactly as described above. The timeline/tween/easing setup is essentially per your codepen above. The timeline is paused initially. Pressing the "Set..." button will do timeline.time(.00001) and cause the object to rotate in place to align with the path (without starting the timeline). Pressing "Go" runs the timeline. Reset button allows you to repeat the process from scratch. Note that I have ease set to Power0, so that it works (as mentioned, there is no problem when there is no ease/linear). If you set the power to 1, 2, 3, or 4, the "Set..." button's action no longer works -- to make those work you need to raise the .time() setting in the button handler to a much higher value in the range of .01 to .2, depending on the power -- these "high" values are problematic for low/0 power eases, as the object is taken off its starting point by a noticeable amount. If you recompile this with the baseline v12 bezierPlugin (mine's from Nov 2013), everything works fine, ie, all powers work at .00001. Hope this helps. Doug EDIT: Changed the attached SWF to one that was compiled with Power1 ease to show the "Set" button NOT working; the FLA has the ease set to Power0 which does work, bezierTimeInitTest.zip bezierTimeInitTest-SWF-SHOWS_PROBLEM_WITH_POWER1.zip
  10. 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....
  11. 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.
  12. 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
  13. 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.
  14. 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
  15. 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
  16. 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
  17. 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).
  18. 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?
  19. 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.
  20. 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
  21. 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
  22. Jack, Thanks much... that's exactly the insight I was looking for, particularly : "...if two tweens are placed directly on top of each other (same start time), the order that you insert them is honored (so the one you add last runs last)..." That probably confirms the theory mentioned earlier as to why I was seeing my proxy object rotate per the concurrent rotation property tween, while the targeted animation object (which is made to track the proxy object's position and rotation via the bezier's onUpdate), was, "surprisingly", able to rotate according to the bezier's autoRotate (AR) at the same time... Seems the proxy object first was rotated per AR, since the bezier tween was added first, then the bezier's onUpdate handler was run which made the animated object track that AR-driven proxy rotation, then the concurrent rotation tween (added second) was allowed to re-rotate the proxy object , and then eventually would come the next screen redraw -- net result: the proxy object visually appeared to rotate according to the rotation tween, while the animated target object rotated per AR... I'll take the advice to avoid this exact circumstance, but bumping into it definitely resulted in getting a better understanding of property tween priority determination, which will help in managing other cases --- such cases are somewhat inevitable when there is an app UI that allows a wide variety of options in defining how the object is tweened along the path. Thanks again, Doug
  23. I'll try to find some time to distill it to some sort of demo in AS.. I guess the stripped down crux of the question is this, which is pretty simple: Imagine a timeline with 2 concurrent tweens, both starting at time 0, and both targeting the same object. One is a bezier tween with autoRotate enabled, the other is a simple rotation tween. So, both are acting (or would act) on the same object's rotation property. Both tweens are added dynamically to the timeline, via two separate .add statements, while the timeline is paused. Then, later the timeline is kicked off to run from time 0. So, I'm wondering which tween would be expected to "win" as far as controlling the rotation of the object, and why (ie, what are the factor(s) that would allow me to know which one should win). That's the core of the question. Now that I see the various options under "overwrite" (that Jamie pointed out), I'm sure that is part of the answer, but I'm still not clear on the order of evaluation -- that seems to be tied to the order that the tweens are added to the timeline in the first place, but not sure. You may wonder why I'd want to set up such a condition... well, the UI for this app gives the user a choice to have an independent rotational tween set on the object as it moves along the bezier path, OR to use the beziers autorotate for orienting to path, OR possibly even some combination of both that would shift at different points along the path (which is possible since my path is made up of a series of separate bezier tweens)... so, I'm trying to understand this interaction so that I can provide predictable and repeatable options via the UI, and know for sure when I could expect one or the other to win out if they both happen to be enabled at the same time for a certain segment of the object's path.
  24. Jack, As an update, wanted to let you know that the use of the .time setting method you suggested above did work out fine for what I needed. Since last posting, I've run into yet another interesting autorotation (AR) behavior that I need to more fully understand: I've recently added features to the bezier plug-in based motion path editor app I'm developing to allow for various properties of the animated object (the object that is tweened along the bezier paths) to also be tweened in parallel (simultaneously). The bezier tween series is in an inner timeline, and that timeline is nested inside an outer timeline that also now contains tweens for rotation, scale, and alpha on the animated object. So, for example, if bezier AR is turned off, the parallel rotation tween can make the object rotate continuously while the object moves along the path, etc. These parallel tweens seem to work fine along side the bezier tweens. In this design, the bezier tweens and the "parallel" rotation tween are not directly controlling the targeted (visible) animation object, but are instead controlling a proxy object (normally invisible) that allows for various animated object offsets to be achieved, etc. In the Bezier's onUpdate handler, the x, y, and rotation of the tweened proxy object are assigned to the targeted animation object's properties, which then make it track the proxy object as it is being bezier-tweened (and autorotated if enabled)-- this all works fine with or without AR. When I added the parallel tween in the outer timeline to rotate the proxy object while it was also being bezier tweened, I expected this independent rotation action to work fine with bezier AR disabled (which it does), but I expected some sort of conflict/ tug of war if I were to enable AR, since there would then be two different tweens simultaneously trying to control the rotation of the proxy object... When AR was enabled (which I'd prefer to override the other rotation tween if there was a conflict) the AR did override in the sense that the TARGET object DID then follow the path... BUT, much to my surprise, the proxy object (which has a visual marker in one corner so I can see how it's moving) was smoothly rotating according to the parallel rotation tween (not per AR)... So, this begs the question: with AR on, how can the target object actually be following the path, while the proxy object (the bezier-tweened object that the animated target object follows via onUpdate) is, at the same time, appearing to rotate independently per the other rotation tween?? The only theory I have is that the bezier tween is grabbing control of the proxy object when it needs to, autorotating it to path, running onUpdate to auto-orient the target object to path as well (as in normal AR) and then control of the proxy is released such that the parallel rotation tween can ALSO then change the proxy's rotation as it needs (but without affecting the target object since the bezier onUPdate handler has already run).... and it so happens that visually I'm only seeing the proxy rotate per the parallel rotation (with no flicker) , rather than seeing it trying to also track to the path, due to the relative timing of the screen refresh that keeps me from seeing the short period when bezier has control of the proxy.... whew... but that's just a guess... So, it so happens that it works the way I need it to under these conditions, but my concern is that I don't necessarily understand WHY it's working this way, or whether it would always reliably work this way.... ie, I may be just getting lucky and something could be on the edge of not working without me realizing it, if that makes sense... Would you expect the behavior I described, and if so, is my theory in the ballpark or is there another reason? UPDATE: since the above posting, I noticed that the observed behavior depends on the order in which my outer timeline adds are done. If I .add the parallel rotation tween AFTER I .add the nested timeline containing the bezier tweens, I see what I described above. If I reverse the order, such that the beziers are added to the outer timeline last, I get the more "expected" visual -- ie, BOTH the proxy AND the animation object track with AR.. So, this seems to support the theory that both tweens (the independent rotation tween and the AR action within the bezier tween) take their turn manipulating rotation of the proxy object... and, the one that is added last, also apparently runs last, and therefore determines which of the two rotation effects is made visible at time of screen refresh.. (?) Thanks, Doug
  25. Thanks Jack. I'll try out those direct time settings.. I had tried jumping to small "progress" amounts before, and as I recall, the rotation would not get set with that approach, but I have not used .time before I don't believe.. You're right, the pick-up where the last tween's rotation left off behavior makes perfect sense as default behavior... if I was confused about anything I guess it was the effect and timing of declaring the rotation to be some value via .set prior to the appends which occur dynamically, to override the natural behavior of inheriting the final rotation of the previous tween... I've made my code to optionally run a .set on rotation prior to appending each tween in the series if the user has selected "fixed rotation" of a certain value for a certain tween (path "segment") -- that overrides the default behavior of inheriting prior rotation from the last tween, which allows there to be choice -- so that's all fine. Re the constant speed, I'm aware you can set the time resolution param to a high value in a single tween to make speed constant regardless of point spacing, but I was referring to my challenge of needing a constant speed across the multiple series of tweens that make up the overall path -- that was discussed in a prior post, and I ended up solving that by doing approximations of each tweens curve length and calculating durations that would achieve the same speed regardless of each tweens length, and of course they all have different lengths.
×