Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...

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

  1. Welcome to the forums, @Sooova. Would you please provide just a minimal demo that more clearly demonstrates the issue? I'm pretty lost when I look at that demo, especially with all the missing images. You can just use simple colored <div> elements instead maybe. It shouldn't take 100+ lines of code to show the issue. There are a lot of setTimeouts/Promises and delays and stacked up strings of logic - perhaps you could just eliminate any randomization, isolate a single state change of one or two elements, and only focus on that in your demo(?) And please keep in mind that these forums aren't really for general troubleshooting of logic issues, but we're happy to answer any GSAP/Flip questions. A few quick comments: I assume this was a mistake: // BAD onComplete: isComplete(), // <- executes immediately and assigns whatever isComplete returns to the onComplete. // GOOD onComplete: isComplete, And this: // BAD overwrite: "false", // GOOD overwrite: false, You can use gsap.utils.random() instead of your getRandomInt() function.
  2. Hi guys, So, I've done an Horizontal Scroll on Elementor but I'm getting really frustrated with horizontal scroll (anchors) because nothing really works.. Can you please advise what I'm doing wrong? This is the Elementor site. I've tried the bellow code: <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollTrigger.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollToPlugin.min.js"></script> <script>gsap.registerPlugin(ScrollTrigger); let sections = gsap.utils.toArray("section"), nav = gsap.utils.toArray(".menu-item a"), getMaxWidth = () => sections.reduce((val, section) => val + section.offsetWidth, 0), maxWidth = getMaxWidth(), scrollSpeed = 4, snapProgress, lastScrollTween = 0, tl = gsap.timeline(); tl.to(sections, { x: () => window.innerWidth - maxWidth, duration: 1, ease: "none" }); ScrollTrigger.create({ animation: tl, trigger: ".elementor-section-wrap", pin: true, scrub: 1, snap: {snapTo: directionalSnap(tl), duration: 0.5}, end: () => "+=" + maxWidth / scrollSpeed, invalidateOnRefresh: true }); function init() { gsap.set(sections, {x: 0}); maxWidth = getMaxWidth(); let position = 0, distance = maxWidth - window.innerWidth; // add a label for each section to the timeline (for "labelsDirectional" functionality): tl.add("label0", 0); sections.forEach((section, i) => { let progress = position; position += section.offsetWidth / distance; tl.add("label" + (i+1), position); nav[i].onclick = () => { // link clicks should trigger a scroll tween to the appropriate spot snapProgress = progress; // save the current progress so that if we can return it in the directionalSnap() when called right after the scrollTo tween is done (because ScrollTrigger would normally look at the velocity and snap, causing it to overshoot to the next section) lastScrollTween = Date.now(); // for checking in the directionalSnap() if there was a recent scrollTo that finished, in which case we'd skip the snapping (well, return the current snapProgress) gsap.to(window, {scrollTo: maxWidth / scrollSpeed * progress, duration: 1, overwrite: "auto"}); }; }); } init(); ScrollTrigger.addEventListener("refreshInit", init); // on resize, things must be recalculated // a helper function for doing "labelsDirectional" snapping, but we can't use that directly since we're doing some special things with scrollTo tweens, and we need a way to skip the snap if a scrollTo recently finished (otherwise it'll overshoot to the next section) function directionalSnap(timeline) { return (value, st) => { if (Date.now() - lastScrollTween < 1650) { // recently finished doing a tweened scroll (clicked link), so don't do any snapping. return snapProgress; } let a = [], labels = timeline.labels, duration = timeline.duration(), p, i; for (p in labels) { a.push(labels[p] / duration); } a.sort((a, b) => a - b); if (st.direction > 0) { for (i = 0; i < a.length; i++) { if (a[i] >= value) { return a[i]; } } return a.pop(); } else { i = a.length; while (i--) { if (a[i] <= value) { return a[i]; } } } return a[0]; }; }</script> With this CSS (working fine on scroll): @media only screen and (min-width:768px){ .elementor-inner .elementor-section-wrap{ display: inline-flex; } .elementor-section{ width:100vw; } .custom-width{ width: 100px; } .custom-width2{ width: 100vw; } body{ overflow-y: hidden; overscroll-behavior-y: none; } .elementor-inner { width: 100vh; height: 100vw; overflow-x: hidden; overflow-y: scroll; transform: rotate(-90deg) translateX(-100vh); transform-origin: top left; position: absolute; scrollbar-width: none; -ms-overflow-style: none; } .elementor-inner .elementor-section-wrap { transform: rotate(90deg) translateY(-100vh); transform-origin: top left; display: flex; flex-direction: row; width: 600vw; } /*section { width: 100vw; height: 100vh; }*/ ::-webkit-scrollbar { display: none } } @media only screen and (max-width:768px){ .elementor-inner .elementor-section-wrap{ display: block; } body{ overflow-y:auto; } } Thank you
  3. There is no kill method. That's why I was saying that you would need to write that yourself. Maybe something like this. export default class AnimationServicesHomePage { constructor(animationEl) { this.triggers = []; this.DOM = { animationEl: animationEl }; this.DOM.scrollColorElems = [ ...this.DOM.animationEl.querySelectorAll("[data-bgcolor]") ]; if (this.DOM.scrollColorElems) { this.DOM.scrollColorElems.forEach((colorSection, i) => { const prevBg = i === 0 ? "" : this.DOM.scrollColorElems[i - 1].dataset.bgcolor; this.animationBgImgScroll(colorSection, prevBg); }); } /* ScrollTrigger.addEventListener("resize", () => locomotive.update()); ScrollTrigger.refresh(); */ } kill() { this.triggers.forEach((t) => t.kill()); } /* Animation Scroll Bg Color Change Services Apparitions Home */ animationBgImgScroll(colorSection, prevBg) { /* ScrollTrigger.config ({ limitCallbacks: true }) */ const body = document.querySelector("body"); let st1 = ScrollTrigger.create({ trigger: ".services", start: "top 12.5%", end: "bottom 12.5%", markers: true, toggleActions: "play none none none", onEnter: () => body.classList.remove("bg-black"), onLeaveBack: () => body.classList.add("bg-black") }); let st2 = ScrollTrigger.create({ trigger: colorSection, start: "top 50%", end: "bottom 50%", markers: false, invalidateOnRefresh: true, immediateRender: false, preventOverlaps: true, fastScrollEnd: true, onEnter: () => gsap.to("body", { backgroundColor: colorSection.dataset.bgcolor }), onLeaveBack: () => gsap.to("body", { backgroundColor: prevBg, overwrite: "auto" }) }); this.triggers.push(st1, st2); } }
  4. @Septrios we can't effectively troubleshoot live web sites - if you can't provide a minimal demo in CodePen or something like that, you'll probably need to secure paid consulting services. My advice: try to reproduce the issue in the most basic way possible (a few simple <div> elements in a CodePen) and then post that here. I think part of the problem is likely that you're just doing tweens inside a callback which don't get reverted when ScrollTrigger.refresh() is called (like on resize). I'd probably just use a regular tween that has a ScrollTrigger, like this: // OLD ScrollTrigger.create({ trigger: colorSection, scroller:'.js-locomotive', start: "top 50%", end:'bottom 50%', markers:false, toggleActions : "play none none reverse" , onEnter: () => gsap.to("body", { backgroundColor: colorSection.dataset.bgcolor, }), onLeaveBack: () => gsap.to("body", { backgroundColor: prevBg, overwrite: "auto", }), }); // NEW gsap.to("body", { backgroundColor: colorSection.dataset.bgcolor, scrollTrigger: { trigger: colorSection, scroller:'.js-locomotive', start: "top 50%", end:'bottom 50%', toggleActions: "play none none reverse", immediateRender: false, preventOverlaps: true, fastScrollEnd: true } });
  5. Yes, that's exactly it. Thank you Jack. Why is the overwrite:true important in this case?
  6. Maybe preventOverlaps could help you? Alternately maybe looking into overwrite modes? However - as Blake said, if you use one timeline you won't run into these issues. It's by far the easiest solution If you have four sections in the DOM, make sure that your tweens are equally distributed (timing-wise) into four equal parts and then that'll map to the sections!
  7. Hello, I'm a new Gsap's fan in this place . I'm a french Developper, so sorry for my english. I have a problem with GSAP. I have a scrollTrigger.create, where I add and remove a class ('bg-black) depending on the trigger. Also, I change the colors of the background in another scrolltrigger, when scrolling the page. On the first load it works!, but when, I switch to the mobile or switch the page and come back to the first page in desktop(when i m resize the window) , the bg-black class is automatically deleted and the background has the last color of the effect. By debugging, the problem would come from the OnEnter function, but I can't find an answer, thank you for your help I used NUXT, locomotive scroll and GSAP ScrollTrigger.create({ trigger: ".services__content", scroller:'.js-locomotive', start: "top 30%", end:'bottom 30%', markers:true, toggleActions : "play none none reverse" , onEnter: () => body.classList.remove("bg-black") , onLeaveBack: () => body.classList.add("bg-black") }) ScrollTrigger.create({ trigger: colorSection, scroller:'.js-locomotive', start: "top 50%", end:'bottom 50%', markers:false, toggleActions : "play none none reverse" , onEnter: () => gsap.to("body", { backgroundColor: colorSection.dataset.bgcolor, }), onLeaveBack: () => gsap.to("body", { backgroundColor: prevBg, overwrite: "auto", }), });
  8. 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.
  9. 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' }); } } }
  10. The main problem is that you keep creating a new tween every single time there's a mousemove event and also every time there's a mouseenter but you never set an overwrite nor do you kill() the old tween(s). So, for example, you create a repeating backgroundPosition tween the first time the user's mouse enters and then the next time you create a new one but the OLD one is continuing to play and repeat over and over. That tween is affecting the backgroundPosition as well (you're creating a bunch of conflicting tweens). You could just set overwrite: "auto" on your tween(s) but I'd actually recommend simply reusing a single tween instance rather than creating new ones over and over and over again. That'll perform better. https://codepen.io/GreenSock/pen/podNjwp?editors=0010 You had a few typos in there too. Is that CodePen more like what you wanted?
  11. Sure, if you're just staggering them (same animation for all, just offset), you can simply use a "stagger" on a single tween. No need for a timeline. But yes, if you need to animate various things differently, you can absolutely use a timeline that you create in the callback(s). Just make sure you set overwrite: true (or "auto") on the tweens to ensure you don't create conflicts. onEnter: () => { let tl = gsap.timeline({defaults: {overwrite: true}}); tl.to(...).to(...)... } If you're still struggling, please provide a minimal demo and we'd be happy to take a peek. Good luck!
  12. 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.
  13. Hi, I am a new user of gsap, I just removed the end property and edited the other properties according to my requirements in my next.js project. The above codepen is the same as the documentation example with its end property removed. I am facing the same problem as that codepen, sometimes the car or tractor goes out of the screen while scrolling, I noticed the further the end, the slower the car moves and vice-versa. Could someone please suggest what I should do to fix this, I tried modifying start and end properties but that becomes unresponsive on different sizes. In simple words it is not responsive for all sizes. In my next.js project this is the code for the animation gsap.to("#motionSVG", { scrollTrigger: { trigger: ".section.hiw", start: "300px 20% ", scrub: 1, markers: true, onUpdate: (self) => { gsap.to("#tractor", { rotation: () => (self.direction === 1 ? 0 : -180), overwrite: "auto", }); }, }, duration: 10, ease: "none", immediateRender: true, motionPath: { path: "#motionPath", align: "#motionPath", alignOrigin: [0.5, 0.5], autoRotate: 90, }, });
  14. Hi @akapowl, Thanks for the guidance I've managed to make some headway after your suggestions and have somewhat of a solution in place. See latest fiddle here. For visual, here is my latest JS: $(function() { const pageContainer = document.querySelector("[data-scroll-container]"); const scroll = new LocomotiveScroll({ el: pageContainer, smooth: true, }); scroll.on(pageContainer, ScrollTrigger.update); ScrollTrigger.scrollerProxy(pageContainer, { scrollTop(value) { return arguments.length ? scroll.scrollTo(value, 0, 0) : scroll.scroll.instance.scroll.y; }, getBoundingClientRect() { return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight }; } }); /* anims */ function animateFrom(elem, direction) { direction = direction || 1; var x = 0, y = direction * 100; if (elem.classList.contains("gsap_reveal--fromLeft")) { x = -100; y = 0; } else if (elem.classList.contains("gsap_reveal--fromRight")) { x = 100; y = 0; } elem.style.transform = "translate(" + x + "px, " + y + "px)"; elem.style.opacity = "0"; gsap.fromTo(elem, { x: x, y: y, autoAlpha: 0 }, { duration: 2, x: 0, y: 0, autoAlpha: 1, ease: "expo", overwrite: "auto", }); } function hide(elem) { gsap.set(elem, { autoAlpha: 0 }); } gsap.utils.toArray(".gsap_reveal").forEach(function(elem) { hide(elem); // assure that the element is hidden when scrolled into view ScrollTrigger.create({ trigger: elem, scroller: "[data-scroll-container]", onEnter: function() { animateFrom(elem) }, onEnterBack: function() { animateFrom(elem, -1) }, once: true, }); }); /* anims end */ window.addEventListener("load", function(event) { ScrollTrigger.refresh(); }); ScrollTrigger.addEventListener("refresh", () => scroll.update()); ScrollTrigger.refresh(); }); Key changes in the above based on before: Moved my animateFrom() below the scrollerProxy() Added scroller: "[data-scroll-container]" to my scrollTrigger Follow-up question. Whilst I do have something working now, I have all of my GSAP animations in another js file. This file is called animations.js. In my demo above and in the fiddle, the scrollTrigger animations only work when the scrollTrigger is below the scrollerProxy() and above the scroll.update() event listener. Is the only way for this to work is to have all of my animations between the two? Something like below: ScrollTrigger.scrollerProxy(pageContainer, { scrollTop(value) { return arguments.length ? scroll.scrollTo(value, 0, 0) : scroll.scroll.instance.scroll.y; }, getBoundingClientRect() { return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight }; } }); /* /* ALL scrollTrigger animations here */ window.addEventListener("load", function(event) { ScrollTrigger.refresh(); }); ScrollTrigger.addEventListener("refresh", () => scroll.update()); ScrollTrigger.refresh();
  15. I have sections across my site which are using ScrollTrigger. Once I implemented Locomotive JS, all of my ScrollTrigger animations stopped working. I've read through the forums and saw that you need to update() ScrollTrigger when Locomotive is scrolling. I implemented this and saw no results. Then, I resized the window and my ScrollTrigger animations that were in view, they started working. In short, animations trigger on resize, but not on page load. I've implemented update() and also tried refresh(), but no luck. Below is a demo of the issue. Further down, I've added in steps to recreate and also a visual. <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/locomotive-scroll@4.1.3/dist/locomotive-scroll.min.css" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdn.jsdelivr.net/npm/locomotive-scroll@4.1.3/dist/locomotive-scroll.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollTrigger.min.js"></script> <div data-scroll-container> <div data-scroll-section> <section class="hero"> <div class="container"> <div class="row justify-content-center justify-content-xl-between"> <div class="col-12 col-md-10 col-lg-9 col-xl-5"> <div class="hero__text text-center text-xl-start"> <h1 class="hero__title" data-scroll data-scroll-speed="2">Title</h1> </div> </div> </div> </div> </section> <section class="textImageRepeater"> <div class="container"> <div class="row"> <div class="col-12"> <div class="textImageRepeater__item textImageRepeater__layout--row"> <div class="textImageRepeater__text text-center text-md-start gsap_reveal gsap_reveal--fromRight"> <div class="textImageRepeater__copy"> <h2>Header</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> </div> <div class="textImageRepeater__graphic text-center gsap_reveal gsap_reveal--fromLeft"> <img class="textImageRepeater__image" src="https://picsum.photos/200/300" alt="placeholder-image" loading="lazy"> </div> </div> <div class="textImageRepeater__item textImageRepeater__layout--rowReverse"> <div class="textImageRepeater__text text-center text-md-start gsap_reveal gsap_reveal--fromRight"> <div class="textImageRepeater__copy"> <h2>Header</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> </div> <div class="textImageRepeater__graphic text-center gsap_reveal gsap_reveal--fromLeft"> <img class="textImageRepeater__image" src="https://picsum.photos/200/300" alt="placeholder-image" loading="lazy"> </div> </div> </div> </div> </div> </section> </div> </div> $(function() { gsap.registerPlugin(ScrollTrigger); function animateFrom(elem, direction) { direction = direction || 1; var x = 0, y = direction * 100; if(elem.classList.contains("gsap_reveal--fromLeft")) { x = -100; y = 0; } else if (elem.classList.contains("gsap_reveal--fromRight")) { x = 100; y = 0; } elem.style.transform = "translate(" + x + "px, " + y + "px)"; elem.style.opacity = "0"; gsap.fromTo(elem, { x: x, y: y, autoAlpha: 0 }, { duration: 2, x: 0, y: 0, autoAlpha: 1, ease: "expo", overwrite: "auto" }); } function hide(elem) { gsap.set(elem, { autoAlpha: 0 }); } gsap.utils.toArray(".gsap_reveal").forEach(function(elem) { hide(elem); // assure that the element is hidden when scrolled into view ScrollTrigger.create({ trigger: elem, onEnter: function() { animateFrom(elem) }, onEnterBack: function() { animateFrom(elem, -1) }, onLeave: function() { hide(elem) } // assure that the element is hidden when scrolled into view }); }); /*******************************************************************/ /* Locomotive /*******************************************************************/ const pageContainer = document.querySelector("[data-scroll-container]"); const scroll = new LocomotiveScroll({ el: pageContainer, smooth: true }); // each time locomotive Scroll updates, tell ScrollTrigger to update too (sync positioning) scroll.on(pageContainer, ScrollTrigger.update); // tell ScrollTrigger to use these proxy methods for the ".data-scroll-container" element since Locomotive Scroll is hijacking things ScrollTrigger.scrollerProxy(pageContainer, { scrollTop(value) { return arguments.length ? scroll.scrollTo(value, 0, 0) : scroll.scroll.instance.scroll.y; }, // we don't have to define a scrollLeft because we're only scrolling vertically. getBoundingClientRect() { return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight}; } }); window.addEventListener("load", function (event) { ScrollTrigger.refresh(); }); ScrollTrigger.addEventListener("refresh", () => scroll.update()); ScrollTrigger.refresh(); }); .hero { min-height: 1000px; background: lightblue; display: flex; align-items: center; } .textImageRepeater { overflow: hidden; padding: 120px 0 160px 0; } .textImageRepeater__intro { margin-bottom: 66px; } .textImageRepeater__layout--row { flex-direction: row !important; } .textImageRepeater__layout--rowReverse { flex-direction: row-reverse !important; } .textImageRepeater__item { display: flex; align-items: center; justify-content: center; flex-direction: column; padding-top: 70px; justify-content: space-between; } .textImageRepeater__header { margin: 17px 0; } .textImageRepeater__graphic { margin: 0; } .textImageRepeater__text, .textImageRepeater__graphic { flex-basis: 50%; } .textImageRepeater__text { max-width: 500px; } .c-scrollbar_thumb{ background-color: #5D209F!important; width: 7px; margin: 2px; opacity: 1; border-radius: unset; mix-blend-mode: multiply; } Steps to recreate: Open this fiddle Widen the output box to something wide (i.e. 1300px) Run the fiddle Scroll down and you'll see the elements not loading Resize the output box to something smaller The scrollTrigger animations now appear Here is a gif showcasing the issue:
  16. If you don't want it play backwards, you can do something like this. Basically animate the progress yourself. let tl = gsa.timeline()... ScrollTrigger.create({ trigger: ".foo", onUpdate: ({ progress }) => { if (progress > tl.progress()) { gsap.to(tl, { ease: "power3", overwrite: true, progress }); } } });
  17. Hi @camiloignaval Welcome to the forum. Looks to me like you'll need to set the overwrite property to true in those tweens. (It's false by default) You could also create a timeline for each element and play/reverse it on enter/leave. Hopefully that helps. Happy tweening and welcome aboard.
  18. Yep. I've got a little experience with that kind of thing It was an excuse to try to make one that's as bare-bones as possible. I tend to geek out over that kind of thing. 🤔 Yep, you could totally implement a tween for the dragging instead of a direct setting of the scroll position. And then give it whatever duration you want (just remember overwrite: true so you're not creating lots of conflicting tweens). So yeah, you could set your scrub value to whatever the shortest one should be (dragging/buttons/scrolling) and then for the ones that you want to take longer, simply tween them accordingly with whatever duration you want. Fun, right? GSAP handles getter/setter methods which can be super useful. Once you learn that you can use one tween to animate the progress or timeScale of another tween...it's kinda mind-blowing. 🤯 You're welcome. Good luck with the project!
  19. Hey there @NeroThroN, You have some conflicting tweens here. If I were you I would either take a look at some different overwrite modes or Wrap the content in a container div and animate that div on scroll instead of the same elements you're animating in the entrance animation Hope this helps!
  20. You're creating bunch of animations in your mousemove handler, which might be conflicting with the animations you created on the previous mouse move, so you should overwrite those... testin gsap (codepen.io)
  21. now i added overwrite:true https://codepen.io/undertakerio/pen/mdBJMmG
  22. Is there a reason you don't want to use tweens with overwrite:true like @GreenSock did in his demo?
  23. That's asking a LOT of the browser to render all of that dynamically as vectors. I'm not at all surprised that performance is suffering. And to be clear, it has nothing to do with GSAP. I'd bet that less than 1% of the load is GSAP - the rest of graphics rendering. Also, I'd use overwrite: true instead of "auto" because it's cheaper. There's no need to do a pupil.forEach() to create a bunch of gsap.to() calls - just do a single gsap.to(pupil...) call (you can pass in multiple elements as the targets (Array). I'd recommend that you consider switching to something like PixiJS instead of using SVG. It'll render way faster but it is more work to set up.
  24. Can you explain what you mean? What are you wishing for that immediateRender doesn't provide? And if you just want to get something to render at a new playhead position, you can easily do that by setting the progress() or time(). Yes, that's very intentional and it's also easy to fix. We explain it here: In the old (v2 and earlier) version, the default overwrite mode was "auto". Now it is false because: It's faster (performance) because in the vast majority of cases people aren't creating conflicting tweens, so we can skip the processing involved in hunting down conflicts. It confused people in some cases because they didn't even know overwriting was a thing. The new behavior in v3 ensures that people opt-in to overwriting so that it never catches them off-guard. The fix: either set overwrite: "auto" (or true) in the new/overwriting tweens or you can just set the default mode for all animations to one of those like: gsap.defaults({overwrite: "auto"}); Does that clear things up?
  25. Still wish there was a render method,Very helpful for me One more problem was found when upgrading the old project: Tween does not overwrite the previous Tween very well https://codepen.io/lzy100p/pen/XWaQKpx In gsap2 it will stop after 1 second This is very different from gsap2
×