Jump to content


  • Posts

  • Joined

  • Last visited

MLM's Achievements



  1. @Carl Thank you for the insight into the decisions! Just to be clear, I like your solution of adding them onto the very end after everything else is built mentioned in Post #6 the best so far. I think infinite timelines are a big use case. Although I am new to GSAP and I am still working on my first animation. I am using it to keep a flame flickering constantly while other stuff continues to go on. Hopefully the way I tackled this problem with an infinite timeline, doesn't turn out to be a XY problem. But I can also see it for a buzz-saw rotating, a hand poking/hinting at pushing a button over and over, sun continuously rotating its rays, character blinking, ambiance light flicker, a clock in the background, tail wagging, step-by-step instructions that repeat over and over before you press "next", etc. While some of those can be replaced with a CSS animation, GSAP's power and control would be lost. The reason `tl.recent().endTime()` becomes cumbersome, even after being wrapped up nicely, is because everything has to have a explicit position after the infinite timeline gets added. It becomes a fiasco of having to have explicit positions and `.addLabel` everywhere. Can a plugin wrap up this non-blocking infinite timeline functionality? As long as it is possibly to shove the gritty details behind a library and have everything work awesome, this could be a great solution.
  2. @Diaco.AW This is very similar to @OSUblake solution which is not very ideal.
  3. @Diaco.AW Here is a pen with your solution. The root timeline `pause` doesn't pause the child timeline. I also noticed that if you are at the beginning before it starts rotating, and then seek "yellow-label" it doesn't rotate. Although this works fine with the "cyan-label"(which is also after the `add` rotate function), so I am not sure what side-effect is happening there. @Carl Your solution for adding infinite child timelines after everything else is built is awesome! I wish I didn't have to sacrifice potential clarity from that would come from having it in a more logical spot. Perhaps a new keyword for the `TimelineMax.add` `align` option or a completely new option that would ignore the duration "so that it doesn't throw off where the "end" of the timeline". // New `align` option keyword // does collide with existing keywords, would need `ignore-sequence`, `ignore-start` tl.add(childTimeline, '+=0', 'ignore'); // Or new parameter `blocking` or `isBlocking` tl.add(childTimeline, '+=0', 'normal', 0, false); // Maybe a new method tl.addNonBlocking(childTimeline); tl.addIgnored(childTimeline); I really appreciate you laying out all of the possible options. Just to address your `tl.recent().endTime()` solution, very cumbersome to always have to reference a specific position from after the infinite child is added. This could also be cleaned up by putting the rest of the timeline in its own timeline if it didn't need to reference any labels in the root.
  4. @OSUBlake Thank you for the reply. Clever, but does have a flaw where you can pause at the beginning or any stage before it starts rotating, and then you press play which makes it prematurely start rotating. Also, because `start`, `pause`, `seek` can be called anywhere, I would need to wrap each one with the proper child timeline play/pause and only use the wrapped version throughout. But this also falls apart with `addPause`. I don't use `addPause` but I am looking for something robust and doesn't require maintenance so that I don't have to remember to add it in some list or in the wrapped call in order to properly pause it.
  5. What is the best way to handle child timelines that have a infinite duration? You can't just `TimelineMax.add` an infinite child timeline because they would block and cause the remaining events to never run in the root timeline. The best way I have found is `restart`'ing the infinite child timeline in an `onStart` or `onComplete` event. One problem I have run into with this method is, if you seek past when the child timeline gets initiated, then it will never run. When using `start`, `stop`, `seek` on the root/parent timeline, how do you `start`, `stop` the child timeline appropriately? Here is a basic example of an infinitely spinning ball that also translates around on the root timeline: http://codepen.io/anon/pen/vOpBEV let tl = new TimelineMax(); let ballNode = $('.ball'); // Set up the infinite rotating timeline let alwaysRotateTl = new TimelineMax({ repeat: -1, paused: true }); alwaysRotateTl .fromTo( ballNode, 2, { rotation: 0 }, { rotation: 360, ease: Linear.easeNone } ); // Now do some stuff on the main timeline tl .addLabel('red-label') .set( ballNode, { backgroundColor: '#ff0000' }, 0 ) .to( ballNode, 2, { x: 100, backgroundColor: '#00ff00', onComplete: function() { // Start the infinite rotate loop alwaysRotateTl.restart(); } }, 'green-label' ) .to( ballNode, 2, { y: 100, backgroundColor: '#00ffff' }, 'cyan-label' );
  6. @Carl Thanks for the reply, I think I understand the situation now. btw, we replied at the same time in case you missed that message. When exactly is the `from` state applied and the value remembered to return to (`restart`, `start`, non-paused timeline creation chained call)? In my actual animation, it seems to still be borked, even when doing all the `set`'ing first(synchronously) and separate. But `immediateRender` does solve it. My theory of operation in the demo: The first object works because the timeline is not paused when created, then the `set` is called and starts running, then `from` is called after in the chain and works as expected. But then first item takes longer to finish than the synchonous `forEach` so the rest of the items `from`'s get called before the `set` has a chance to go. Sorry, I am using Babel for some ES6 features such as template strings, let(although they work in modern browsers anyway) but I will refrain from using in future demos.
  7. @Rodrigo Thank you for the reply. It wasn't quite clear after reading your reply although I think I understand. `immediateRender` does solve the problem. Here is my understanding: `set` gets run in timeline time, while the `from` sets it's state immediately. The `from` runs immediately (I assume at a timeline.start/timeline.restart) and remembers whatever current value, which is not the `set` value because that will run later down the road. But I don't understand why the first one works as expected?
  8. When using `TimelineMax.from`, only the first object returns to the original `TimelineMax.set` value. All objects obey as I expect, when all of the `set`'s are done first, then `from`'s. I understand the timeline is doing the following respectively. I know they are different but in either demo, I expect the all of the bars to be at a `y` value of `20px` at the end. http://codepen.io/anon/pen/aOVwXv tl set from set from set from http://codepen.io/anon/pen/waPeOX tl set set set from from from
  9. @Carl The `addLabel` behaviour makes total sense now. Thank you for the explanation. I wish you could pass in another parameter after `position` to label it but the `TimelineMax.recent()` workaround works great. Here is the fixed barebones example. Carl also has a link to a demo in his reply. @Rodrigo Thanks for the reference, I have watched that video multiple times even before this issue. `TimelineMax.recent` would make a great addition to that page.
  10. When working with TimelineMax, is it possible to use a relative position and have a label? I have tried to chain `addLabel` before and after the desired position, but it does not seem to be able to be referenced. Am I falling into some sort of anti-pattern? Here is a barebones demo: http://codepen.io/anon/pen/VLrpQX var tl = new TimelineMax(); var boxNode = $('.box'); tl .fromTo( boxNode, 8, { autoAlpha: 0 }, { autoAlpha: 1 }, 'fadeIn' ) // Start the movement alongside the fade .addLabel('moveFromTop') .to( boxNode, 1, { top: '200px' }, 'fadeIn+=0' ) //.addLabel('moveFromTop') // One second after moving from top, move from the left .to( boxNode, 1, { left: '200px' }, 'moveFromTop+=1' );