tgczan Posted October 29, 2022 Share Posted October 29, 2022 My goal: have an SVG (fill: gradient) animated to change into a different gradient fill. All this should be done dynamically, using GSAP v3 (maybe using gsap.fromTo()?). I can create the SVG dynamically. I can also create other elements like the <defs> and <stop> to go inside the gradient elements. At this point, I can have the SVG display the 1st gradient dynamically. And I can animate other properties (like size, speed, or location). What I cannot do, however, is animate the actual gradient fill change using GSAP. How do you do that? There are a lot of examples from others online, but what I've found only includes: - a solid color changing to another solid color, and back - a gradient changing to a solid color, and back - a gradient changing to another gradient, and back –> but does not use SVGs and uses CSS gradients instead - a gradient changing to another gradient, and back –> but uses GreenSock v2 with the stagger function (which, apparently, doesn't exist with GSAP v3) Link to comment Share on other sites More sharing options...
GSAP Helper Posted October 29, 2022 Share Posted October 29, 2022 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 starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo: See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen If you're using something like React/Next/Nuxt/Gatsby or some other framework, you may find CodeSandbox easier to use. Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. Link to comment Share on other sites More sharing options...
Trapti Posted October 29, 2022 Share Posted October 29, 2022 If you have below example CodePen then share that if it uses older GSAP code it will not be difficult to change it for GSAP 3. - a gradient changing to another gradient, and back –> but uses GreenSock v2 with the stagger function (which, apparently, doesn't exist with GSAP v3) Link to comment Share on other sites More sharing options...
tgczan Posted October 29, 2022 Author Share Posted October 29, 2022 Here are some primary examples: 1. This See the Pen MWwyJLe by malnurtured (@malnurtured) on CodePen uses CSS gradients. Although the 3 samples claim to be browser-dependent, it doesn't seem to be the case for any of my browsers. 2. This See the Pen OVWLOd?editors=0010 by dfranklinau (@dfranklinau) on CodePen creates SVG gradients dynamically, but then stays static. 3. This See the Pen bMxqYR by PointC (@PointC) on CodePen does use GSAP v3 but only transform gradient into a solid color. 4. This See the Pen MwbRoL by MAW (@MAW) on CodePen uses SVG gradients, but only GSAP v2 (TimelineMax). 5. This See the Pen WNoxoLP by garethj (@garethj) on CodePen is pretty weird. Its syntax suggests it's staggering from one gradient to another, but it's only going from one solid color to another – this may give off the effect of gradients in motion, but they're not true gradients. 6. This See the Pen ZWKmrK by jonathan (@jonathan) on CodePen uses SVG gradients, but only GSAP v2 (TimelineMax) 7. This See the Pen 56dc377001d36c64c154cc3a120098cb?editors=1111 by GreenSock (@GreenSock) on CodePen uses CSS gradients and GSAP v2 (TweenMax). 8. This See the Pen LYGXrMq by DickeySingh (@DickeySingh) on CodePen uses GSAP v3, but uses CSS gradients. 9. This See the Pen DgyRbB by rhernando (@rhernando) on CodePen uses TweenLite and Raphel.js. 10. This See the Pen XdBvEB by PointC (@PointC) on CodePen is good, but still uses TimelineMax. Essentially, I'm trying to produce a combined version of #8 and #10 (morphing between random shapes and applying gradient changes simultaneously). Creating the elements dynamically and appending them to one another is easy enough. How do I set up gsap.timeline(), or gsap.fromTo(), or MorphSVG to accommodate them? Link to comment Share on other sites More sharing options...
PointC Posted October 29, 2022 Share Posted October 29, 2022 You can target any or all of the stops in your gradient. Here's a fork of my demo you posted above. Instead of a tweening the gradient to a solid fill, I've now tweened it to a new gradient. Happy tweening. See the Pen RwJWwQQ by PointC (@PointC) on CodePen 7 Link to comment Share on other sites More sharing options...
tgczan Posted October 30, 2022 Author Share Posted October 30, 2022 Thank you, @PointC. Your demo was very helpful. I still have some questions regarding the syntax of gsap.timeline. Here is a sample See the Pen VwdvmMY?editors=1010 by tcwadr (@tcwadr) on CodePen Questions: 1. In your code, you write .to("rect", {attr:{stroke:"white"}}, 0);, I deleted attr and wrote it as .to("rect", { stroke:"white"}, 0);. It ended up working exactly the same. Can you explain what the purpose of attr is? What would be a situation where one would be required to include attr? EDIT: I double checked and placed attr back in afterwards. Everything worked pretty much the same except for the rotate attribute, which no longer rotates the SVG. I checked the documentation and see nothing beyond the few sentences there. How does one rotate with attr? Is there better documentation available for this plugin? 2. In one of the to()s, I initially used a parameter named stroke-width (copied from the <rect> element), but that caused an error. I then made a guess and turns out the correct word is strokeWidth – it was a good guess, but a guess nonetheless. Is there a list of attributes where one may find accurate available attribute names? 3. In HTML, the <rect> element's fill is defined as "url(#someID)", referring to the ID of the gradient element. In JavaScript, if I define the #rect's fill attribute as "url(#someID)", the fill color just stays white; or if I define the fill attribute as "#someID", nothing happens. Is there a convenient way to define to() and from() using fill (or some other attribute, like background) that can encompass the entire gradient at once? Or am I forever stuck with having to minutely change each stopColor attribute at a time? 4. Related to question 3: Because you can't just use "url(#someID)" as a fill in JavaScript, you seem to be stuck with the same gradient structure as you started with. How do I, for example, (1) animate from a radial to a linear gradient, and back? And (2) what if it's the same structure (linear/radial), but I just want to add additional colors or remove some colors entirely from the lineup? Link to comment Share on other sites More sharing options...
PointC Posted October 30, 2022 Share Posted October 30, 2022 1. attr:{} is the attribute plugin. I'm more in the habit of specifically targeting attributes that way, but in this case, yes - simply using stroke without that wrapper will work just fine. Sometimes a property and an attribute may seem the same but they aren't. A rectangle for example has an x attribute. These 2 lines may appear the same but they are not. One will translate x:100 while the other targets the x attribute. .to("rect", {x:100}) .to("rect", {attr:{x:100}}) If you specifically want to target an attribute, use the attr:{} wrapper. 2. You'll generally switch hyphenated properties to camelCase. So stroke-width becomes strokeWidth. If that's not to your liking you can also use the hyphenated version, but you'll need to use quotes. These two lines are effectively the same. .to("rect", { "stroke-width": 40 }) .to("rect", { strokeWidth: 40 }); 3. You can use GSAP to set a gradient fill with no problem. That will work with or without the attr:{} wrapper. // add a fill this way gsap.set("rect", {attr:{fill:"url(#someGradient)"}}) // inspect the element and you'll find this fill="url(#someGradient)" // add a fill this way gsap.set("rect", {fill:"url(#someGradient)"}) // inspect the element and you'll find this style="fill: url("#someGradient");" 4. I don't know that you could smoothly interpolate between a linear and radial gradient. A crossfade would probably be a better way to go. You can dynamically add stops with JS by creating the element and adding offset/color attributes, but since the gradient isn't rendered, I don't think it would refresh the changes. If you want to go from a couple stops to multiple stops, I'd probably add all the stops at the beginning and just set the color and offset the same on some of them so it will appear to only have two. You can then loop though and target any or all of the stops offsets/colors . I'd also add that animating gradients is pretty intensive so my recommendation would be to use it sparingly. Good luck. 5 Link to comment Share on other sites More sharing options...
tgczan Posted November 1, 2022 Author Share Posted November 1, 2022 Thank you for the explanations, @PointC. I really appreciate it. 🙏 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now