Search the Community
Showing results for 'overwrite'.
-
Multiple animations on the same Object is creating issues
tailbreezy replied to jhtjards's topic in GSAP
Have you tried overwrite: "auto" it will try to detect if there are values that are still going which the tween doesn't affect, so it should leave those alone. Also why do you need other way. True seems to give good results as well. Other than that I am bit lost to what you want to achieve. -
Hi, i've started my first project with greensock a few weeks ago, had some problems along the way, solved them with the help of the detailed documentation and by quietly reading in the forums. Big kudos to the Dev Team for creating such a fun and high quality library and also to the awesome and super helpful community! But now I'm at a stage where I'm a bit stuck. I've created a little landing page with three smiley faces (svg) that pop out and in on mouseEnter / mouseLeave To draw attention to the little guys, I made an "idle"-timeline that makes them move randomly as if they were rummaging through some stuff in their caves. On mouseEnter they should stop rummaging and pop out ("tl"-timeline). It generally works, but there is one issue that I don't know how to get rid of: I had to place an overwrite: true into the animations, otherwise the timeline animations mix and produce all kinds of weird behaviour. But this removes all X and Y random motions i've declared and only leave the rotation being executed. Is there any other way of circumventing the animations mixing that keeps X and Y moving?
-
Also, just to be clear, your example creates a huge memory leak and compounding performance problem because you're literally creating 60 new tweens per second (assuming 60fps) that are constantly repeating and fighting each other for control of the same property of the same element. Definitely don't do that! So after 1 minute, you've got 3,600 tweens all fighting (3,599 more tweens than you need). At the very least you should set overwrite: true to avoid the build-up, but there are definitely better ways to code that. I'm trying to understand why you were putting it in a requestAnimationFrame() and constantly creating new instances. I don't mean it as a criticism - I'm genuinely trying to wrap my head around your original goal so that I can better advise you about a more appropriate way to do it.
-
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.
-
When creating new versions of demos for these forums, please use the "fork" button so that context is not lost for future readers of the thread. Your approach is fine. You might want to add overwriting so that new tweens kill off conflicting other ones: overwrite: 'auto'. You could also make use of GSAP's built in random functionality instead of adding your own which just (slightly) bloats your code: x: 'random(["-=50", "+=50"])'.
-
In general you don't want to keep adding to the same timeline like that. You should usually either use control methods on animations created beforehand (usually this is preferable) or create new timelines if you need to, making sure to overwrite old tweens. You might learn a lot from my article about animating efficiently. As for ScrollTo not working, I'm guessing that the ScrollToPlugin is updating the scroll position of the page but your custom scrollbar is not working? If not, please explain. In any way, please create a minimal demo using something like CodePen or CodeSandbox if you'd like debugging help. Side notes: You're using some of the old syntax. We highly recommend using all new syntax. It's easy to upgrade! You should avoid animating properties like top and left. Instead animate x and y as they're more performant.
-
Back to `overwrite:` ! That was what I was looking for! But then I don't get why my frist pen didn't work, there I had `overwrite: true` and it was in a timeline instead of straight up `gsap.to()`. I had it also `scrollTo:` the element on click, maybe that is the culprit? But I've modified your pen and everything seems to work fine. https://codepen.io/mvaneijgen/pen/wvozqJa?editors=1010
-
@ZachSaucier I want ScrollTrigger to scale the elements and on click the element should scale to 100%. If I want the click 100% scale to happen I have to `.disable()` the SCROLL scrollTrigger otherwise it will overwrite the scale. Another scrollTrigger should then check if you `onLeave()` or `onLeaveBack()`, then it should scale back to some magic value and the SCROLL trigger should enable again. In the end I also want to have a close button, with scales it back from 100% and enables the scroll animation again. I've also made a screen recording explaining my issue in more detail: and the pen https://codepen.io/mvaneijgen/pen/LYbZwyM?editors=0110 Fair enough, but I'll start optimising code when I got a working version.
-
Hi, I would like to set dynamically x transform on scroll on element in my marquee, but the render is not immediate, there lot of latency. That my different gsap definition. Do you have any solution ? this.duration = 40; this.timeLine = gsap.timeline({ repeat: -1, force3D: true }); // SCROLL EVENT document.addEventListener('scroll', debounce(() => { //console.log(this.currentX - n); let t = window.scrollY; let n = t - this.scrollPosition; //console.log('SCROLL', this.currentX - n); this.timeLine.fromTo(this.trainContentWrapper, { x: this.currentX, immediateRender: true }, { x: this.currentX - n, immediateRender: true, }) this.scrollPosition = t; }, 250)); //Timeline definition resize() { this.totalDistance = this.trainContentWrapper.getBoundingClientRect().width / 2; this.timeLine.to(this.trainContentWrapper, { x: -this.totalDistance, duration: this.duration, ease: "none", //overwrite: true, onUpdate: () => { this.currentX = gsap.getProperty('.train-content__wrapper', 'x'); } }); }
-
Thank you! i was thinking about the container too, in my project im using gatsy img (i know we already discussed about "framework" specific topics) and probably the rendred image alread have a wrapper i can "intercept" i will surely add the overwrite thanks again
-
Hey popland. When creating something like this, you usually want to apply the mouse listeners on a container of the transformed element instead of the transformed element itself because that will make the mouse events less glitchy (i.e. if it rotates too much then the mouseleave will fire even though it's not outside of the original element's bounds). So in this case I'd probably make an empty element wrapper around each image. It'd likely also be easier if you use the native mouse event's layerX and layerY properties. These are relative to the element instead of the viewport which make calculating the angle from the center of your element a lot simpler. Lastly I highly recommend using overwrite: 'auto' on your tweens so that they kill off conflicting tweens (that way you don't have unnecessary processing being done). With those tips I think you can get it working the way that you want it to work. If you run into something you can't figure out feel free to ask.
-
Restart and play again animation on state change. (With useEffect)
ZachSaucier replied to Argi's topic in GSAP
It depends on the situation and what you need to animate from and to. You should use whatever method that you need at the appropriate time, whether it's .set(), .from(), .fromTo(), or .to(). Reading the docs is probably the best way to learn .set() sets the properties at that time. Defaults are just that - default values for tweens. They don't do anything unless you have a tween that the default gets applied to. And if you have the same property declared inside of a tween, it will overwrite the default value. Again, I encourage you to read about them There are various ways to do that sort of thing. As covered in my article about animating efficiently that I said you should read earlier, most of the time creating animations beforehand and using control methods is the way to go. Other times it might be appropriate to overwrite your old animations and make sure that you animate to the correct end values. -
We've had several people ask about this type of effect, so I just built a GSAP effect that makes this a lot simpler for you (or anyone). Here's a fork of your original CodePen with it in place: https://codepen.io/GreenSock/pen/oNYXzYB?editors=0010 So you can just paste that gsap.registerEffect(...) code into your project, and then it's super simple to make anything have that effect: gsap.effects.ticker(".hero__ticker-init"); That's it! You can control the speed and direction with attributes like: <div data-speed="8" data-direction="right"></div> I noticed a problem with your original implementation - if the screen was resized, it didn't adjust, so there could be gaps that showed up. The effect here automatically listens for "resize" events on the window, and dynamically adjusts. Seems to work relatively well. I haven't done tons of testing on this, but hopefully it's at least a good starting point for you. Here's the raw effect (you don't really have to understand it all to use it): gsap.registerEffect({ name: "ticker", effect(targets, config) { buildTickers({ targets: targets, clone: config.clone || (el => { let clone = el.children[0].cloneNode(true); el.insertBefore(clone, el.children[0]); return clone; }) }); function buildTickers(config, originals) { let tickers; if (originals && originals.clones) { // on window resizes, we should delete the old clones and reset the widths originals.clones.forEach(el => el && el.parentNode && el.parentNode.removeChild(el)); originals.forEach((el, i) => originals.inlineWidths[i] ? (el.style.width = originals.inlineWidths[i]) : el.style.removeProperty("width")); tickers = originals; } else { tickers = config.targets; } const clones = tickers.clones = [], inlineWidths = tickers.inlineWidths = []; tickers.forEach((el, index) => { inlineWidths[index] = el.style.width; el.style.width = "10000px"; // to let the children grow as much as necessary (otherwise it'll often be cropped to the viewport width) el.children[0].style.display = "inline-block"; let width = el.children[0].offsetWidth, cloneCount = Math.ceil(window.innerWidth / width), right = el.dataset.direction === "right", i; el.style.width = width * (cloneCount + 1) + "px"; for (i = 0; i < cloneCount; i++) { clones.push(config.clone(el)); } gsap.fromTo(el, { x: right ? -width : 0 }, { x: right ? 0 : -width, duration: width / 100 / parseFloat(el.dataset.speed || 1), repeat: -1, overwrite: "auto", ease: "none" }); }); // rerun on window resizes, otherwise there could be gaps if the user makes the window bigger. originals || window.addEventListener("resize", () => buildTickers(config, tickers)); } } }); Hopefully that gives you something that you can work with, or at least analyze some of the logic. Enjoy!
-
Triggering different effects on mouseenter vs mouseout events
ZachSaucier replied to PG1's topic in GSAP
Hey PG1. You shouldn't be splitting your elements every time the mouse enters and exits. Only split it at the start. Besides that, you're making one of the most common GSAP mistakes: creating .from() logic issues. You should probably use .fromTo()s in your burnIn instead. Fixing those issues, you should get something like this: https://codepen.io/GreenSock/pen/vYyEwxb?editors=0010 Note that I didn't fix the logical issue when a user hovers it in and out quickly before the animation completes. You'll have to decide what to do in that case - whether or overwrite the previous animation, whether to ignore it if the animation is completed, or something else. FYI animating filters is not very performant.- 1 reply
-
- 3
-
-
Hi there I have set up some animation based on scroll through "enter & leave" state. Everything works as expected except when I scroll the page fast like by pressing the home or end button then animation will not complete and elements will overlap over each other. I searched on the forum and found the partial solution by using "overwrite: true". It made the animation complete but I am using scaling of elements in it that does not go back to it's original scale 1. Attached is the codepen for better understanding. Can someone pls explain what causing this behavior and how to prevent it so that when page is scrolled fast, the animation works all the way as supposed. Regards, Shehzad Asif
-
Hey SntsDev. One option might be to add a default onUpdate callback to your tweens: gsap.defaults({ onUpdate: () => console.log("fires if tween is running") }); However if you overwrite the onUpdate in a tween then it wouldn't fire for that tween. Perhaps @GreenSock could help with another alternative.
-
Horizontal with ScrollTrigger, Draggable - Dragging reverses sometimes
ZachSaucier replied to Hargy's topic in GSAP
Hey Mike. Connecting all of these modes of navigation is not the easiest task as you have found out Using the scroll position as the "core" of all of your navigation as you're doing is the right way to go. Unfortunately debugging all of your functionality is a bit out of scope of what we're able to provide for free. There's definitely some logical issues going wrong here, probably related to how you're updating the scroll position on drag. You definitely need to make sure to overwrite any previous animations affecting the scroll position by using overwrite: 'auto' on the relevant tweens. What makes you think it will go into an infinite loop? The cosmetic state is not attached to the actual scroll position... You should be able to update the cosmetic state as often as you'd like. -
Yep, exactly - we've actually got 3 levels of GSAP-ing; we've got the raw timeline which is the base which has "extra" animations because we want things to be "infinite", so we can't start the animation at the very beginning - there won't be any elements showing to the LEFT of that first element. So, for example, if we've got 5 elements to animate, it'd look like: 1-2-3-4-5-1-2-3-4-5-1 ^ start here The "overlap" is just the number of elements on each side of the start/end that we'll pad it with (so we'll add 2 * overlap number of extra animations). It really just depends how many elements are shown on the screen at any given time. The goal: cover the extra space. Here the overlap is 3 (thus 6 extra animations tagged onto the end). The tighter the spacing, the more elements/animations you'll need to cover the gaps which is why I've got it set to Math.ceil(1 / spacing). We pause that timeline because we'll control its playhead with ANOTHER timeline we're creating - "seamlessLoop". As indicated above, we'll start at the first "extra" animation so that there's stuff to the left ("5-4-3..."). Then we tween forward by the "overlap" amount (3 here) at which point we jump the playhead backward that same spot in the "normal" set of animations (non-extra). 1-2-3-4-5-1-2-3-4-5-1 ^ <------ ^ jump from here Then it tweens forward to where we started, thus if you were to play the seamlessLoop timeline (which just contains two tweens that scrub the raw timeline's playhead), it'd appear to seamlessly loop the "raw" timeline. Cool, huh? Most people really struggle with figuring out how to do a seamless loop where elements go off one side of the screen and come in the other side later. If you can explain this approach well in your tutorial (or whatever), it might help a lot of developers. Smooth scrubbing So now we've got a seamless loop that'd play, but we want to link that playhead to the scrollbar and have it SMOOTHLY move to a new position whenever the user scrolls, so we create a simple "scrub" tween to handle that which we reuse over and over again whenever we're going to a new position. That's cheaper than creating a new tween instance on every update (which could be quite frequent while scrolling). No need to manage overwrites that way too. Snapping Since we spaced all the animations out on the "raw" timeline with the "spacing" value, and we set up our "seamlessLoop" to start at exactly the spot where the first element is in the middle of the screen, snapping is easy. If "spacing" is 0.1, for example, we know that element #2 will be centered on the screen at a time of 0.1, the third would be at 0.2, etc. So it's index * spacing. Infinite looping & "iteration" We set the seamlessLoop to a repeat: -1 to allow us to just keep pushing the totalTime forward however far we want, and the timeline handles the looping at the appropriate spots. I'm using scrub.vars.totalTime is the destination value for the scrubbing. It's a convenient way to keep track of that too. So when you hit the "next" or "previous" buttons, all we've gotta do is add/subtract whatever our "spacing" amount is to get to that next spot on the timeline. The only catch is that you can't really go backwards past 0 (the start of the timeline), so we sense that condition and shove the playhead forward 10 iterations (it could be any number, there's no reason it has to be 10). We need to track the "iteration" in order to appropriately handle the wrapping around for the infinite scrolling effect. Otherwise, think about what'd happen if you scrolled all the way down (progress: 1) and it shot you back to the start (progress: 0) - the scrub tween would end up REWINDING all that distance instead of acting like it's continuing forward. Note: I based everything off of a tween duration of 1 second. Originally I had that as a variable, but then I realized it's not very helpful. It seemed cleaner to just use 1 across the board, and then you can adjust the "spacing" variable for a different effect, and/or alter the tweens, of course, but there seemed no benefit to having yet another "duration" variable floating around. So if you see the value "1" in various spots, it's likely related to duration. The down side of your previous solution was that it had to run a bunch of logic and create a set of new tweens each and every time you reached a new "slot". If someone scrolls really fast, it's expensive and you were actually creating conflicting tweens (easily remedied by setting overwrite: true, but still). You'd also get inconsistent timing because imagine what'd happen if one of the elements is halfway to its destination, and then the user scrolls so now it's gotta go to a new destination...if you've got a duration of 0.5, for example, it'd move a lot faster if that spans 800px than if it spans 50px. So the spacing between things could get a bit inconsistent. If your tweens are fast enough, people probably wouldn't really notice. But I obsess about this stuff. When you use a single timeline like this, all the tweens are created ONCE and interpolation is very fast. Plus you get totally consistent spacing no matter how fast the user scrolls or clicks the buttons. Cheaper, faster, more accurate and consistent. 🎉 Answers to your comments in the code Regarding the onRepeat that works around a super rare edge case bug that's fixed GSAP 3.6.1 - I'd keep it in there because 3.6.1 isn't out yet, and people may use older versions. Without getting into the weeds too much, if you go backwards over a loop threshold in a paused timeline (before 3.6.1), it could render (just for that one time) at the very beginning of the iteration. Since our demo is constantly tweening that playhead (with "scrub" tween), there would be situations where going backwards past the first element would have that tween start at the wrong value because the tween happened to snag the starting value at just that moment, thus things would appear to go back a whole iteration. // There are two fromTo because the properties have a different duration. // We want the cards to appear quicker. No, it's just because we have some properties that yoyo from the right side of the screen to the left (opacity and scale, for example) so they get big until the center of the screen, then go back down whereas the "xPercent" tween is consistently decreasing that whole time. So we need TWO simultaneous tweens for all that. These are NOT obvious questions and I'm glad you asked. It's a relatively advanced concept. I don't think I've seen anyone else take this approach, but in my opinion it has a lot of merit. Phew! Longest post in a long time. But I'm excited about what has been accomplished here.
-
How to control and move an object with a virtual joystick
Narendra786 replied to Narendra786's topic in GSAP
So the overwrite:'auto' worked perfectly. However, I haven't applied any bounds to the joystick because the outer container is circular and not rectangular. So, I just added some logic to end drag if it is a particular distance from center. Hence, maxX and maxY is simply undefined. -
(In Animate CC) I have been at this for a while but cant figure out how to restart an animation from the beginning values when I use an overwrite. A basic example. On "tl2" timeline a symbol scales slowly from 0 to 100. After 3 seconds "tl" timeline overwrites and scales this symbol back to 0. Both of these timelines are nested inside a "maintl" that runs on a endless loop. In this case when "maintl" restarts the "tl2" symbol is not at 0 scale but at where it was cleared and scaled back to 0 by "tl". How to restart the "maintl" so that scaling starts again from 0. var maintl = gsap.timeline({repeat:-1}); var tl = gsap.timeline({repeat:0}); var tl2 = gsap.timeline({repeat:0}); //tl1 tl.to([this.ring],{duration:0.5, scale:0, ease:"none", overwrite:"auto"},"+=3"); tl2.to([this.ring],{duration:6, scale:2.5, ease:"none"},"+=0"); //maintl maintl.add(tl,0)//starts at time of 0 .add(tl2,0) Thanks in advance.
-
How to control and move an object with a virtual joystick
ZachSaucier replied to Narendra786's topic in GSAP
Hey Narendra786 and welcome to the GreenSock forums. Currently every single time the onDrag function fires (which is a lot while users are dragging) you're creating a new tween that plays for its entire duration. That's not good. You should either use overwrite: 'auto' on that tween to make sure that it kills old tweens affecting the same properties of the same object or use a different approach like a more manual setting of the rotation probably using quickSetter (but you'd have to handle the easing and such yourself). To get the position, you will need the max distance in the x and y directions from the center point. Then you can use the current x and y along with those maxes to create a proportion. Then you can apply that proportion to your max velocity (or acceleration if you'd prefer) in the x and y directions to get a current velocity (or acceleration). Then you should apply that to your rocket. -
scrollTrigger: I need help with section fade-in/fade/out
ZachSaucier replied to RandallHolbrook's topic in GSAP
You can view what I did in the demo that I posted. From the tween vars docs: overwrite 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. That's @Carl's stuff -
scrollTrigger: I need help with section fade-in/fade/out
RandallHolbrook replied to RandallHolbrook's topic in GSAP
This was copied from one of the videos with the "Freds". Do I just use .to or .from and drop the tl? Also, help me to understand what "overwrite" does in: gsap.defaults({overwrite: 'auto', duration: 1}); I couldn't find it in docs. -
Hey Ivan and welcome to the GreenSock forums. Thanks for supporting GreenSock with a Club GreenSock membership! These forums are for specific questions, not general questions to help fix logical issues in your project's code. With that being said, here are a few notes about how I'd approach the situation: If there are less than four items, I would not show your buttons or create any animations. I would create a variable that keeps track of the current index. I would create a function that you can pass in an index to and it will animate the items to have the item at that index at the top of the cart section. I would create event listeners for each button that either increments or decrements the index by 1 depending on the button and then calls the function from the last bullet. I probably would not have a single animation and animate through the progress but instead create a new tween each time (making sure to overwrite any old animation) so that you have more control over how the items are animated. Since your cart is a fixed width do you really need a resize function? Hopefully that's helpful. If you have a specific question, especially about GSAP, let us know and we'll do our best to help!
-
Hover multiple elements - mouseenter changes width and moves other elements
ZachSaucier replied to darkgr33n's topic in GSAP
Hey darkgr33n. Step by step process through creating this effect is kind of out of scope for these forums. These forums are focused on GSAP-specific questions and while you use GSAP, most of your question is more logical. So if you have GSAP-specific questions please ask With that being said, I likely would try laying things out with flexbox instead, since the layout you're wanting is built into flexbox - taking a given width and dividing it up into parts. Then you just have to animate the flex properties. If you are going to use your method I likely wouldn't do any reversing - I would use new .to() tweens each time you need to change state. Also make sure to overwrite old tweens when appropriate (overwrite: 'auto'). Alternatively you could try using the Flip plugin to transition between states.