Jump to content

Search the Community

Showing results for 'overwrite'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


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

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge


There are no results to display.

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start



Personal Website



Company Website



  1. Hi, The issue with overwrites is basically generated when one or more GSAP instances affect the same property (blur filter in this case), on the same element at the same time. Right now you are creating two different animations for each element before even running one of them. On top of that you are not correctly reversing all the animations, for example you move from heading-2 to heading-3. When you enter heading-2 the heading-1 element gets affected by one animation, when you move to heading-3, one heading-1 animation is reversed but as soon as you enter heading-3 another one starts while the other is still reversing. You have two different animations affecting the same property on the same element. On top of that overwrite won't help you in this case, you can test it by using this configuration in your methods: function animation_blur(elem) { const theAnimation = gsap.timeline(); gsap.set(elem, { filter: 'blur(0px)' }); theAnimation.to(elem, { filter: 'blur(5PX)', ease: 'none', duration: 0.5, overwrite: true, }); return theAnimation } function animation_blur2(elem) { const theAnimation = gsap.timeline(); gsap.set(elem, { filter: 'blur(0px)' }); theAnimation.to(elem, { filter: 'blur(20PX)', ease: 'none', duration: 0.5, overwrite: true, }); return theAnimation } You'll notice that this definitely doesn't work the way you want. Here is what overwrite does: If true, all tweens of the same targets will be killed immediately regardless of what properties they affect. If "auto", when the tween renders for the first time it hunt down any conflicts in active animations (animating the same properties of the same targets) and kill only those parts of the other tweens. Non-conflicting parts remain intact. If false, no overwriting strategies will be employed. Default: false. Since your animations affect just one property everything will be flushed out and only the animations created by the animation_blur2 method will remain and work, that's why I think the best approach is the one I suggested, as that takes the element from it's current state to the state you want (no blur, low blur or high blur). If you need to use reverse, that means that you are using an event handler for doing that, so why using a method that creates a new GSAP instance is not an option? If you want to keep the current approach you have, you have to look into reversing everything and then playing the instances you want, but you already ran into some logic issues with your code. Based on the Codepen example you gave us I provided a solution for the issue I saw there which should be scalable into a larger setup without too much problems. If you keep having issues, let us know. Happy Tweening!
  2. Hey @Rodrigo - thanks for your response! I appreciate the new approach that you suggested, but I am looking for a solution that still uses .reverse() on mouseleave. (My original codepen is kind of a boiled down example of something more complicated that I'm working on). You mentioned that I'm running into "overwrite issues" - do you think that this is the core issue that I'm facing in my original codepen? Could you possibly expand on overwrite issues? Is there any documentation on overwrite issues? Any ways to combat overwrite issues from occurring? Thanks again!
  3. Hi, i'm not exactly sure what effect you are going for. FWIW it seems a bit disorienting to move something down to a y:200 while scrolling up. That aside I would avoid creating 2 timelines initially time that control the same properties of the same thing. To avoid conflicts I would suggest creating these animations fresh when you need them inside your callbacks sort of like: ScrollTrigger.create({ trigger: ".top-page", start: "top-=100 top", end: "top+=200 top", markers: true, onEnter: () => {let tl1 = gsap.timeline({}) .fromTo("header", { y: 0, overwrite: 'auto' },{ duration: 2, y: 200, ease: CustomEase.create("custom", "0.5, 0, 0, 1"), overwrite: 'auto' })}, onLeaveBack: () => {let tl2 = gsap.timeline({}) .to("header", { scale: 1.2, y: 200, }) .set("header", {y: 200,scale: 1,},"hide") .to("header", {opacity:1},"start2") .to(("header"), { y: 0, duration: 1, ease: "power4.out" }, "start2")} }); I would also remove locomotive scroll until you know things are working fine without it. Hopefully this set up will allow you to remove some of redundancy between the 2 animations like tweening and setting y:200 multiple times. If you need more help please try to simplify the animations as much as possible in a fork of the original pen.
  4. Have you ever been in a situation with GSAP where you needed a higher level of control over conflicting tweens? If you’re just creating linear, self-playing animations like banner ads, chances are the default overwrite mode of false will work just fine for you. However, in cases where you are creating tweens dynamically based on user interaction or random events you may need finer control over how conflicts are resolved. Overwriting refers to how GSAP handles conflicts between multiple tweens on the same properties of the same targets at the same time. The video below explains GSAP’s overwrite modes and provides visual examples of how they work. Want to master GSAP? Enroll in CreativeCodingClub.com and unlock 5 premium GreenSock courses with over 90 lessons. New lessons like this one are added weekly to keep your learning fresh. GSAP’s 3 Overwrite Modes false (default): No overwriting occurs and multiple tweens can try to animate the same properties of the same target at the same time. One way to think of it is that the tweens remain "fighting each other" until one ends. true: Any existing tweens that are animating the same target (regardless of which properties are being animated) will be killed immediately. "auto": Only the conflicting parts of an existing tween will be killed. If tween1 animates the x and rotation properties of a target and then tween2 starts animating only the x property of the same targets and overwrite: "auto" is set on the second tween, then the rotation part of tween1 will remain but the x part of it will be killed. Setting Overwrite Modes // Set overwrite on a tween gsap.to(".line", { x: 200, overwrite: true }); // Set overwrite globally for all tweens gsap.defaults({ overwrite: true }); // Set overwrite for all tweens in a timeline const tl = gsap.timeline({ defaults: { overwrite: true } }); Below is the demo used in the video. Open it in a new tab to experiment with the different overwrite modes See the Pen overwrite demo by SnorklTV(@snorkltv) on CodePen. Hopefully this article helps you better understand how much control GSAP gives you. Overwrite modes are one of those features that you may not need that often, but when you do, they can save you hours of trouble writing your own solution. For more tips like this and loads of deep-dive videos designed to help you quickly master GSAP, check out CreativeCodingClub.com. You’re going to love it.
  5. I saw a few problems: You're setting the width/height in the same gsap.set() call as the transformOrigin, and in this very rare edge case that's actually a problem because it just so happens that in the for...in loop through the properties, transformOrigin happens BEFORE the width/height. So when it tries to calculate the percentage-based origin offsets, your <rect> literally has no width or height at all, thus it gets positioned in its upper left corner. The solution: set the width/height FIRST. You could just separate those out into their own gsap.set() that you put first. You're creating conflicting animations. If you click again before the first set of animations completely finishes their 4 repeats, you'll be creating new ones that are also fighting with the old ones for control of the same elements. Make sure you kill() the old animations before you create new ones. Or you can just leverage the overwrite feature (overwrite: true here). Just so you know, the smoothOrigin does absolutely nothing in this line: gsap.timeline({ smoothOrigin: true, yoyo: false, repeat: 4 }); Timelines don't have a property like that. Maybe you intended to pass that down as a default for all child tweens?: gsap.timeline({ defaults: {smoothOrigin: true}, yoyo: false, repeat: 4 }); https://codepen.io/GreenSock/pen/NWBaLOd?editors=0010 Does that clear things up?
  6. Hi @Roman S. is you're issue that your elements are not obeying the width you've set? That is because flexbox is trying to 'help', flexbox will automatically distribute the elements over the width you've given it. You can overwrite that using the flex-grow, flex-shrink and flex-basis property or the short hand flex: 0 0 "your width". You're right that this is a CSS issue and we like to focus these forums to just GSAP related questions. Still hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/GRXOvgo?editors=0110
  7. Nice job, @Toso 👍 Minor tweaks: https://codepen.io/GreenSock/pen/KKxXjvW?editors=0010 I'd use backgroundColor rather than background, and I'd set the overwrite to either true or "auto" just in case the user rolls over/out quickly, you don't want to create conflicting animations.
  8. Hi @aileen-r and welcome to the GreenSock forums! The reason for the different speed is beacuse you're setting the timescale of each animation on the mouse leave event to be 2 and is never reset to 1, that's why is faster after the first mouse over event. If you want to keep the same speed on both events just remove that and make the duration of the animation half the current time: reactions.forEach(reaction => { const action = gsap.to( reaction, { scale: 1.2, margin: '0 30px 0 20px', duration: 0.25, ease: 'power2.inOut', overwrite: 'true', paused: true } ); reaction.addEventListener("mouseenter", function() { action.play(0); }); reaction.addEventListener("mouseleave", function() { action.reverse(); }); }); Now if you still want the leave animation to be faster, then keep the timescale setter on the mouse leave, but add one to the mouse enter as well: reactions.forEach(reaction => { const action = gsap.to( reaction, { scale: 1.2, margin: '0 30px 0 20px', duration: 0.25, ease: 'power2.inOut', overwrite: 'true', paused: true } ); reaction.addEventListener("mouseenter", function() { action.timeScale(1).play(0); }); reaction.addEventListener("mouseleave", function() { action.timeScale(2).reverse(); }); }); You can learn more about timeScale here: https://greensock.com/docs/v3/GSAP/Tween/timeScale() Finally if you want to prevent the bounce effect in the reactions container, that's a bit more tricky since you need to get the current active element check in the array, see if there are elements before and move all those a specific amount of pixels and do the same for the elements after the active one. Finally when leaving the reactions container tween all the reactions back to their original x position. Avoid using margins for this if you can for that scenario. But I must say as a user I would be totally fine with the way things are, just speed up the animation and keep the timescale, no need to change it IMHO. Hopefully this helps. Let us know if you have more questions. Happy Tweening!
  9. Hi guys! I come humbly in front of you with few drops of hope left, after 5 full days of switching between possible solutions to get a consistent ScrollTrigger behavior on a Gatsby site. Getting directly to you is my last resort, as every google and gsap forum link regarding ScrollTrigger and Gatsby is already visited. 😒 I cannot get a CodePen reproducing the exact issue so I'll try my best to describe it here. Shortly, the problem seems to be, as I suspect, that the ScrollTrigger does not refresh itself when Javascript pops into the browser on top of the SSR-ed html/css bundle. Here's what i did. I created several projects with different versions for dependencies, but i will stick to the simplest one with all dependencies up to date.It's a gatsby with material-ui plugin added, who's exact structure can be found here: https://github.com/mui-org/material-ui/tree/master/examples/gatsby There are no other plugins added, nor any other configs/plugins changed. I rendered the component that will contain the ScrollTrigger (AboutBlock) in the AboutPage page: about.js const AboutPage = () => { return ( <AboutBlock /> ) } export default AboutPage This is the component where i try to animate some elements on reveal when scrolled into view: aboutBlock.js import gsap from "gsap"; import ScrollTrigger from 'gsap/ScrollTrigger'; import animateReveal from "./gs_reveal"; export default function AboutBlock() { gsap.registerPlugin(ScrollTrigger) const revealRefs = useRef([]) revealRefs.current = [] useLayoutEffect(() => { let scrollTriggers = [] scrollTriggers = animateReveal(revealRefs.current) return () => { scrollTriggers.forEach(t => t.kill(true)) } }, []); const addToRevealRefs = el => { if (el && !revealRefs.current.includes(el)) { revealRefs.current.push(el); } }; return ( <Grid container> <Grid item width={{ xs: '100%', sm: '80%', md: '35%' }} pl={{ xs: 0, md: '2.5%' }} mt={{ xs: 60, sm: 0 }}> <Grid container direction="column" alignItems={{ xs: "flex-start", sm: "flex-end" }}> <Grid item mt={{ xs: 0, md: '10vh' }} id="acum"> <Typography variant="h5" textAlign={{ xs: "left", sm: "right" }} ref={addToRevealRefs} className='gs_reveal_fromRight'> NOW WE ARE IN </Typography> </Grid> <Grid item> <Typography variant="h6" textAlign={{ xs: "left", sm: "right" }} ref={addToRevealRefs} className='gs_reveal_fromRight'> LOCATION </Typography> </Grid> <Grid item mt="10vh" id="hi"> <Typography variant="h5" textAlign={{ xs: "left", sm: "right" }} ref={addToRevealRefs} className='gs_reveal_fromRight'> SAY HI </Typography> </Grid> <Grid item className='toughts'> <Typography variant="h6" textAlign={{ xs: "left", sm: "right" }} ref={addToRevealRefs} className='gs_reveal_fromRight'> TELL US YOUR THOUGHTS </Typography> </Grid> </Grid> </Grid> </Grid> } HTML is longer and crowded, I left a part to get the idea of the structure and styling approach (MUI's sx - emotion). And finally, this is the animateReveal function: gs_reveal.js import ScrollTrigger from 'gsap/ScrollTrigger'; import gsap from 'gsap'; export default function animateReveal(elements) { const triggers = [] elements.forEach(function (elem) { hide(elem) let tr = ScrollTrigger.create({ trigger: elem, id: elem.id, end: 'bottom top', markers: true, onEnter: function () { animateFrom(elem) }, onEnterBack: function () { animateFrom(elem, -1) }, onLeave: function () { hide(elem) } }); triggers.push(tr) }); return triggers; } function animateFrom(elem, direction) { direction = direction || 1; let x = 0, y = direction * 100; if (elem.classList.contains("gs_reveal_fromLeft")) { x = -100; y = 0; } else if (elem.classList.contains("gs_reveal_fromRight")) { x = 100; y = 0; } else if (elem.classList.contains("gs_reveal_fromBelow")) { y = -100 } elem.style.transform = "translate(" + x + "px, " + y + "px)"; elem.style.opacity = "0"; gsap.fromTo(elem, { x: x, y: y, autoAlpha: 0 }, { duration: 1.25, x: 0, y: 0, autoAlpha: 1, ease: "expo", overwrite: "auto", delay: elem.classList.contains("gs_delay") ? 0.3 : 0, }); } function hide(elem) { gsap.set(elem, { autoAlpha: 0 }); } The ScrollTrigger markers are misplaced when page loads, and might move (get more misplaced) on hard reloading page, depending on the current scroll position in the moment of reloading, even though the scroll position is not preserved on reload (always is scrolled on top). - The markers are placed on the correct position on resizing, as expected. I followed gsap official docs on react and react-advanced and tried: grabbing the html elements to animate on scroll inside animateReveal() by let elements = gsap.utils.toArray(".gs_reveal"); Assigning to each element a useRef() and use the .current value for each in animateReveal() grabbing html elements using gsap's selector utility gsap.utils.selector changing to simpler animation on scroll, like just a fade refreshing ScrollTrigger in different moments useLayoutEffect(() => { ScrollTrigger.refresh(true) // or ScrollTrigger.refresh() ... }, []); 6. Lifting ScrollTrigger logic to parent about.js page 7. Assigning scrollTrigger to a timeline triggered by the to-be-reveal element 8. Use useEffect() instead of useLayoutEffect() (recommended anyway for ScrollTrigger) 7. Other who-knows-what unsuccessful twists. I suspected a rehydration error, when the static generated code does not match the client side one. But the only JS that could cause a mismatch is the gsap related one, and it does not seem an SSR issue. I checked if the CSS and HTML elements are being properly SSR-ed, by preventing JS from running in the browser. All looking fine. This is both a SSR issue (gatsby build) and a development issue (no SSR). As i said on point 5, setting a ScrollTrigger.refresh() when component is mounted does not work, but delaying this with a 1-2 seconds in a setTimeout successfully solves the issue useLayoutEffect(() => { setTimeout(() => { ScrollTrigger.refresh(true) }, 2000); }, []); This is hard to be accepted as a solution, since i cannot rely on a fixed value to 'guess' when DOM is properly rendered in the eyes of the ScrollTrigger, not to mention the glitches that might occur. So, the question is 'WHY?', why animating with ScrollTrigger from within useLayoutEffect, which is not triggered on the server anyway and should mark the 'component is successfully mounted' moment, seems to not wait for the DOM being completely painted, even though nothing is generated dynamically! There are quite of threads on this forum regarding gatsby, and none seemed to have a clear cause-outcome-solution. Is this battle lost, should i move on? Do you have any suggestions? Thanks so much for your time reading this, it means so much to me!
  10. Yes you can! Like you do with CSS you can call all your elements at once and then use a stagger (see Stagger docs) to have them animate in one by one. Then when using a smart position parameter we can start the next animation right after the first one is done! Also you can target all transform properties directly with GSAP x, y, rotate, skew, scale ect and if you want to use percentage based values use xPercent and yPercent. I would also recommend keeping all he animation values to GSAP instead of setting something with in CSS that you then need to overwrite with GSAP, that is where .from() is really handy. I've sprinkled a lot of useful comments throughout your pen to explain certain parts, be sure to read through them! Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/GRXmQqV?editors=0100 Oh and a side note! When working with ScrollTrigger I like to disable it, to really focus on just the animation I find it a lot easier. I've also added a repeat: -1, so be sure to remove those when you're going to enable ScrollTrigger again.
  11. Hello, i have tried the official codepen demo with the horizontalLoop: https://codepen.io/GreenSock/pen/gOvvJee Thanks for this awesome slider. But I run in some troubles with the dragging. I could fix some problems by myself but with 1 problem i have my troubles Scenario: - Open the page and drag much, so the slider its moving. - When it comes nearly to the end (but it has not stopped yet) please press the active button with the white boarders. - It now jumps a lot. Do you know why? Thanks a lot! Other bugs i could solve (but its ugly 😞 Scenario 1: - Open the page and drag just some pixels on the active button (Button number3) and release the mouse. - Then click a few times on the button 3. - Now it jumps some boxes. I tried to fix it in the "toIndex" function before line 150. It works better. vars.overwrite = true; if (index === curIndex) { return; } curIndex = newIndex; gsap.killTweensOf(proxy); return tl.tweenTo(time, vars); Scenario 2: - Drag a lot, so that the slider is moving. - While the slider is moving please press the "wrapper" (the grey lines above or below the boxes) - Now it jumps a loooot. I fixed this with adding a new var isNowDragging (true when the user drags) and change line 182. Seems to work now. if (!isNowDragging) {gsap.set(proxy, {x: startProgress / -ratio});} Thanks a lot for your help.
  12. Hello all, So in this codepen example I use Flip.from to get items into grid slots, and then on another flip to get them back in old parent, but also to transform each item to value I set with gsap.set. This works too, but on 3rd click, when I want to animate items again into grid, the gsap.set doesnt set xPercent value back to 0. I also tried overwrite: true but it didnt work. Is there something Im missing? Thanks
  13. Hi, I've been fiddling with your codepen example for a bit and this seems to do the trick: ScrollTrigger.create({ trigger: ".images", start: "center top", markers: true, onEnter: self => { let state = Flip.getState(images); images.forEach((image, i) => slots[i].appendChild(image)); gsap.set(images, {xPercent: 0, rotation: 0}); Flip.from(state, { duration: 6, overwrite: true, // <- HERE ease: "power1.inOut" }) } }) Since the first ScrollTrigger instance you're creating for the images has once: true, it doesn't really matter if the Flip animation overwrites those. In the tests that I've ran seems to work as expected: https://codepen.io/GreenSock/pen/ZEMeBKR Hopefully this helps. Let us know if you have more questions. Happy Tweening!
  14. The live example you have and the demo you provided don't use either Draggable or the Inertia Plugin, so you can set the draggable option to false: let carousel = buildCarousel(items, { radiusX: 250, radiusY: 210, activeAngle: -90, draggable: false, onClick(element, self) { self.to(element, {duration: 1, ease: "power1.inOut"}, "short"); }, onActivate(element, self) { element.classList.add("active"); }, onDeactivate(element, self) { element.classList.remove("active"); }, // when a drag or animation starts (via the Carousel's to()/next()/previous() methods) onStart(element, self) { gsap.to(descriptions[items.indexOf(element)], {autoAlpha: 0, duration: 0.25, overwrite: "auto"}); }, onStop(element, self) { gsap.to(descriptions[items.indexOf(element)], {autoAlpha: 1, overwrite: "auto"}); } }); If you want to use the example with the red circles you can just offset the start and endpoints by minus 25%: gsap.set(items, { motionPath: { path: circlePath, align: circlePath, alignOrigin: [0.5, 0.5], start: -0.25, end: i => (i / items.length) - 0.25, }, scale: 0.9 }); The rest of the code should remain the same. Yet another option with the latter example (red dots) is to set the start point of the path to the top of the circle. Check this article by @PointC https://www.motiontricks.com/cut-your-path-start-points-in-adobe-illustrator/ Hopefully this helps. Happy Tweening!
  15. That's because you created conflicting animations - you've got your motionPath animation first in the timeline that controls the x/y position, and then you ALSO have another one that's affecting x to go in a completely different direction. So they're both fighting for control. If you do overwrite: "auto" (or true), all that does is basically KILL the overwritten part (so of course you won't see it affecting things after that point at all). You definitely should not be creating conflicting animations like that. The reason it looks different when scrolling forwards vs backwards is because the rendering order inverts in reverse. In other words, when moving the playhead forward, the LATER tween would render last whereas when moving the playhead backwards, the EARLIER tween would render last. That's exactly how it's supposed to work. Possible solutions: Don't overlap the animations. https://codepen.io/GreenSock/pen/dyqNQRR?editors=1010 Use a different (invisible) motionPath that has the shape you want. Basically copy the path you have now, but add that extra part at the top that's curved in the way you want your objects to travel. You can still leave the red stroked path as-is. Everything would look the same visually, but you'd just use one motionPath tween where the path actually has the shape you're going for. You technically could write a bunch of extra JavaScript to force things to render in a particular order no matter which direction the playhead travels, but honestly that seems quite hacky and unintuitive to me. It is doable, though. If you need help with that, we're available for paid custom consulting - just reach out directly to explore those options. I hope that helps!
  16. It looks like you just had your toggleActions wrong: // BAD toggleActions: "play none reverse none" // GOOD toggleActions: "play none none reverse" And this is not a valid start value: // invalid start: "-=200top top" I'm not sure if you meant "top top" or "200 top" or something else. But actually, if I were building this I'd approach it in a very different way: Put the color/backgroundColor into a data-color attribute on any element that I want to have this effect (a space-delimited value like "blue white") Grab all the elements that have that data-color attribute, loop through them and create a ScrollTrigger for each. When it activates, create a new tween that animates to its colors. Here's a demo with my strategy implemented: https://codepen.io/GreenSock/pen/OJoROgY?editors=0010 Benefits: You can easily add as many sections as you want - just slap a data-color value on it in the markup and BOOM, it works. It works more smoothly if you scroll very quickly. With your previous strategy, you had one animation for each section, and you were calling play()/reverse() on them when necessary...but they were controlling the same properties of the same object. Imagine a scenario where the user scrolls quickly, so one animation starts and is midway through when the other animation gets triggered. Now you've got two animations fighting for control of the same properties. Plus you may see a jump because let's just say (to make it simpler) we're animating a number from 0 to 100 in the first one, and 100 to 200 in the second animation. If the first animation is at 50 when the second one starts playing, you'd see it jump from 50 to 100 instantly (and go to 200). With my strategy above, a new tween gets created each time so that it's just taking the value from whatever it currently is to the new value. So everything is perfectly smooth every time. No fighting for control (it has overwrite: "auto"), no overlapping. I hope that helps.
  17. Hi all, In the CodePen I've set up a basic toggle that opens and closes a div. As part of the animation, the padding also expands from 0px to 20px. The 20px is however currently hard coded. What's the best way to store the divs original padding and refer to this for future animations? As currently if for example the button is toggled before the animation completes, the padding would return for example 10px if it wasn't hard coded. I was wondering if gsap had any way to store such properties? Or just storing it in a data attribute on the div is a fine solution.
  18. we can play animations when we click on the Nav "Slides 1 2 3..." and i want it to start as Slides[0] index array element that is Slide A as already Played or Finished animation, and then we can click on Nav slides to play the animation the issue im having is, i want when i click on Slide 2 3 4 or 5 it should Overwrite gsap.set property Slides[0] by GSAPSlideTL or in other words Slides[0] is not working when click animation to play GSAPSlideTL thank you
  19. Hi, In the animation, overwrite: true is not working with mask animation, works fine on other normal tweens. Works fine once animations are finished. Thanks for your help, always appreciated.
  20. Hi @Fabian W and welcome to the GreenSock forums! First thanks for being a Club GreenSock member and supporting GSAP! 🥳 What you are looking for is the invalidateOnRefresh configuration option in the ScrollTrigger configuration object: Boolean - If true, the animation associated with the ScrollTrigger will have its invalidate() method called whenever a refresh() occurs (typically on resize). This flushes out any internally-recorded starting values. https://greensock.com/docs/v3/GSAP/Tween/invalidate() This seems to work the way you intend: let t1 = gsap.to(c1, { scrollTrigger: { scrub: true, start: () => 0, end: () => 'max', markers: true, invalidateOnRefresh: true,// <- HERE }, y: () => document.body.clientHeight - c1.clientHeight, ease: 'none', overwrite: 'auto' }); let t2 = gsap.to(c2, { scrollTrigger: { scrub: true, start: () => 0, end: () => 'max', markers: true, invalidateOnRefresh: true,// <- HERE }, y: () => document.body.clientHeight - c2.clientHeight, ease: 'none', overwrite: 'auto' }); Hopefully this helps. If you have more questions let us know. Happy Tweening!
  21. Hi, Maybe you should take a look at ScrollTrigger's batch method: https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.batch() Here is a live example: https://codepen.io/GreenSock/pen/NWGPxGZ In the case of your last codepen example it would be as simple as this: gsap.registerPlugin(ScrollTrigger); gsap.set(".grid-i", {y: 50, opacity: 0}); ScrollTrigger.batch(".grid-i", { onEnter: batch => gsap.to(batch, {opacity: 1, y: 0, stagger: 0.15, overwrite: true}), }); Hopefully this helps. Let us know if you have more questions. Happy Tweening!
  22. @GreenSock How do I use this but with a scrolltrigger? I need to animate items per row, but it seems that when I use the row as a trigger it doesn't work. This is what I added to it: ``` rows.forEach((GridItems) => { let tl = gsap.from(GridItems, {opacity: 0, yPercent: 80, stagger: 0.05, duration: 0.7, overwrite: true}); ScrollTrigger.create({ trigger: GridItems, start: 'top 70%', end: 'bottom bottom', markers: true, onEnter: () => tl.play(), onEnterBack: () => tl.restart(), onLeaveBack: () => tl.pause(0), }); });
  23. How do I overwrite scrollTrigger with an other timeline that also scrollTo the element on click, but keep the scrollTrigger alive to use the `onLeave` trigger? I have a page with videos and on scrollTrigger enter the videos should play and scale a bit (✅ working), but then when the user clicks the video should scale to 100% (❌ not working). I've set the property `overwrite: true` on the time line, but that doesn't seem to work in combination with scrollTrigger. In my demo you can see an orange box that scales to 100% on click, the video tries to do the same, but is taken over by the scrollTrigger timeline which I want to overwrite. I've tried killing all the scrollTriggers, but I need the `onLeave` trigger for when the user scrolls away again, so I can scale the video back and pause the video
  24. Hello @amitr95 I think the problems you are having might just be related to the general processing of the code's logic you run inside your function, and not really to GSAP measuring the height incorrectly. Here is an approach, that is a bit different on the logic side of things, which works fine for me with regard to the height. I also added overwrite: 'auto' to the tweens, so GSAP can sort out conflicting tweens that might be created along the way. [Note: this approach is not meant to be 100% bullet-proof. It is mainly to show, that the height gets tweened to the proper value.] https://codepen.io/akapowl/pen/VwBqJmj Edit: Since getting the logic right for something like this can become a bit tricky, here's another example of your setup, using an approach by OSUBlake - which works a lot better. Hope that will help. https://codepen.io/akapowl/pen/BaPvXQM Based on this demo. https://codepen.io/osublake/pen/JYQqZr
  25. I'm not completely sure what you're asking. But I think your problem is that you have one element that is controlled by two ScrollTriggers and they will fight for control if the first one is not yet done and the other one is starting, so you either have to make sure the other one is done when the next one starts or make it one big ScrollTrigger that just triggers over the whole duration (this seems like the easiest solution) https://codepen.io/mvaneijgen/pen/GRBPbgr?editors=1010 You could also look in to the overwrite property https://greensock.com/docs/v3/GSAP/Tween/vars If true, all tweens of the same targets will be killed immediately regardless of what properties they affect. If "auto", when the tween renders for the first time it hunt down any conflicts in active animations (animating the same properties of the same targets) and kill only those parts of the other tweens. Non-conflicting parts remain intact. If false, no overwriting strategies will be employed. Default: false.