Jump to content
GreenSock

kreativzirkel

Tweening radial-gradient with ellipse

Recommended Posts

The forest of information regarding this is hard to travel through. 

What I'm trying to do probably won't be possible. So I hope to get some channeled and compressed insights about animating gradients and the backgrounds.

 

I basically want to create a somewhat "sunrise-experience" and therefore need to go ..

// from here
radial-gradient(ellipse at bottom, #ffed00 21%, #ffe808 42%, #ffdb1d 68%, #ffce32 100%); // 4 stops

// to here
radial-gradient(ellipse 200% 100% at center 73%, #FFED00 0%, #FFED00 1%, #36a9e1 40%, #003a63 100%); // 3 stops + 1 "faked stop"

.

But so far all I got was flashes after the desired duration, instead of an animation. (even with the exact same ellipsis and stops no animating results)

 

Important: animating the middle point of the radial-gradient would be really great; so I wouldn't have to fiddle with absolutely positioned height: 200% pseudo elements. Woooh!

 

 

So what are GSAP capabilities with radial-gradients? Is the ColorPropsPlugin the answer to my prayers?

Thank you, dear Elders!

 

 

René

 

 

BONUS: Any ideas how to animate from a linear- to a radial-gradient?

A workaround would be a suuuuper wide radial-gradient animating narrower. Would that be possible?

See the Pen YZLXYE by ka...ouis (@ka...ouis) on CodePen

Link to comment
Share on other sites

GSAP and the CSSPlugin do nothing special for gradients. 

However, GSAP is able to see multiple numbers in complex strings and animate them.

 

So if your starting gradient is:

 

radial-gradient(circle at 0px 0px, #0FC, #039);

 

and your ending gradient is

 

radial-gradient(circle at 250px 250px, #fff, #000)

 

GSAP will tween the first number in the first string to the first number in the second string. 

Then the second number in the first string to the second number in the second string.

and so on and so on.

 

GSAP will recognize color values like #fC0 and animate them appropriately too!

 

So as long as your starting and ending gradient are formatted the same and have the same number of numbers it should work.

 

Please see these examples

 

http://codepen.io/GreenSock/pen/56dc377001d36c64c154cc3a120098cb?editors=1111

http://codepen.io/GreenSock/pen/b384868de31e4ca46fb82f89c741f258?editors=0010

http://codepen.io/GreenSock/pen/c441e8b3071273acdc9254a221f88717

 

I don't have any suggestions for tweening from radial to gradient. Not even sure the browser could handle that.

Also, using keywords like "at bottom" in one string and not the other is a bit of a red flag too. 

 

If you still think you have a case that isn't working as designed, please provide a simple CodePen. 

 

Thanks!

  • Like 2
Link to comment
Share on other sites

It's still not working... and I don't understand why!

 

Like you explained the two gradients are formatted exactly the same an dI'm only tweening the ellipses width and y value here.

 

See the Pen YZLXYE by katerlouis (@katerlouis) on CodePen

 

 

EDIT:
it seems ellipse is causing the problems here. None of your examples featured ellipse.

I got my pen to work using circle, which unfortunately is not an option for me. 

Link to comment
Share on other sites

Remember this post?

https://greensock.com/forums/topic/16093-relationship-between-css-transform-translate-and-gsap-x/?p=70753

 

What you set in your CSS may not be what the browser reports. To animate a complex string like a gradient, it needs to be formatted the same way the browser reports it.

See the Pen KWxdNE?editors=1111 by osublake (@osublake) on CodePen

.

  • Like 3
Link to comment
Share on other sites

Yes I remember this post. But..

 

Hmpf; .. but why is the circle example working without converting the colors (in the tween) to RGB-functions? The browser also reports rgb-values when using circle.

 

Quickhitter: How would you convert hex-colors to rgb-colors with JS? Can GSAP do it?

 

 

BONUS:
here's a special one: How would you realize tweening lets say the width value quicker / different than the y value? I think something similar to your circle-drawing with canvas. Is it possible to tween different variables and then update these variables with an overlaying time-tween? 

Link to comment
Share on other sites

Not sure why the circle worked. What value did you use? It might be something the CSSPlugin can handle without the complex string interpolation.

 

For the color conversion, there's ways to do it using the ColorPropsPlugin, but if you're using jQuery you could do something like this.

var div = $("<div>");

div.css("color", "#673ab7");
console.log(div.css("color")); // => rgb(103, 58, 183)

See the Pen aa1e4c8acabe9e044a551da698ba5845?editors=0011 by osublake (@osublake) on CodePen

  • Like 2
Link to comment
Share on other sites

I used the same values for the circle; only difference is I didn't provide a radius for the circle.

You can see the working example in the initial codepen, when you use the commented lines.

See the Pen YZLXYE by katerlouis (@katerlouis) on CodePen

 

Maybe we find a lil bug here? circle working and ellipse not? What do the other Elders say?

 

What do you say to my BONUS-request? :)

Link to comment
Share on other sites

For the bonus, you can do it like my canvas demo. Just add the individual values you want to tween to a generic object, tween those values, and then in a update callback, combine those values into a string.

See the Pen MpqeKd?editors=0110 by osublake (@osublake) on CodePen

  • Like 2
Link to comment
Share on other sites

It's crazy. This method is so insanely powerful! Now that we generate the string by ourselves we can use hex or even string colors again, because it now is a simple color tween which GSAP handles super duper well!

 

I kinda see and maybe softly understand why you reverse() at the end of the timeline. 

But just to be sure: Could you explain why you used resverse() there and why exaclty .reversed(), which is just a setter / getter, also acts as a .play()? Or has the timeline never stopped playing?

Link to comment
Share on other sites

Hello kreativzirkel,

 

You will also have to add the syntax check for webkit so you can go cross browser since the radial gradient syntax is different to target various webkit android and webkit apple older and new versions.

 

Following examples use the GSAP ColorPropsPlugin.

 

Here is an example of a cross browser radial gradient - circle:

 

See the Pen BeJwd by jonathan (@jonathan) on CodePen

 

And here is one of cross browser radial gradient - ellipse:

 

See the Pen LWJReB by jonathan (@jonathan) on CodePen

 

I have spent many sleepless nights debugging gradients and their syntax. So it is very important, especially since Google webkit will change the syntax many times. Since in the past 5 years the CSS gradient syntax has changed like 8 times and Google Chrome has changed their implementation of it twice that amount.

 

:)

  • Like 4
Link to comment
Share on other sites

The .reversed() method is a getter and setter.

// Getter
var isReversed = tl.reversed(); // returns true or false

// Setter
tl.reversed(true);

So these have the same effect.

// This is the same...
var isReversed = tl.reversed();
tl.reversed(!isReversed);

// ... as this
tl.reversed(!tl.reversed());

Using that technique is just a shortcut for something like this...

if (tl.reversed() || tl.paused()) {
  tl.play();
} else {
  tl.reverse();
} 

And calling reverse at the end of a timeline or tween effectively pauses it. I explain more about that in this post.

https://greensock.com/forums/topic/13268-how-to-toggle-tweens-in-a-dry-fashion/?p=55018

 

.

  • Like 4
Link to comment
Share on other sites

By the way, the reason that the "ellipse" didn't work was because the browser reports the computed value WITHOUT that "ellipse" keyword, thus your two strings had mismatching amounts of values:

var ellipse = document.querySelector(".ellipse");
ellipse.style.backgroundImage = "radial-gradient(ellipse 100% 100% at 50% 0%, #266fb0 30%, #003a63 40%, #061a36 100%)";
console.log(window.getComputedStyle(ellipse).backgroundImage); //radial-gradient(100% 100% at 50% 0%, rgb(38, 111, 176) 30%, rgb(0, 58, 99) 40%, rgb(6, 26, 54) 100%)
  • Like 3
Link to comment
Share on other sites

Uff, I assumed it's gonna be tricky; but that many gotchas, eyeyey.

 

But since I am tweening the generic object and build the string myself I haven't had any problems.

So far I didn't need the ColorPropsPlugin aswell. TweenMax package seems strong enough with colors.

 

 

Thanks guys!

 

 

 

PS: I still didn't fully internalize how to play around with playing / pausing timelines or when best to create. Not a question for this thread, but maybe you have some quick links on this matter. Is it better to create a timeline early on, pause it on creation and then play it when needed or just create when needed? If you create it early you get maybe unwanted sets of .from() – 

Link to comment
Share on other sites

PS: I still didn't fully internalize how to play around with playing / pausing timelines or when best to create. Not a question for this thread, but maybe you have some quick links on this matter. Is it better to create a timeline early on, pause it on creation and then play it when needed or just create when needed? If you create it early you get maybe unwanted sets of .from() – 

 

Regarding the above: It depends.

 

In an ideal world, what you should really do is to check your code and where things are being initialised and how long they take. Then, you look into spreading the initialisations along the life of your app. Making use of idle moments to load/initiate secondary elements.

 

There's no particular reason to hog the thread for three seconds, for example, initialising all of you code, all of your animations, etc. If you can initialise a just section and move on to the rest of it if/when needed.

  • Like 2
Link to comment
Share on other sites

In an ideal world, what you should really do is to check your code and where things are being initialised and how long they take. Then, you look into spreading the initialisations along the life of your app. Making use of idle moments to load/initiate secondary elements.

 

 

How do you do that?

I still debug with console.log() :x – Never took the time to look into the timeline thing or the step-by-step debugging. Any prominent tutorials you can recommend on this? (Of course I will google myself, but if you guys already know one famous article on the level of CSS-Tricks' Flexbox CheatSheet, tell me :D)

Link to comment
Share on other sites

I'm afraid I'm going to disappoint you there as I know of no particular *holy grail* tutorial. I, myself, am still dabbling with it and learning the ropes. Hence the "ideal world" caveat ;)

 

But you know the tools you need to discover, you named them yourselves. We just need to get familiar with them - myself included. It also depends on which browser you develop. Chrome? Firefox? Safari? They all have slightly different tools.

 

I, too, do 90% of my debugging with console.log() - don't sweat about it. :)

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×