Jump to content

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


  • 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. Hello @F.D.C.H - welcome to the Forums. You could extend that helper function by a new variable - in the demo below I added startIndex = 0 up top where all the neccessary variables are being set up. In the draggables onPress you could set the startIndex = curIndex so at a later point (like on throwcomplete e.g.) you could check wether the value of the new curIndex is equal to the value of the startIndex. From outside the curIndex is accessible via tl.current() and I made the startIndex accessible via tl.dragStart() - but you could of course change the names to whatever you'd like. Of course the tl part here you would have to then exchange with whatever variable you are applying that horizontalLoop helper-function to. Then from outside you could do something like this. That's just an idea - I hope that will help loop.draggable.addEventListener("throwcomplete", log); function log() { console.log(loop.dragStart(), loop.current()) if( loop.dragStart() === loop.current() ) { console.log('Same Index') gsap.to(document.body, { backgroundColor: '#f00000', overwrite: 'auto' }) } else { console.log('New Index') gsap.to(document.body, { backgroundColor: '#111', overwrite: 'auto' }) } } https://codepen.io/akapowl/pen/KKQmPxB Edit: In this following pen the startIndex is also being set in the toIndex() function, so calling the check will also properly integrate with click on the buttons - and at this point the naming of tl.dragStart() doesn't seem appropriate anymore https://codepen.io/akapowl/pen/zYRwxBd
  2. Hi everyones I got stuck at the rotation so my question is how can i Overwrite the rotation ? ?? please go to the Codepen dont know only show the mobile version ... thanks for your time !
  3. Thank you for having a look at it. I did overwrite those declarations, however the issue is still there. I also tried commenting out everything but that didn't help either.
  4. @OSUblake @GreenSock Thanks again for your feedbacks! Sorry for not posting the link to the demo again; it is still in the first post (which I adapted): https://codepen.io/rowild/pen/eYVmJdE There I added the "quickTo", which I cannot get to work. And yes, when talking about "onMoveEnd", I actually mean Draggable – sorry for being so unclear! About my performance question: since I cannot get "quickTo" to work, I define the tween that is frequently called in "onDrag" as extra timeline and invoke "resume()" on it (I now also can call this tween from "onDragEnd"): function pedalOnDragReaction(rotation) { const tl = gsap.timeline({ paused: true }) tl.to(pedal, { duration: 0.5, rotation: -rotation, overwrite: true }) return tl } const handleOnDrag = (rotation) => { pedalOnDragReaction(rotation).resume()} } Draggable.create(bikePedal, { type: "rotation", onDrag: function () { handleOnDrag(parseInt(this.rotation % 360, 10)); }, onDrag: function () { handleOnDrag(parseInt(this.rotation % 360, 10)); }, [...] }); https://codepen.io/rowild/pen/bGLpbQe?editors=1111 It seems to work - but is it an improvement performance-wise?
  5. You're creating a tween at the end for that, so you could just use an onComplete on that tween to know when it's done. Beware, though - you are creating a whole new tween EVERY time there's any movement and you didn't set overwrite: true (or "auto") so you're technically creating a bunch of conflicts. I'd recommend setting overwrite: true or "auto". I'd personally recommend using the new gsap.quickTo() method instead for maximum performance.
  6. Heya! Ok so there's a couple of things I can recommend here. First up - overwrite modes. You're using true which is killing the conflicting tweens. You don't want that. You only want to overwrite the conflicting parts 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. Next, no need for an open and close timeline. We can create one timeline and then manage it with control methods. like tl.play(0) and tl.reverse()- then the timeline is interruptible, if you click open and close really quickly it'll just change the direction the timeline is animating. Here's an adjusted demo. https://codepen.io/GreenSock/pen/ZErEZEK?editors=0010
  7. Hi Michael, Have you seen the new Observer plugin? You can simply some of your event handling with it. 😉 https://greensock.com/docs/v3/Plugins/Observer As far as the rotation goes, you'd have to do some math to get it to work correctly, kind of like what is shown in this post for making a generic directionalRotation plugin. The code in that pen that is inside the if statement for short is what you would need to do. Or just use the built-in directional rotation, but you'd need to use a regular tween. gsap.to(this.elRotation, { rotation: `${degree}_short`, overwrite: true }) A Pen by GreenSock (codepen.io)
  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. Welcome to the forums @AFoeee You really don't have to call then, and using overwrite: "auto" only kills the property animations that are conflicting. Animations are set to resolve on complete, so it wouldn't make sense to resolve tween1 in the code below when the new animation starts as the x animation is still going to run its natural course. let tween1 = gsap.to(".box", { x: 100, y: 100 }); setTimeout(() => { gsap.to(".box", { y: 200, overwrite: "auto" }) }, 100) Maybe we can add in something to resolve if the entire animation is killed, but for now you would have to force it to complete, maybe like this. GSAP .then() interruption test (codepen.io)
  10. This is my demo link https://tool.baotramcompany.com/animation/v2/ and this my Gsap Code so 1. Can i reduce the space between point A -> B ? 2. Can i reduce the speed of the character movement ? Thanks for you times. Sory i cant push my code to codepen (something was wrong!) var animation; gsap.registerPlugin(MotionPathPlugin, ScrollTrigger); gsap.set("#cat", { scale: 1, autoAlpha: 1 }); gsap.set("#cat", { transformOrigin: "50% 50%" }); animation = gsap.to("#cat", { scrollTrigger: { trigger: "#motionPath", start: "top left", endTrigger: "body", end: () => ScrollTrigger.maxScroll("html"), scrub: true, markers: false, timeScale: 10, onUpdate: self => { gsap.to("#cat", { rotationY: () => self.direction === 1 ? 0 : 180, overwrite: 'auto', onscroll: function () { if (self.direction === 1) { jQuery("#increaseTrans").trigger('click'); //console.log("progress", self.progress); } else { jQuery("#increaseTrans").trigger('click'); } }, //=> self.direction === 1 ? jQuery("#increaseTrans").trigger('click'); jQuery("#moveDown").trigger('click'); : console.log("up"), }); } }, duration: 0.5, ease: "none", immediateRender: true, motionPath: { path: "#text-curve", align: "#text-curve", alignOrigin: [0.5, 0.5], autoRotate: true, } });
  11. Hey, I'm new to GSAP and absolutely loving it! I'm currently working on my first commercial Gatsby React site and while experimenting with the useLayoutEffect hook I came across an issue. managed to rectify it and now I was just wondering if I could get a little context. When I started setting up my animations I was nesting each animation into a separate useLayoutEffect hook like so: const h2Ref = useRef(null); const contentRef = useRef(null); useLayoutEffect(() => { const el = h2Ref.current; gsap.set(el, { y: -30, opacity: 0 }); gsap.to(el, { y:0, opacity:1, delay:.25 }); gsap.to(el, { y: -50, opacity: 0, immediateRender: false, overwrite: 'auto', scrollTrigger: { trigger: el, start: "top+=100px center", scrub: .5, } }); }, []) useLayoutEffect(() => { const el2 = contentRef.current; gsap.set(el2, { y: -30, opacity: 0 }); gsap.to(el2, { y:0, opacity:1, delay:.25 }); gsap.to(el2, { y: -30, opacity: 0, immediateRender: false, overwrite: 'auto', scrollTrigger: { trigger: el2, start: "top+=100px center", scrub: .5, } }); }, []) Everything works fine just like this. As an experiment, I had a shift around and dropped several animations into a single useLayoutEffect hook to see if I could clean up my code a little bit. Like this: const h2Ref = useRef(null); const contentRef = useRef(null); useLayoutEffect(() => { const el = h2Ref.current; gsap.set(el, { y: -30, opacity: 0 }); gsap.to(el, { y:0, opacity:1, delay:.25 }); gsap.to(el, { y: -50, opacity: 0, immediateRender: false, overwrite: 'auto', scrollTrigger: { trigger: el, start: "top+=100px center", scrub: .5, } }); const el2 = contentRef.current; gsap.set(el2, { y: -30, opacity: 0 }); gsap.to(el2, { y:0, opacity:1, delay:.25 }); gsap.to(el2, { y: -30, opacity: 0, immediateRender: false, overwrite: 'auto', scrollTrigger: { trigger: el2, start: "top+=100px center", scrub: .5, } }); }, []) When I did that, I was ending up with masses of white space appearing at the bottom of the page whenever I changed to a new route. So really my question is more out of curiosity, why did this happen? Is this something to do with how hooks work or how GSAP works? Just hoping to get a little enlightened Many thanks, and thanks for such an awesome animation tool!
  12. Hi @OSUblake, sorry for the delay in responding, the past two weeks have been hectic. I took what you suggested on board and spent some more time re-reading the docs, I have a habit of trying to run before I can walk... The whitespace bug has been resolved by killing the scrollTrigger and I've set up a wrapper element. Everything is working as intended. let el = useRef(); useLayoutEffect(() => { const q = gsap.utils.selector(el); const wrapper = el.current; gsap.set(q(".fancy-text"), { opacity: .2 }); gsap.to(q(".fancy-text"), { y: -50, opacity: 0, immediateRender: false, overwrite: 'auto', scrollTrigger: { trigger: wrapper, start: "top+=100px center", scrub: .5, markers:true } }); return () => ScrollTrigger.getAll().forEach(t => t.kill()); }, []) Thanks for your help, much appreciated
  13. I have confirmed it. But what I want is that the next section(wrapper enclosing sections 3, 4, 5), which is longer than the previous section(section 2), covers the previous section, and then scrolls. that example, the height of the sections is the same. plz check my pic Section 2 is overwritten by Section 3. However, Section 3 is smaller than Section 2, so I tried to overwrite Section 2 with the wrappers wrapped around Section 3, 4, and 5. Subsequently, sections 3, 4, and 5 proceed to normal scrolling.
  14. The scrub value is just the duration of that tween, so put in whatever value you want. gsap.to(tl, { progress: 1 - self.progress, ease: "power3", overwrite: true, duration: 0.25 });
  15. You can't animate "x" and "y" properties on every element to multiple places at the same time You could, however, wrap each element in another <div> and have the pointer parallax animate that one, and the motionPath can animate the child. The way you're handling the parallax pointermove thing is extremely inefficient. On every pointermove event (which can fire over 60 times per second) you're creating a whole new tween for every single element, and you're also calling .getBoundingClientRect() twice. Since you didn't set overwrite: true or overwrite: "auto", it also means you're creating a bunch of conflicting tweens that are fighting with each other for control of the same properties of the same targets. You're also getting the offsetTop and offsetLeft on every element on every pointermove event too which is expensive. You're needlessly duplicating the calculation of speed too (speedX and speedY are identical). You could pre-calculate a lot of the values, store them in a data object along with a tween for each element that you then invalidate() and restart() after updating the x/y destination values, sorta like this: const data = elements.map(el => { return { left: el.offsetLeft, top: el.offsetTop, speed: 100 - el.dataset.size, tween: gsap.to(el, {x: "+=0", y: "+=0", ease: "expo", duration: 2, paused: true}) }; }); const onMouseMove = (event) => { let bounds = wrapper.getBoundingClientRect(), pageX = event.pageX - bounds.width * 0.5, pageY = event.pageY - bounds.height * 0.5; data.forEach(d => { d.tween.vars.x = -((d.left + pageX * d.speed) * 0.005) / 2; d.tween.vars.y = -(d.top + pageY * d.speed) * 0.005; d.tween.invalidate().restart(); }); }; The upcoming release is going to have a very cool feature that'll make this even easier and faster, so stay tuned for that Side note: GSAP has a gsap.utils.random() method that you can tap into instead of making your own. I'm not even sure you need to use MotionPathPlugin - are you just trying to make it go in a circular path? If so, there may be easier algorithms. Like put it in a wrapper <div>, offset the transformOrigin and then rotate it while rotating the inner element in the opposite direction. Just an idea. Have fun!
  16. I don't have much time to dig into this but from a quick glance... You're likely creating a bunch of overlapping/conflicting tweens because you're trying to animate the exact same property of the same object every time you enter or leave a section. So imagine when you go from a red section to an orange section...you leave the red AND enter the orange at the same time, thus it's trying to animate to red AND orange simultaneously. That's a logic issue in your code. You've gotta choose one or the other. My guess is you only need it to happen onEnter and onEnterBack. I'd recommend setting overwrite: true or "auto" on your tweens to prevent conflicts. With the helper function that's doing the smooth scrolling, you can't have the sub-ScrollTriggers also have a scrubbed value other than true due to order-of-operation challenges with the current version. Watch for the next release for some exciting news. https://codepen.io/GreenSock/pen/popoPoN?editors=0010
  17. Good afternoon, i have a very long page that utilizes scrolltriggers in several modules. one of the modules on my pages has a horizontal scroll with a few slides and within each slide is an animation. everything works pretty well except we have found during beta testing that the user can scroll and very quickly through and past the horizontal "slider" into the regular vertical page. overall the horizontal portion doesnt "feel" great and breaks the user experience. we've tried doing "snap" points- but they snapped in odd ways that didnt feel natural. i've googled this, searched the forums, tried on my own but nothing is working or is overly complex to the point of getting overwhelmed at the complexity of some of these other "snap" solutions. what im wondering is is there a way to add a bit of a "click" feel as each slide finishes. or some sort of anticipation and "pause" after each slide so the user doesnt whip trough the horizontal scroll? i''d be very thankful for any assistance i can get on this, as it's become quite frustrating. const tl2 = gsap.timeline({ scrollTrigger: { trigger: '.module_3_wrapper', start: "center center", end: "center center", pin: '.module_3_wrapper', scrub: 1, pinSpacing: true, } }); let container = document.querySelector('.module_3'); let sections = gsap.utils.toArray(".module_3 .slides"); let scrollTween = gsap.to(sections, { x: () => -(container.scrollWidth - document.querySelector('.module_3_wrapper').clientWidth) + "px", ease: "none", duration: .1, scrollTrigger: { trigger: ".module_3_wrapper", pin: true, start: "center center", scrub: true, invalidateOnRefresh: true, end: `+=${container.offsetWidth}`, } }); I found someone did something like this with a nest scrolltrigger, but i can't figure out how to merge what i have and what this does. but it has the exact effect im looking for. where it nicely locks between slides. let slides = gsap.utils.toArray(".slide"); slides.forEach((slide, i) => { if (i) { // skip the first one. ScrollTrigger.create({ start: () => ScrollTrigger.maxScroll(window) / (slides.length - 0) * i, end: "+=1", onEnter: self => gsap.to(".slide", {x: (-100 * i) + "vw", ease: "none", overwrite: true}), onLeaveBack: self => gsap.to(".slide", {x: (-100 * (i - 1)) + "vw", ease: "none", overwrite: true}) }) } });
  18. 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.
  19. Are you maybe looking for pinspacing:false Also - If you wanted to go with this type of a solution you'd need to tweak the calculation of the marker placement to be based around the slide container itself rather than the window. Something vaguely like this? This is just a guess so apologies if it doesn't work, I figure most things out by trial and error. But basically you'll want to be adding a little more offset to the start marker on each one. let slides = gsap.utils.toArray(".slide"); slides.forEach((slide, i) => { if (i) { // skip the first one. console.log('maybe?', myslides.offsetWidth / (slides.length - 0) * i) ScrollTrigger.create({ trigger: myslides, markers: true, start: () => `top+=${myslides.offsetWidth / (slides.length - 0) * i} top`, end: "+=1", onEnter: self => gsap.to(".slide", {x: (-100 * i) + "vw", ease: "none", overwrite: true}), onLeaveBack: self => gsap.to(".slide", {x: (-100 * (i - 1)) + "vw", ease: "none", overwrite: true}) }) } });
  20. Hi Cassie, thank you so much for responding. i think what needs to happen it's basically putting each slide in a scrolltrigger and giving it a pin (stays on screen for a second before releasing to the next slide) effect. right now the continuous scroll of the horizontal slider doesnt feel very good. and snapping doesnt either. But i found a post buried here, that i can no longer find that had a solution that was exactly what i needed. and it's the below code. my only problem is i couldnt figure out how to integrate into my page flow like you see in my codepen. because the below code acts as if the horizontal slider is the only main element on the page. let slides = gsap.utils.toArray(".slide"); slides.forEach((slide, i) => { if (i) { // skip the first one. ScrollTrigger.create({ start: () => ScrollTrigger.maxScroll(window) / (slides.length - 0) * i, end: "+=1", onEnter: self => gsap.to(".slide", {x: (-100 * i) + "vw", ease: "none", overwrite: true}), onLeaveBack: self => gsap.to(".slide", {x: (-100 * (i - 1)) + "vw", ease: "none", overwrite: true}) }) } });
  21. Yes, it's generally not a good idea to reuse an animation that might be competing with another animation. The left timeline doesn't know you are changing stuff in the right timeline. Also, I'm not sure what these from statements are for. .from(logoRef.current, { transform: "none" }, "<") It's best to always use GSAP transform properties like x, y, scale, etc instead of transform. If you need to remove one, you can just use a set. .set(logoRef.current, { scale: 1 }, "<") I would suggest reworking your animation into a single animation, kind of like this. A Pen by GreenSock (codepen.io) If some of the stuff isn't easy to control inside a single timeline, you can also make a timeline that does the progress and whatever else you want. gsap.timeline() .to(animation, { overwrite: true, progress: 0.5 }) .to(myLogo, { ... }, 0) Outside of that, the best way to handle competing animations is to just not use them and create your animations on the fly, like in the mouseenter/mouseleave events.
  22. See if this gets you going in the right direction. I just used standalone ScrollTrigger to toggle the nav items. The back ease looks a little bit weird in reverse, so if you wanted a different ease when hiding the items, you should just create a new animation in that if/else. if (self.isActive) { gsap.to(boxes, { overwrite: true, ease: "back.out", // or whatever exit ease you want y: -64, opacity: 0, stagger: { amount: 0.25 } }); } else { gsap.to(boxes, { overwrite: true, ease: "back.out", y: 0, opacity: 1, stagger: { amount: 0.25 } }); } Multiple GSAP Animations in React (codepen.io)
  23. GreenSock

    Unregister Effect

    You don't have to unregister - if you want to replace one, you can just registerEffect() a new effect with the same name and it'll overwrite the previous one.
  24. Hello guys, I am in need of some dire help. I am trying to implement a scrolltrigger effect with snapping exactly like the GSAP codepen demo here, but in React / Next JS. I been working on it for days trying to implement on a website. I also created a mini codesandbox demo with the effect, but as you see, the behavior snapping and scroll is not the same. I was wondering if I could get some assistance. Sandbox link: https://codesandbox.io/s/festive-babycat-b8lh74?file=/pages/_app.js useEffect(() => { let panels = gsap.utils.toArray(".panel"); let scrollTween; function scrollTo(arg) { return { y: arg * innerHeight, autoKill: false }; } function goToSection(i) { scrollTween = gsap.to(window, { scrollTo: () => { scrollTo(i); console.log(i); }, duration: 1, onComplete: () => (scrollTween = null), overwrite: true }); } panels.forEach((panel, i) => { ScrollTrigger.create({ trigger: panel, start: "top bottom", markers: true, onToggle: (self) => self.isActive && !scrollTween && goToSection(i) }); ScrollTrigger.create({ start: 0, end: "max", snap: 1 / (panels.length - 1) }); }); }, []);
  25. I don't quite understand your question here - can you please be more specific? I didn't see anything jerky. You should definitely switch to the more modern GSAP 3 syntax: // OLD TweenMax.to(".bar", 0, {width: "-=3%"}); // NEW gsap.set(".bar", {width: "-=3%"}); If you want to animate things instead of suddenly setting them, you could use a small duration on a gsap.to() call, and make sure to set overwrite: true so that you're not creating conflicting tweens. If you're setting the same value over and over again, you might want to look into using gsap.quickSetter() for performance reasons.