Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onComplete callback not being called on empty paused timelines #448

Closed
tchapi opened this issue Apr 23, 2021 · 4 comments
Closed

onComplete callback not being called on empty paused timelines #448

tchapi opened this issue Apr 23, 2021 · 4 comments

Comments

@tchapi
Copy link

tchapi commented Apr 23, 2021

Hi
I'm not sure if this expected behavior or not, but when creating a paused timeline with nothing in it, the onComplete callback is not fired on 3.6.1

const timeline = gsap.timeline({
   paused: true,
   onComplete () {
      console.log("timeline completed")
   }
})
timeline.play()

the log is not created, but in the previous version I was using (3.5.1), it was, so I'm not sure if I need to change something or if it's a bug

Thanks a lot for this wonderful lib !

@jackdoyle
Copy link
Member

Yeah, that's a bit of a tricky scenario because on one hand, the playhead hasn't moved at all thus it seems like it shouldn't "complete" but on the other hand, it is a zero-duration timeline (which is pretty weird actually) so you could make an argument that onComplete should fire. I've updated the next release to do that - you can preview it here: https://assets.codepen.io/16327/gsap-latest-beta.min.js (minified)

Better?

@tchapi
Copy link
Author

tchapi commented May 11, 2021

Hi @jackdoyle and thanks a lot for your answer !

I agree that it's tricky. My main point was that the behaviour changed for 3.6.1 which was a bit unexpected.

My use-case (just so you can image a real world scenario) is that I'm creating a timeline at some point, with an onComplete callback that I want to fire, and then, according to different parameters, I add sub-timelines to it. There are some cases where I don't need to add anything at all, so the timeline ends up empty, but I still want the callback to be fired. In my mind, the onComplete is a bit like a finally in a try / catch control flow: always firing at the end, whatever happens.

I had modified my script to use a call() call, which seems to work fine :

const timeline = gsap.timeline({ paused: true })

// Lot of stuff involving if (this) { timeline.add(that) }

timeline.call(() => {
    console.log("timeline completed")
})

timeline.play()

What would be the recommended way in this scenario you think ?

@jackdoyle
Copy link
Member

What would be the recommended way in this scenario you think ?

Either way should be fine, at least in future releases. Sorry about any confusion there.

@tchapi
Copy link
Author

tchapi commented May 11, 2021

No problem, thanks for everything !

jackdoyle added a commit that referenced this issue Jun 16, 2021
- NEW: percentage-based position parameter options for timelines - A value like "-=25%" would overlap by 25% of the inserting animation's totalDuration, or "<25%" would insert it 25% into the previous animation. See docs for details. Related: #444

- NEW: gsap.utils.selector() returns a selector function that's scoped to a particular element (or React ref or Angular ElementRef) - no need to create a ref for each and every element you want to animate, for example!

- NEW: gsap.utils.toArray() accepts an optional 2nd parameter, the Element on which .querySelectorAll() should be called (the scope) if selector text is passed in. Like gsap.utils.toArray(".box", myElement)  will find all the descendant elements of myElement with the class of "box".

- NEW: added getTween() method to ScrollTrigger that allows you to get the scrub tween (default) or the snapping tween (getTween(true)).

- NEW: ScrollTrigger.scrollerProxy() recognizes a fixedMarkers: true option that'll prevent it from moving the scroller markers. It can be useful in setups like described at #452

- NEW: ScrollTrigger recognizes a new pinnedContainer property which allows you to specify an ancestor element that gets pinned which would affect the positioning of the start/end values. For example, if the parent element gets pinned for 300px, the start/end values of a ScrollTrigger on that child element should be pushed down by 300px. See https://greensock.com/forums/topic/28255-scrolltrigger-not-delaying-within-pinned-element/

- NEW: MotionPathPlugin recognizes a new "fromCurrent" boolean value that, when false, causes it NOT to include the current property values in an Array that's passed in for the "path". For example, if the target is currently at x: 0, y: 0 and then you do a motionPath: {path: [{x: 100, y: 100}, {x: 200, y: 0}, {x: 300, y: 200}]} tween, by default it would add {x: 0, y: 0} to the start of that Array so that it animates smoothly from wherever it currently is but now you can set fromCurrent: false to avoid that and just have it jump to x: 100, y: 100 at the start of that tween. See https://greensock.com/forums/topic/28421-motionpathplugin-option-to-not-add-current-targets-position-to-the-start-of-the-path-array/

- NEW: Helper function added to the docs that can deliver onReverse() functionality plus much more. It's called trackDirection(). See https://greensock.com/docs/v3/HelperFunctions#onReverse. Related to #144 (comment)

- IMPROVED: Flip plugin has better support for SVG elements (it was created for regular DOM elements)

- IMPROVED: better support for special characters inside string-based "random(...)" values. See https://greensock.com/forums/topic/28077-using-special-symbols-and-characters-in-gsap-text/

- IMPROVED: if you enable() a ScrollTrigger (after it was disabled), it now resets itself by default rather than factoring in the previous position. So, for example, if its progress was 1 when it was disabled, and then you scroll the page all the way up and enable() it, it previously would fire its onEnterBack and onLeaveBack callbacks but now it doesn't. You can control this behavior with the new reset parameter of the enable() method.

- IMPROVED: better support in ScrollTrigger for CSS grid properties on pinned elements

- IMPROVED: ScrollToPlugin will sense if a scroll-snap-type is set on the target and if so, it will set it to "none" during the scrollTo animation, and then re-apply it at the end. See https://greensock.com/forums/topic/26181-scroll-snap-and-scrolltoplugin-not-playing-nice-togehter/

- IMPROVED: 2 extra decimal places of precision for generic tweens in order to add extra smoothing to ScrollTrigger scrubbing of very long timelines, for example. See https://greensock.com/forums/topic/28148-scrolltrigger-and-lottie-animation-flickering-problem/

- IMPROVED: TypeScript definition fixes and enhancements

- IMPROVED: for Draggables of type:"rotation", cursor changes are enabled

- IMPROVED: you can stagger keyframe tweens

- FIXED: if you animate a non-CSS property on a DOM element (like "innerHTML") with a .fromTo(), the "from" portion may not be pulled directly from that vars object. See https://greensock.com/forums/topic/27644-fromto-starting-from-0-instead-of-passed-value-when-1000/

- FIXED: .from() scrambleText animations with a starting value of "" didn't work properly.

- FIXED: ScrollTrigger.saveStyles() could cause inline CSS styles to stay reverted (like for from() tweens) when ScrollTrigger.refresh() was triggered aside from a "matchMedia" event. See https://greensock.com/forums/topic/25944-problem-with-scrolltriggersavestyles-and-scrolltriggermatchmedia

- FIXED: a timeline's iteration() could return an incorrect value if called from inside its own onRepeat callback. See https://greensock.com/forums/topic/27643-timeline-repeat-iteration-vs-standalone-tween-repeat-iteration/

- FIXED: a ScrambleTextPlugin from() tween could seem to have a gap at the beginning caused by an internal ease.

- FIXED: if you have a stagger applied to a ScrollTrigger animation that's a .fromTo() or .from(), it may not render it in the initial state before reaching the start scroll position (regression in 3.6.0). See https://greensock.com/forums/topic/27664-gsap-3-timeline-stagger-with-immediaterender-not-working/

- FIXED: if you didn't define an "animation" for GSDevTools (meaning it uses the globalTimeline), and then select another animation in the drop-down UI that has a delay, it wouldn't isolate that animation properly. See https://greensock.com/forums/topic/27690-question-about-dynamic-tweens-and-gsdevtools/

- FIXED: if you put a non-scrubbing scrollTrigger on a tween that has a delay and a stagger, it could skip the delay. See https://greensock.com/forums/topic/25610-problem-delay-property-not-working-with-srolltrigger/

- FIXED: if you tried using a modifier for a CSS variable, it didn't work. See https://greensock.com/forums/topic/27793-modifiers-with-vars/

- FIXED: the "restart" toggleAction of ScrollTrigger now factors in any delay value that was specified in the tween/timeline.

- FIXED: if you called ScrollTrigger.update() from inside an onUpdate callback on an immediately-rendering tween that has a ScrollTrigger, it could throw an error.

- FIXED: if a MotionPathHelper's tween had a target that started at non-zero x/y values, those offsets weren't factored in (so the editable path wouldn't match up with where it should be).

- FIXED: a regression in 3.6.1 could cause repeatRefresh on a timeline not to work properly in one particular case. See https://greensock.com/forums/topic/28031-gsap-361-timeline-issue/

- FIXED: if you use a snap duration on a ScrollTrigger that's shorter than the scrub duration, it could lead to odd results. See https://greensock.com/forums/topic/28112-using-scrolltrigger-w-fixed-position-sections/

- FIXED: in extreme cases, inertia in snapping could cause ScrollTrigger to scroll past the maximum or minimum, consequently restarting the snap. Overall, cleaned up several aspects of snapping in ScrollTrigger.

- FIXED: if you don't specify an animation for GSDevTools, it could fire callbacks of the animations when the page loads initially (and then again at the proper times). See https://greensock.com/forums/topic/19465-timelines-oncomplete-callback-fired-twice-when-gsdevtools-added/?tab=comments#comment-137962

- FIXED: if you create ScrollTriggers in a .matchMedia() and then resize to where all ScrollTriggers are removed, and then go back to a size where it creates the ScrollTriggers again, it could return to the scroll position from that initial state (before all ScrollTriggers were removed). See https://greensock.com/forums/topic/28114-scrolltrigger-does-not-revert-elements-to-their-original-values-on-resize/?tab=comments#comment-138731

- FIXED: onComplete didn't fire in a zero-duration timeline. See #448

- FIXED: when you set markers: true on a ScrollTrigger that uses a scroller with position: fixed, it won't change it to position: relative. See #452

- FIXED: if you gsap.getProperty(svgElement, "transformOrigin"), it would always return 0px 0px 0px for SVG elements.

- FIXED: if you cause the tween to render at a different time from INSIDE its onStart callback, it would still render at the original time.

- FIXED: if ScrollTrigger.update() was called from within a refresh handler, it could result in skipping the refresh() on some of the ScrollTriggers under certain conditions.

- FIXED: if you tried to render a .from() or .fromTo() tween at a negative time value (like rewinding it past the start), it may render the initial values rather than reverting.

- FIXED: if you try to set() an empty string value (""), it could be interpreted as "0". And if you use "=" as the second character in a string, it may not work correctly because it's interpreted as a relative value prefix, like "+=" or "-=". See https://greensock.com/forums/topic/28257-set-empty-strings/

- FIXED: if you animate to an invalid scale, like NaN, it wouldn't default to 0 and the transforms wouldn't render properly (because of that invalid value). See #453

- FIXED: if you timeline.tweenFromTo() an immediately alter its progress(), it may not render at the appropriate time.

- FIXED: if you use Draggable for a position: fixed element that has movement limited to one direction, on Android it may not drag properly. See https://greensock.com/forums/topic/28357-draggable-android-issue-with-position-fixed/

- FIXED: timeline.recent() may return the incorrect child immediately after a .fromTo()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants