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, Scrolltrigger version 3.11.3 (and probably older versions too) save the history.scrollRestoration value at the beginning and it seems it's not possibile to overwrite that value later: _scrollRestoration = _win.history.scrollRestoration || "auto"; Then the stored value is applied again every clearScrollMemory call: _isString(scrollRestoration) && (_win.history.scrollRestoration = _scrollRestoration = scrollRestoration); Even setting history.scrollRestoration to manual at the beginning of my script, due to Webpack bundle, the Scrolltrigger code is extecuted before mine. In my case I need to set the scrollRestoration to manual because I use Barba.js Is there a way to do it? Am I missing something?
  2. Hi @dhdbtkd welcome to the forum! By default ScrollTrigger selects the the body (or HTML) as the scroll element, eg the element that normally scrolls. If you want to overwrite that, you'll have to define what element is the scroller in your case scroller: ".myScroller", for it to work. (I gave your element a class of myScroller) String | Element - By default, the scroller is the viewport itself, but if you'd like to add a ScrollTrigger to a scrollable <div>, for example, just define that as the scroller. You can use selector text like "#elementID" or the element itself. Read more on the docs https://greensock.com/docs/v3/Plugins/ScrollTrigger https://codepen.io/mvaneijgen/pen/JjZEyVo Personally I wouldn't overwrite the normal browser behavior if you don't have a clear use case for it. In your case you can just set the header and footer to position: fixed; and have the browser behave like it normally does, but that is just my opinion. Hope it helps and happy tweening!
  3. 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
  4. 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 })
  5. @Isla that is correct, bootstrap will apply a lot of CSS to your layout. You either have to overwrite that or write your own logic for this particular block of content. It's really important how you build your layout if you want to animate it and with bootstrap this is not something you get great control over, because it will imply that you want everything underneath each other on mobile.
  6. 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!
  7. Hi all. I have been tasked my by company to revamp our site. We have designs and a concept for a single-page site that makes use of animations tied to scroll progress. GSAP and Scrolltrigger has been amazing for this so far. At this point I have the full animation orchestrated from the top to the bottom of the page. Scrolling at a reasonable speed results in the desired effect. However scrolling too quickly or jumping to certain points on the page results in elements ending up in places where they shouldn't be. The animation is quite a complex one when all put together. It involves the same elements being animated multiple times, as they move around the page while scrolling. I've divided the single-page into various sections, and have a separate timeline that handles each section. I'm unable to share a full codepen as I'm not allowed to share certain information such as our assets, but I have included code below that I hope adequately shows my approach. I've tried various solutions suggested already on this forum, including: setting "immediateRender" and "overwrite", using only fromTo's, relative vs absolute values. I think that my mistake lies in my approach to the task, I believe I'm not employing the optimal practices in order to complete a complex animation of this nature. useEffect(() => { gsap.registerPlugin(ScrollTrigger); planetFloat(); landingPhase(); discoverPhase(); discussPhase(); decidePhase(); }, []); export const landingPhase = () => { gsap .timeline({ scrollTrigger: { trigger: ".scroll-trigger", start: "10% bottom", end: "+=2000", scrub: 0.25, }, }) // Move landing text off screen .to(".landing-text", { opacity: "-=1", x: "+=300", }) // Bring greatness text onto screen .fromTo( ".greatness-text", { autoAlpha: 0, x: -300 }, { autoAlpha: 1, x: 0, }, ">-50%" ) // Scale up discover system .fromTo( ".discover-system", { opacity: 0, scale: 0 }, { opacity: 1, scale: 1, }, // ">-60%" "<" ) // Telescope ledge rises into view .fromTo( ".telescope", { y: 350 }, { y: 0, }, // ">-60%" "<" ) // Greatness text descends below telescope ledge .to( ".greatness-text", { opacity: "-=1", y: "+=550", }, ">100%" ) // Journey text descends into view .fromTo( ".journey-text", { y: -550, autoAlpha: 0 }, { y: 0, autoAlpha: 1, }, ">-70%" ) // Beginning of system rearrange --> .to( "#moon-container", { x: "-=50", y: "-=100", scale: "-=0.7", overwrite: true }, ">100%" ) .to( "#galaxy-swirl-container", { x: "-=400", y: "+=50", rotate: 7, scale: "+=0.4", overwrite: true }, "<" ) .fromTo("#sun-container", { scale: 0 }, { scale: 0.3 }, "<") .to( "#ringed-planet-container", { x: "-=500", y: "+=100", overwrite: true }, "<" ) .fromTo("#red-planet-container", { scale: 0 }, { scale: 1 }, "<") .fromTo("#darkBlue-planet-container", { scale: 0 }, { scale: 1 }, "<") .to( "#lightBlue-planet-container", { x: "-=160", y: "+=240", scale: "+=0.5", overwrite: true }, "<" ) .to( "#dark-planet-container", { x: "+=50", y: "-=150", scale: "-=0.5", overwrite: true }, "<" ) .to( "#turquoise-planet-container", { x: "-=260", y: "+=60", scale: "+=1.5", overwrite: true }, "<" ) // <-- Ending of system rearrange // Telescope ledge zooms out of view .to( ".telescope", { y: "+=500", x: "-=800", }, "<" ) // Journey text zooms out of view .fromTo( ".journey-text", { y: 0, x: 0, }, { y: 500, x: -800, }, "<" ); }; export const discoverPhase = () => { gsap .timeline({ scrollTrigger: { trigger: ".scroll-trigger", start: "25% bottom", end: "+=2000", scrub: 0.25, }, }) // Phase 1 text moves in from the right .fromTo(".phase1-text", { x: 1500 }, { x: 1200 }, "") // Discover text fades in .fromTo( ".discover-text", { autoAlpha: 0, scale: 2.5 }, { autoAlpha: 1, scale: 2.5 }, "<" ) // Phase 1 text moves over the screen .to(".phase1-text", { x: "-=135%" }, ">100%") // Beginning of system rearrange --> .to( "#galaxy-swirl-container", { rotate: -15, x: "+=300", scale: "-=0.4", overwrite: true }, ">-50%" ) .to( "#sun-container", { x: "+=250", y: "+=25", scale: "-=0.05", overwrite: true }, "<" ) .to("#moon-container", { x: "+=250", overwrite: true }, "<") .to( "#lightBlue-planet-container", { x: "+=200", y: "-=50", scale: "-=0.5", overwrite: true }, "<" ) .to( "#dark-planet-container", { x: "+=200", y: "+=25", scale: "-=0.1", overwrite: true }, "<" ) .to( "#turquoise-planet-container", { x: "+=200", y: "-=75", scale: "-=0.5", overwrite: true, }, "<" ) .to( "#red-planet-container", { x: "+=400", y: "+=50", overwrite: true }, "<" ) .to( "#darkBlue-planet-container", { x: "+=400", y: "+=50", overwrite: true }, "<" ) .to( "#ringed-planet-container", { x: "+=450", scale: "-=0.2", overwrite: true }, "<" ) // <-- Ending of system rearrange // Discover text moves away with system .to( ".discover-text", { rotate: -25, x: "+=450", scale: "-=0.6", opacity: "-=1" }, "<" ) // Curiosity header text slides in .fromTo( ".curiosity-header-text", { x: -700, }, { x: 0 }, "<" ) // Curiosity paragraph 1 text slides in .fromTo( ".curiosity-paragraph1-text", { x: -700, }, { x: 0 }, ">-70%" ) // Curiosity paragraph 2 text slides in .fromTo( ".curiosity-paragraph2-text", { x: -700, }, { x: 0 }, ">-70%" ) // Beginning of system rearrange --> .to( "#lightBlue-planet-container", { x: "-=500", y: "+=500", scale: "+=15", overwrite: true, }, ">200%" ) .to( "#turquoise-planet-container", { x: "-=825", y: "+=30", scale: "+=1.5", overwrite: true, }, "<" ) .to( "#ringed-planet-container", { y: "-=50", x: "-=50", scale: "+=1", overwrite: true, }, "<" ) .to( "#red-planet-container", { x: "-=1500", opacity: "-=1", overwrite: true, }, "<" ) .to( "#darkBlue-planet-container", { x: "-=1500", opacity: "-=1", overwrite: true, }, "<" ) .to( "#dark-planet-container", { x: "-=900", y: "-=150", scale: "+=0.5", overwrite: true, }, "<" ) .to( "#moon-container", { y: "-=0", x: "-=200", scale: "+=0.5", overwrite: true, }, "<" ) .to( "#galaxy-swirl-container", { x: "-=1500", opacity: "-=1", scale: "+=10", overwrite: true, }, "<" ) .to( "#sun-container", { opacity: "-=1", x: "-=1500", y: "-=200", scale: "+=2", overwrite: true, }, "<" ) // <-- Ending of system rearrange // Curiosity header text moves off screen .to( ".curiosity-header-text", { x: "-=700", }, "<" ) // Curiosity paragraph 1 text moves off screen .to( ".curiosity-paragraph1-text", { x: "-=700", }, "<" ) // Curiosity paragraph 2 text moves off screen .to( ".curiosity-paragraph2-text", { x: "-=700", }, "<" ) // Phase 1 text moves off screen .to( ".phase1-text", { x: "-=1000", }, "<" ) // Discuss text fades up and in .fromTo( ".discuss-text", { autoAlpha: 0, scale: 0, y: 500, }, { autoAlpha: 1, scale: 2.5, y: 0, }, ">-50%" ) // Phase 2 texts slides on screen .fromTo( ".phase2-text", { x: -1700, }, { x: -800, }, "<" ); };
  8. I've been tinkering with it a bit, but I don't want to judge wether this is a bug or not. One thing I found is that if you do not set box-sizing: border-box inline (as in 1.: deactivate it via dev-tools or 2.: alternatively overwrite/clear it in a refresh callback and refresh the smoother instance) on the pin-spacer of the first ScrollTrigger it appears to work as intended by @thei. Maybe this can serve as a workaround for now and if this atually is a bug, help find the root of the problem. Works for me in both, the OPs codepen and @Cassie simplified demo. https://codepen.io/akapowl/pen/rNvJXbd https://codepen.io/akapowl/pen/xxjWxRV
  9. import React from "react"; import "./FollowImage.css" import gsap from "gsap"; import Image from "react-bootstrap/esm/Image"; function FollowImage (){ let FollowBox = "#Wrap .FollowBox"; gsap.set(FollowBox, { xPercent: 1, yPercent: 1, scale: 0 }); const MyDiv = document.getElementById('Wrap') function clamp(num, min, max) { return num <= min ? min : num >= max ? max : num } window.addEventListener("mousemove", (e) => { gsap.to(FollowBox, { duration: 0.5, overwrite: "auto", x: clamp(-100+e.clientX - e.target.offsetLeft,-50,150), y: clamp(-100+e.clientY- e.target.offsetTop,0,150), stagger: 0.15, ease: "none" }); }); return ( <div id="Wrap"> <Image id="FollowBox" className="FollowBox" src="1000x600(mykhaylo).png" alt="" /> <Image className="FollowBox" src="1000x600(music).png" alt="" /> </div> ) } export default FollowImage; This is my current code, so far I failed to translate it for codepen.
  10. Can you let me know exactly what the box animation is doing? If it's simple I'd probably just tween it dynamically and use overwrite modes instead of a timeline?
  11. Or maybe? https://codepen.io/GreenSock/pen/bGvOKMw?editors=0010 You were using the circle itself as the trigger element which is an issue because that trigger is moving, Also scrollTriggers are immediately rendered so you'd want to stop that from happening so it doesn't 'precalculate' the animation values. Then pop an overwrite 'auto' on the tween itself so it take priority over the initial load tween
  12. Hi. I'm trying to animate a circular shape on scroll that sometimes might happen while a previous Tween with the same element is still animating. If you take a look at the codepen, once the page is loaded, the circular shape is being animated, but if you scroll while it's still animating, it causes a jump on the circle. The espected behaviour is that if you scroll while the Tween is animating, the animation should continue from the previous Scale value. I have already tried "overwrite: true" but that doesn't seem to help in this case.
  13. I couldn't reproduce either. Are you able to reproduce it on that CodePen even one time @celli? This is definitely a mistake: box.addEventListener("mouseleave", function () { return tl.reverse(); tl.totalProgress(1).kill(); // <- THIS LINE WILL NEVER RUN!!! }); You have a return statement on that first line which totally bails out of the function immediately, thus that next line never gets executed. But even if it did, you're having the opposite effect that you seem to want. Forcing it to a totalProgress(1) make it go to the END of the timeline, not the start. But aren't you trying to reverse it (to go backward toward the start)? Why would you then try to jump to the end and kill it? My guess is that your real project has a fundamental difference that's the root cause of the problem. You mentioned that it "gets stuck". That sounds to me like you must be killing it somewhere -or- you're overwriting somewhere. Do you have overwrite: true anywhere that might be getting triggered? In order to effectively troubleshoot, we really need a minimal demo that clearly shows the problem but the one you provided seems to never show the problem which makes it tough. Any chance you could provide a broken demo?
  14. 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.
  15. I don't have time to do a deep dive, but it sounds like maybe you just need to do this: if (isOver) { gsap.to(tl, {timeScale: 0, duration: 1, overwrite: true}); } https://codepen.io/GreenSock/pen/QWmmgjd?editors=0010
  16. I'm posting the final code down here: function BackgroundCloud(props){ // Current element let thisEl // Refreshes the component let isLoaded = useContext(props.pageLoaded) // Maxiumum left attribute that the cloud must reach & animation const maxLeft = useRef(0) const animation = useRef([]) function updateWindow(evt){ // If it is the first execution update the left parameter and set currentHeight & currentWidth if(!evt){ resetComponent() } // --> This code must be executed in both vertical and horizontal resize <-- maxLeft.current = 2 * thisEl.width() + $(window).width() // Adapting cloud to new top const parent = thisEl.parent().parent().parent() const fromTop = parent.offset().top const parentDistance = fromTop + parent.height() / 2 let top = props.top if(top.includes("vh")){ top = top.replace("vh", "") top = top * 0.01 top = $(window).height() * top }else if(top.includes("px")){ top = top.replace("px", "") } thisEl.css("--top", String(parentDistance + top).concat("px")) // Delete every ongoing animation killAnimation() // Create a new animation animation.current.push(gsap.to(thisEl, {left: maxLeft.current, duration: props.duration, ease: Linear.easeNone, onComplete: resetComponent})) } // Delete every ongoin animation function killAnimation(){ for(let i = 0; i < animation.current.length; i++){ animation.current[i].kill() } animation.current = [] } // Exec when the site is loaded/the component refreshed useEffect(() => { if(isLoaded){ updateWindow() $(window).on("resize", updateWindow) } }, []) // Reset a cloud (called when the component reaches the end) function resetComponent(){ thisEl = $(`#${props.propId}`) thisEl.css("left", -2 * thisEl.width()) killAnimation() animation.current.push(gsap.to(thisEl, {left: maxLeft.current, duration: props.duration, ease: Linear.easeNone, delay: props.delay, onComplete: resetComponent})) } // Return default cloud return( <div className="backgroundCloudContainer"> <img src={props.background} className="backgroundCloud" id={props.propId} draggable="false" alt={props.propId} style={{ "--z-index": props.zIndex, "--top": props.top, "--scale": props.scale }}/> </div> ) } To fix the problem I did the following things: 1) Using an array to store every animation I create (so I can .kill() everything) 2) Using useRef() instead of saving data in plain variables 3) Fixed the event listeners because I inserted the jquery .off() method that removes every listener from the element that, of course, made my solution not working Now I'm planning to remove the array and setting overwrite to "auto" or true so I'll save a piece of performance. Anyway, thanks for helping me. Hope that the problem I had will help someone else : D
  17. It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or CodeSandbox that demonstrates the issue? Please don't include your whole project. Just some colored <div> elements and the GSAP code is best (avoid frameworks if possible). See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer. Here's a React template. Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. Setting overwrite to "auto" or true can be good, but it's important that you understand what's going on and what that's solving so that you can ensure it's not just a band-aid that covers over something like creating a bunch of conflicting animations unnecessarily.
  18. Before trying those things together, I noticed that React calls multiple times my function, so, is enabling overwriting a good way for "skipping" some problems? And is gsap.defaults({overwrite: "auto"}); a good way for enabling it? (From: )
  19. Ah ok! So currently if it leaves a black section to enter another black section it's trying to reverse the animation and then immediately play it again. I think you may be able to get around this with a different overwrite mode. But I think I'd pop the tween out into a callback instead, then check the incoming section's color and update it accordingly. https://codepen.io/GreenSock/pen/eYMVNYg That seems to work without any overwriting needed and no visual flickers. ☺️ Hope this helps!
  20. That's the idea. You can also set gsap.defaults before gsap.registerPlugin too... My first few lines on a typical GSAP project are: 'use strict'; gsap.defaults({overwrite: "auto"}); gsap.registerPlugin(CSSRulePlugin, ScrollToPlugin, ScrollTrigger, TextPlugin);
  21. That has to do with the plumbing in your app - we really try to stay focused on GSAP-specific things here. But the general idea is to only add those even handlers once. Or if you're gonna add them multiple times, make sure you remove the old one before adding the new one each time (so there's always only one). You can gsap.killTweensOf(Cursor) if you want, but I'm reluctant to suggest that because it's just shielding you from the real, fundamental issue in your app (creating all those listeners). You can set overwrite: "auto" to have GSAP try to find conflicts when the new animation renders for the first time. But again, that's a band-aid here. Good luck!
  22. 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?
  23. Quick question if anyone minds sparing some of their knowledge Like the overwrite property prevents previous animations effecting an element once another has started, is it possible to prevent an onComplete from a previous animation running? I've basically got a click event listener that fires off an animation, and onComplete deletes an element. But the element may or may not be there once the event handler runs again. I'd post a codepen, but to replicate some of the (awkward) design choices I'm working with it would be massive and probably just complicate things, so I was wondering if there was anything obvious I should be looking to do, or if there were any useful approaches I should think about when dealing with overlapping animations like this? Thanks!
  24. Actually it looks like it doesn't like interrupting the tween fired in the leave event. I can't use xTo for that because it has a dynamic ease applied. I wonder why it doesn't overwrite it.
  25. We love helping with GSAP-related questions, but unfortunately we just don't have the resources to provide free general consulting, logic troubleshooting, or "how do I recreate this cool effect I saw on another site?" tutorials. Of course anyone else is welcome to post an answer if they'd like - we just want to manage expectations. If I were you I'd approach this with single tweens per box and overwrite:true or auto. Maybe just focus on trying to swop one box between two different directions without scrollTrigger, then add some more boxes, then add in a ScrollTriggers with some callbacks and swop the direction over in the callbacks. Timelines are pre-calculated and a little less flexible for this sort of thing whereas tweens can be a bit more dynamic. Hope this helps a bit!