Jump to content
Search Community

Search the Community

Showing results for 'overwrite'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • GreenSock Forums
    • GSAP
    • Banner Animation
    • Jobs & Freelance
  • Flash / ActionScript Archive
    • GSAP (Flash)
    • Loading (Flash)
    • TransformManager (Flash)

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge

Categories

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Personal Website


Twitter


CodePen


Company Website


Location


Interests

Found 1,412 results

  1. If you want it to happen for each of your images, then set the ScrollTrigger up in the forEach loop over the images. Adjust its start so it is the same as the start for the ScrollTrigger that is scrubbing the image-height plus half a window's height. Set your colors-array up, so that it also contains the initial color as the first value and then target the colors like this in your callbacks. // pseudo-code... const colors = [firstPanelColor, secondPanelColor, thirdPanelColor, fourthPanelColor ] onEnter: () => { gsap.to("body", { duration: 0.5, backgroundColor: colors[i+1], overwrite: 'auto' }); } onLeaveBack: () => { gsap.to("body", { duration: 0.5, backgroundColor: colors[i], overwrite: 'auto' }); } https://codepen.io/akapowl/pen/rNKORBb
  2. it seems I didn’t quite understand you, or I didn’t explain it well, I know how to change the background when the first panel reaches 50%, but how to change the background of the next ones so that each panel has its own color, I tried to do this, but the panel changes color only 1 time per black const colors = ['#F5EBFF','#EEF8FF', '#000000'] ScrollTrigger.create({ trigger: "section.black", scroller: ".scroller", start: () => "top -" + (window.innerHeight * 0.5), onEnter: () => { console.log('color', colors[i]) gsap.to("body", { duration: 1, backgroundColor: colors[i], overwrite: 'auto' }); }, onLeaveBack: () => { gsap.to("body", { duration: 1, backgroundColor: i === 0 ? '#ffffff' : colors[i-1], overwrite: 'auto' }); }, invalidateOnRefresh: true })
  3. In JSFiddle, what I have built works like a charm(timeline with boxes that fade in from left/right). This was copied from a previous website I Have created and it worked perfect there as well. However, for some reason on another website it simply won't work. The error thrown is the overwrite error and I simply can't understand why it won't work considering it's literally the same. Done with ScrollMagic, GSAP, jQuery. https://goo.gl/JeUiEE
  4. Definitely. If you don't kill() that animation, it will keep running. So every time there's a resize event, it'll create a whole new infinitely-repeating tween and every one of them will be fighting for control of the same properties of the same targets. You don't notice it because basically the "last one wins". So you may have 100 animations all running and tweaking the same property, but the last one created is the last one that runs, thus the final render looks correct. You just have a bunch of unnecessary tweens doing unnecessary work. You could set overwrite: true or overwrite: "auto" if you prefer, but I think it's cleaner/faster to just kill() the old tween before you create the new one. Yep. Here's a technique I use: // reusable function that handles setting it all up for you... function callAfterResize(func, delay) { let dc = gsap.delayedCall(delay || 0.2, func).pause(), handler = () => dc.restart(true); window.addEventListener("resize", handler); return handler; // in case you want to window.removeEventListener() later } Usage: callAfterResize(loop); By default, it'll wait until 0.2 seconds elapses with no "resize" events before calling the function, but you can customize it, like if you want it to wait 0.5 seconds instead: callAfterResize(loop, 0.5); Done. ✅ Have fun!
  5. Hi I've been struggling with the issue of conflicting timelines/tweens over and over again. Notice how in the example, the "more info" divs are consistently not appearing after resizing the browser window while the animation is playing (you'll have to open the example in a new tab to see the problem). https://codepen.io/ynamite/pen/jOeovBm I can't seem to revert a timeline/tween to it's initial state and reinitializing the timeline/animation after resizing the browser window. I've tried killing and/or clearing a timeline, I've tried spamming `overwrite: true` everywhere, I've tried debouncing the resize event etc. I'm at a wits end ... I've checked the forum but could only find the solutions I've already tried. Neither overwriting nor killing/clearing tweens/timelines seems to do the job, at least not in all cases. Sometimes it works and in other cases it just doesn't. It feels inconsistent and my code is starting to feel quite hacky. I'm probably missing a thing or doing something wrong. The example shown on the following page seems to exhibit the same behaviour I'm experiencing: Once you click on "move back" and then click on "restart" the animation seems to break. At least in the way that I understand it. By clicking "restart" I'd expect the element to move back to the right edge and roll back to the left (like it doesk on page load). Instead it just hangs and rolls on the left. Thanks!
  6. Hello GSAP forum! This is my first thread, hope I post it within the rules around here. I've been using GSAP for quite a while now, but there are still a lot of aspects that I couldn't comfortably say I've figured them all out. Such as overwrite, invalidate, restart, stop, seek and so on... I've been reading docs, search on Google, forum post etc, I still can't figure out the most simple things. Question: In the codepen sample, what should I do so whenever I click on buttons the line goes to left or right from wherever it is when the button is clicked. Multiple times. I seriously couldn't figure it out. Any help would be appreciated. Thank you
  7. I'm half afraid to suggest this because it probably exists and it just didn't read the docs close enough, but I think it'd be really useful to have an overwrite mode that checks the assigned value of a tweened property, and doesn't overwrite if the value of one tween matches the value of another conflicting tween. For example, if you have 1 sec tween to Y position "10", and during that tween you call another 1 sec tween, also to Y position "10", the second tween could be ignored with this proposed overwrite mode. Could be useful when multiple UI elements effect the same targets and you don't want a stutter caused by successive tweens with unchanged property values. Hope that all makes sense.
  8. Hello! Is it intended that the Promise object, which is returned by a Tween's .then() method, isn't terminated when the animation has been overwritten? At first I planned on using it in combination with the async/await syntax, which sometimes resulted in a permanent halt of the respective function. (In my tests the status of the Promise remains "pending" after the animation has been overwritten.) But even when I use it with a then-catch-structure, no clause is executed. In the end I promisified the GSAP animations myself: // for example function hide(elmnt, duration = 0) { return new Promise((resolve, reject) => { gsap.to(elmnt, { duration: duration, autoAlpha: 0, overwrite: 'auto', onComplete: resolve, onInterrupt: reject }); }); } I feel like this undermines the usefulness of the .then() method (at least for some usecases). Have a good one!
  9. Working on an app where users can position an SVG on the "stage" and pick an "IN" animation. Uses a from tween that starts offstage and ends wherever the user has positioned the SVG. I pulled the stage setup, some of the code and a few buttons as well as a preselected "already-added" SVG to the Codepen. There's a master timeline and each SVG becomes an element defined in a new svgObject containing its own timelines for animation onto the stage (the "IN" timeline), animation while on the stage (the "ONSTAGE" timeline) and animation off the stage (the "OUT" timeline). There can be multiple SVGs and each can have it's own tweens as well as start and end times, positions, etc for each of the 3 timelines. Kind of like this... Right now, I'm just trying to figure out how to dynamically change the "IN" tween if the user clicks a different "IN" option button. Also, trying to figure out how to properly pass new vars like ease changes. My thought was to overwrite the "in" tween and "in" timeline every time a new "in" option is chosen and to do the same for the out tween and timeline. (The onstage timeline might contain multiple options where I'll need to give the user the option to add/chain new vars and tweens) I must not understand the overwrite var and I also must not understand invalidate. I added... overwrite:'all',onOverwrite:overwrittenTween ... to the tweens but the overwrittenTween function is never running. I'm doing this at the end of each "IN" tween button click listener function... var theTweens = masterTL.getChildren(); console.log("theTweens",theTweens); ... (masterTL is the master timeline), and the tweens are all still there and growing with each click of a new "in" tween option. Also, trying to change the ease is not working as I thought it was supposed to. When I add a new ease like this: activeSVG.twIn.vars.ease = newEase; activeSVG.twIn.seek(0).invalidate(); The tween seems to break. As hinted at above, for each SVG, there's an object structured like this... var newSVG = (function() { var SVG = { el: $('#svg-0'), // the SVG itself id: "0", gp: $('#gp-0'), // there's a group that wraps each SVG with the same id# rotating: null, // GSAP Draggable object dragging: null, // GSAP Draggable object resizing: null, // GSAP Draggable object tlIn: new TimelineMax(), // in timeline twIn: null, // in tween tlStage: new TimelineMax(), // onstage timeline twStage: null, // onstage tween tlOut: new TimelineMax(), // out timeline twOut: null // out tween } return SVG; }); ... so I can set all the in/out/stage timelines and tweens for each object there. I bet I'm missing something really obvious.
  10. Hey, I have found a great and straightforward demo on the forum of repeat and reverse animation, which was created by @mikel. Here it is https://codepen.io/mikeK/pen/dyooKjJ But using the latest GSAP version, the reverse animation doesn’t work the same as in the 3.1.1 version. The animation doesn’t stop on mouseleave. My main goal is to have repeated animation on mouseenter. But on mouseleave, I need to reverse only once instead of reversing the whole repeats. I understand I can do that with tweens and overwrite properties on mouseleave, but I'm looking for a better solution with timeline. Can you help me, please? Below is the same animation with the latest GSAP version.
  11. Another option: use an onToggle that checks the velocity and if it's adequately fast, it just forces the animation to its end with a reusable helper function like this: function finishOnFastLeave(self) { !self.isActive && Math.abs(self.getVelocity()) > 2500 && self.animation.progress(self.progress === 1 ? 1 : 0).pause(); } Usage: onToggle: finishOnFastLeave https://codepen.io/GreenSock/pen/eYWbZxN?editors=0010 No, overwrite logic runs ONCE for a tween (for performance reasons): overwrite: true - runs immediately when the animation is created - it finds all other tweens of the same target(s) and kills them in their entirety. overwrite: "auto" - runs the first time the tween renders; it isolates and kills only the conflicting individual properties in other tweens that are active at that moment. If you invalidate() a tween, then the first time it renders after that, it'll re-run the overwrite: "auto" routine at that point too. Here's another thread where we discussed several options for handling fast scrolling and overlapping scroll-driven animations (skip to the final few pots):
  12. A few quick notes: Don't use "new" like that. // BAD: let tl = new gsap.timeline({}); // GOOD: let tl = gsap.timeline(); The overwrite value should either be "auto", true, or false - not the string "true". // BAD overwrite: "true" // GOOD overwrite: true I'd strongly recommend moving to the more modern string-based ease syntax: // OLD ease: Power0.easeNone // NEW ease: "none" If you're only adding one tween to the timeline, there's no reason to use a timeline (although it'll work just fine). // LONG let tl = gsap.timeline(); tl.fromTo(...); // SHORT gsap.fromTo(...); You'll have a SIGNIFICANTLY better chance of getting a good answer here if you take the time to create a minimal demo (like a CodePen). Like in your case, I don't really understand the context and I can't see anything being overwritten. I'm left to guess by glancing at a small excerpt of code. If my assumptions are correct, you're trying to call fader() on the ".spaceman" too? Thus you've got an infinitely-repeating x/y tween and you're ALSO trying to have fader() animate it to completely different x/y values simultaneously? That's a logic issue in your code. You could pause() your spaceman animation in that case until the new animation is done and then restart it. There are many ways you could approach this, actually. Here's one: let spaceman = gsap.fromTo('.spaceman', { x: 0, y: 0 } , { x: -2, y: -5, ease: "sine.inOut", duration: 1, repeat: -1, yoyo: true }); function fader(elementName, x, y) { let vars; if (x === 'out') { vars = { x: -150, y: -30, rotation: -15, scaleX: 0.1, scaleY: 0.1, opacity: 0, duration: 2.5, transformOrigin: (y === "left") ? "top left" : "top right", ease: "power4.out" }; } else { vars = { x: 0, y: 0, rotation: 0, scaleX: 1, scaleY: 1, opacity: 1, duration: 1, transformOrigin: (y === "right") ? "top right" : "top left", ease: "power4.out" }; } if (elementName === ".spaceman") { spaceman.pause(); vars.onComplete = () => spaceman.restart(); } return gsap.to(elementName, vars); } If you still need some help, please provide a minimal demo in CodePen or something and we'd be happy to answer any GSAP-specific questions.
  13. Greetings... I have an animation that runs on load which makes my spaceman float up and down. When he gets hidden and returned that animation has been killed. Below are the 2 conflicting animations which both involve x & y. I have looked at overwrites but can't seem to get my head around it. I would like the spaceman animation to run indefinitely so whenever he is visible he is "hovering" var spaceman = new gsap.timeline({ }); spaceman.fromTo('.spaceman', { x: 0, y: 0 } , { x: -2, y: -5, ease: Power0.easeNone, duration: 1, repeat: -1, yoyo: true, overwrite: 'true' }, 2 ); function fader(elementName, x, y) { var tl = new gsap.timeline({}); if (x == 'out') { if (y == 'left') { tl.to(elementName, { x: -150, y: -30, rotation: -15, scaleX: 0.1, scaleY: 0.1, opacity: 0, duration: 2.5, transformOrigin: "top left", ease: "power4.out" }); } else { tl.to(elementName, { x: 150, y: -30, rotation: 15, scaleX: 0.1, scaleY: 0.1, opacity: 0, duration: 2.5, transformOrigin: "top right", ease: "power4.out" }); } } else { if (y == 'right') { tl.to(elementName, { x: 0, y: 0, rotation: 0, scaleX: 1, scaleY: 1, opacity: 1, duration: 1, transformOrigin: "top right", ease: "power4.out", overwrite: 'auto' }); }else { tl.to(elementName, { x: 0, y: 0, rotation: 0, scaleX: 1, scaleY: 1, opacity: 1, duration: 1, transformOrigin: "top left", ease: "power4.out", overwrite: 'auto' }); } } }
  14. Hi, I'm trying to figure out how to reposition and scale an element that has been scaled by a previous animation. The previous animation may have been completed and killed at the time the next animation is called. Overwrite appeared to work only if the animation that positioned and scaled the element previously had not been killed. In this example, I'd like to first apply new position and size attributes, and then apply a new scale. I'd like ellipse1 to end up at the position and scale of ellipse2 after the sequence is completed. Is a sequence like this best accomplished by recording several states in a different order with gsap flip, and animating to those states in the order I'd like them to be played? Thanks for your help!
  15. It all depends on what behavior you want exactly (you could build this several different ways) but I'd probably just create those tweens dynamically and set overwrite: true (or "auto"). One of the problems in the way you've got it structured is that you're pre-creating just two timelines that will lock in their starting/ending values, thus they're not dynamic. So, for example, if you scroll quickly and some of the animations are halfway done but now you want those same elements to go to a different end value that's controlled by a different animation instance which you then .restart(), the values will jump. That's not a bug - it's a logic issue in the way you've got it coded. So I'd do something sorta like: onEnter: () => { gsap.to(".targets", {..., overwrite: true}); }, onLeave: () => { gsap.to(".targets", {..., overwrite: true}); }, ... That way, it's totally dynamic and the animations will pick up exactly where the other left off.
  16. Yeah, you had !important CSS styles that were interfering. Also, you can simplify this: images.forEach((image) => { if (isEnter) { gsap.to(image, { opacity: 1, scale: 1 }); } else { gsap.to(image, { opacity: 0, scale: 0 }); } }); To this: gsap.to(images, { opacity: isEnter ? 1 : 0, scale: isEnter ? 1 : 0 }); You should also make sure to set opacity/scale to 1 right before the flip in case there's a hover animation running and things are partially-tweened. Like if you hover and then almost immediately click the button, the scale might be 0.5 at that point which could contaminate the final state you're flipping to. So do a gsap.set() with overwrite: true to make sure that other tween is killed too. If you click back and forth between the trigger and reverse buttons in @Rodrigo's demo, you'll see some odd behavior because of that. https://codepen.io/GreenSock/pen/dygzdPE?editors=0010
  17. Hey @Rodrigo, Thanks for the recommendations here! I have implemented them and everything is much smoother. My message above was about creating a lerp type of effect fpr the cards using the velocityY property - that's what that this chunk is trying to do using onUp or onDown: const posSetter = gsap.quickSetter(cards, "x", "%"); const clamp = gsap.utils.clamp(-20, 20); const lerp = [8, 16, 24]; const proxy = { x: 0 }; Observer.create({ target: cardItems, type: "wheel,touch,pointer", onUp: (self) => { let lapsedProgress; if (lapsedProgress === 1) return; lapsedProgress = scrollTl.progress() - 0.075; progressTo(lapsedProgress); const x = clamp((self.velocityY / -300) * lerp[Math.floor(Math.random() * lerp.length)]); if (Math.abs(x) > Math.abs(proxy.x)) { proxy.x = x; gsap.to(proxy, { x: 0, duration: 0.8, ease: "none", overwrite: true, onUpdate: () => posSetter(proxy.x) }); } }, }) I guess this is a better example of what i'm trying to do, but wanted to use the velocityY property: https://codepen.io/GreenSock/pen/wvMeNee?editors=0010 Do you think this is doable or should I go down the route of the above example? Here is the updated Codepen for reference: https://codepen.io/jackkemm/pen/RwearyE?editors=0011 EDIT: One thing I noticed too, on mobile/touch devices, the scroll is in the opposite direction. I have tried adding -1 to wheelSpeed and scrollSpeedfor touch devices but the scroll is still in the opposite direction. Is there a way to change this? Thanks, Jack
  18. That would create significant logic problems. Trust me - a feature like that would be a disaster. Imagine you've got a "power4.out" ease on a tween and then halfway through you call reverse() and you want it to use a "power2.in" ease in reverse. Well at 50%, the interpolation would be in a completely different place, so you'd suddenly see a jump. For example, let's say you're tweening element.x from 0 to 100. With a power4.out tween, 50% might render element.x at 94.342, but a power2.in may render it at 29.851. So at the moment of reversing, element.x would JUMP from 94.342 to 29.851. GSAP already allows for the yoyo phase of an ease to be different and that's possible because it only switches when it is all the way complete (thus the eases would render identically). See the yoyoEase property. The most common way of dealing with the situation you described where you have a menu opening animation that you don't want a true reverse on (because you're CHANGING the ease) is to dynamically create it at that time. Don't pre-bake everything into a single timeline. Sorta like: function open() { gsap.to(..., {x: 100, ease: "power2", overwrite: true}) // and all the other parts... } function close() { gsap.to(..., {x: 0, ease: "power2", overwrite: true}); // and all the other parts... } I hope that helps.
  19. Hi, Is there a way to loop a Timeline but only say from after a certain point in the original timeline. I'd like to loop an animation, but only after the initial build, so ie after the timeline is finished, restart it again at 3 seconds. I suppose I could just make two separate timelines at worst but wondered if there was a way to do this within one timeline. Thanks. //----------------------- //til = new TimelineMax(); til = new TimelineMax({repeat:3, repeatDelay:0.1}); //----------------------- til.from(root.Image_01, 2.00, {y:550, ease:Sine.easeOut, overwrite: false}, 0.0) //------------------------------ .to(root.Brand_01, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 3.0) .to(root.Tag_01, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 3.0) .to(root.Image_01, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 3.0) //------------- .from(root.Brand_02, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 3.0) .from(root.Tag_02, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 3.0) .from(root.Image_02, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 3.0) //--------------------- .to(root.Brand_02, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 6.0) .to(root.Tag_02, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 6.0) .to(root.Image_02, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 6.0) //---------------------- .from(root.Brand_03, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 6.0) .from(root.Tag_03, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 6.0) .from(root.Image_03, 0.05, {alpha:0, ease:Sine.easeInOut, overwrite: false}, 6.0) //---------------------
  20. Okay, my ignorance again is a stumbling block and buzzkill. I can't see what I'm doing wrong here but it's just looping from the start each time. til = new TimelineMax({repeat:3, repeatDelay:0.0, onComplete:playAfterBuild}); //----------------------- til.add("one", 3.5) .add("two", 6.0) .add("three", 8.5) .from(root.Image_01, 2.00, {y:550, ease:Sine.easeOut, overwrite: false}, 0.0) -- THIS IS THE ONE OFF ANIMATION THAT I DONT WANT TO REPEAT .to(root.Brand_01, 0.06, {alpha:0, ease:Sine.easeOut, overwrite: false}, "one") .to(root.Tag_01, 0.06, {alpha:0, ease:Sine.easeOut, overwrite: false}, "one") .to(root.Image_01, 0.09, {alpha:0, ease:Sine.easeOut, overwrite: false}, "one") //------------- .from(root.Brand_02, 0.06, {alpha:0, ease:Sine.easeOut, overwrite: false}, "one") .from(root.Tag_02, 0.06, {alpha:0, ease:Sine.easeOut, overwrite: false}, "one") .from(root.Image_02, 0.09, {alpha:0, ease:Sine.easeOut, overwrite: false}, "one") //--------------------- .to(root.Brand_02, 0.06, {alpha:0, ease:Sine.easeOut, overwrite: false}, "two") .to(root.Tag_02, 0.06, {alpha:0, ease:Sine.easeOut, overwrite: false}, "two") .to(root.Image_02, 0.09, {alpha:0, ease:Sine.easeOut, overwrite: false}, "two") //---------------------- .from(root.Brand_03, 0.06, {alpha:0, ease:Sine.easeOut, overwrite: false}, "two") .from(root.Tag_03, 0.06, {alpha:0, ease:Sine.easeOut, overwrite: false}, "two") .from(root.Image_03, 0.09, {alpha:0, ease:Sine.easeOut, overwrite: false}, "two"); //----------------------- function playAfterBuild() { til.play("one")// };
  21. I'll also have to read up on the overwrite: true. I hadn't come across that in my Googling, either.
  22. Yep, sorta like this: https://codepen.io/GreenSock/pen/oNaxdje?editors=1010 Better? And the reason the killTweensOf() helped is because you were creating a TON of conflicting tweens all trying to control the same properties of the same element. You could have solved it equally well by setting overwrite: true. None of that is necessary if you use the gsap.quickTo() technique.
  23. No, it's not a GSAP bug - it's a problem with your code: you keep adding more and more event listeners to the same element each time you navigate. So for example, if you go to 3 pages and then you roll over the "Fixed button", it will call 3 event handlers, firing 3 identical animations that are all fighting for control of the same properties of the same element. The best way to solve this is for you to not add a bunch of the same event handlers. Make sure you removeEventListener() when you leave the page, or add conditional logic to not add a new event handler when there's already one added. Alternatively, you could set overwrite: true or overwrite: "auto" on the tween(s) but even though that'd technically prevent conflicts, it's just masking the fundamental problem in your code. It's bad for performance to just keep stacking up more and more event handlers like that. If your user visits 30 pages, you really don't want a rollover to fire of 30 different handlers, creating 30 new animations and overwriting 29 of them. Does that clear things up?
  24. @GreenSock I would like to re-open this topic once more. On the same example, try to scroll using laptop trackpad, as using mouse it seems to be working fine. And try to do long, short scrolls. The scrollbar then goes to the end of next section, but automatically scrolls back to to top section. overwrite or autoKill seems not helping
  25. GreenSock

    Animation break

    That's because of two problems in your code: You're creating an entirely new timeline on every click and you didn't kill() the old one or set overwrite: true on your tweens, so you've got conflicting tweens (multiple running that are fighting for control of the same property of the same elements). You've created a logic problem by using .from() tweens. Remember that .from() tweens use the CURRENT value as the destination. So let's say opacity starts at 1 and you do a .from(...{opacity: 1}). That would grab the current value (0) as the destination and IMMEDIATELY set opacity to 1 and then animate back to the destination (0). Great. But what if you click again quickly and opacity is at 0.98 when you create ANOTHER .from(...{opacity: 1}) tween? That would take the CURRENT value (0.98 in this case) and use it as the destination, thus your final animation would go from 1 to 0.98 and stop! Again, this is a logic problem in your code, not a bug in GSAP. There are many, many approaches you could take to solve this. Here is one where you just create your timeline up front once, and then simply toggle the playback direction via timeScale() on each click. I'm playing it 50% faster when closing: https://codepen.io/GreenSock/pen/oNqBjoK?editors=0010 Another solution would be to avoid .from tweens. Instead, you could gsap.set() the initial values and then animate to() the destination ones. And make sure you set overwrite: true on your tweens or it may be easier to just use a variable to remember the previous timeline so you can just .kill() it before creating the new one to avoid conflicts. Good luck!
×
×
  • Create New...