Whimsical SVG Animations Using GSAP
with Jhey Tompkins
One of the best ways to learn is to build things that make you smile. In this episode, Jhey Tompkins will teach us to build a playful SVG animation using Greensock.
Resources & Links
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
Welcome to Learn With Jason. Why is my -- look at this thing not loading. What's going on? Where you at right now? Come on, computer. Being betrayed by my technology yet again. Just nonstop. There you go. Okay. All right. It's back. Hello, everyone. Good sound, Tony. So, today we have Jhey, and thank you so much for joining us. I am absolutely thrilled to have you here and I think this is gonna be so much fun. So for those of us who aren't familiar with your work, do you want to give us a little bit of a background on who you are, what you do, all those good things?
How long have we got? I guess people know me or may know me through random whimsical demos that are spurred by ideas of me wanting to learn and make learning fun and share those ideas to help others learn. Maybe that's the easiest way to sum it up. I'm trying to get better at giving myself a little bio.
That was good. The chat is commenting on our beard. Whose got the better beard, put it in profile.
We're both wearing dark shirts.
Who wore it better, chat? Yep, you look like a Viking. I don't think I look like a Viking. I think I just look like an upside down head, you know, like, -- okay --
I can't really -- yeah, I've just got, like --
Oh, you're hiding hair under that hat. I don't know if I've ever seen you without a hat on.
No, there's a load of hair under there.
Yeah, rub it in, why don't you. [ Laughter ] So, today, we're going to do something that I think is really fun. We've been doing a little bit more of animation of, you know, Greensock SVGs and we're going to dig into that today in a really fun way. So I guess this is sort of your wheelhouse, right? You spend a lot of time in this very, like, playful, interactive kind of SVG land, and I think we'll take a second when we switch over to desktop for you to show a few of those. How did you get into this? Where did this come from?
I have no idea. No, I just started, like, messing around with stuff. I got into CSS, and when I started learning CSS, I started it backwards, so I started doing 3D and animation first.
Then I found CodePen and I just started making things. And, actually, Sarah, who has obviously been on and you work with is kind of inspiration. When I joined CodePen she was at CodePen, I think. She used to do a lot of SVG animation stuff. I'm going to get into that. I've always been driven by how can I create this, how can I create that? Oh, that looks smooth. That's SVG. I better learn SVG. I just kind of come up with ideas and then shoehorn technologies into the ideas to learn the ideas, if that makes sense.
Yeah, no, I get that. I feel that a little bit.
So it's more driven by -- driven by ideas instead of the tech. So, like, if I want to learn something, I focus on what I want to make instead of how I'm gonna make it.
I actually stumbled really bad the other day because I wanted to learn Houdini paint work, but I just didn't have an idea and I was like -- I just stood there on stream, like, I don't know what to do.
Yeah, I totally get that. I can't really sit down and say, like, okay, now I'm gonna be creative with --
Grid. It's like, no, I got to have something I want to make. Something that is making me smile already and I'll figure out what technology will make that work. Chat, you're really going to town on that beard right now.
I feel like -- do you know what? I actually have, like, beard lights ready for the holidays.
Oh, my goodness.
That could match the rainbow beard.
Okay, I'm not gonna lie, I wish you wouldn't have showed me. Now I'm disappointed that you're not wearing them.
I didn't know if it was appropriate. Maybe when we hit pause.
Always appropriate. We're lucky I'm not in a onesie. I did wear my square boys, curly boys, round boys, pointy boys. Brad made this sweatshirt.
Oh, yeah, Brad. But, yeah, I'm very, very fond of this. So, okay, I could joke about this forever, but actually I'd love to dig in and start. I no we got a million things we want to try to do. Probably not enough time to do them all. So without further ado, let's switch over. Before we get started, keep in mind we have live captioning provided by White Coat Captioning. We've got Jordan helps us out. LWJ.dev/live to follow along there. That is brought to us by -- generous sponsors of the show and give us the ability to make this more accessible to more people. With that being said, let's jump right into this. So go follow Jhey on Twitter. Make sure you do that. He is pretty much nonstop with very fun, creative things.
I never see this view. Like, you know the thing on the sidebar? Like, I wrote an extension to wipe that out, so I never see that. I didn't know that it bunches all your media in the top-right corner.
Get all that out of here. Usually I try to make it small enough that it hides that. But, yeah, so there's a lot of fun stuff going on here. Let's actually just go look at your CodePen for a second. Because this is a treasure trove of fun stuff. A lot of good bear jokes and -- what do you got here? Like --
There's a few. I just -- I just pushed up a -- the foundations of a new site. That DJ one is good if the sound comes through.
Let's see if it's working.
So if you hit the mute toggle. \M\M
That's really fun. Everybody, go play with that. So, yeah, I mean, it's just stuff like this, right? This really, if we go down to brass tacks, this is serving no purpose other than to make you smile, right?
Makes a great music player.
But, like, this is the stuff that I love. I love this part of the internet. I love this part where it's -- we're not worried about metrics or engagement or, you know, hitting goals or whether or not it's something you can sell. You're just trying to do something that's fun. That, like, warms your heart and makes you smile. And that's one of the things that I love the most about your work and, you know, the other folks who do things like this. Like, you know, Lynn Fisher is another creator like that. Cassie Evans. You can tell they had a blast when they made this. And I love that. So, today, you drew a Corgi for us.
Yeah, we're done. [ Laughter ]
Great show, everyone.
Check out the -- no. Yeah, well, I back and forthed with you on some ideas for this. We've got -- yeah, we got a lot to get through, if we want to make it do all the bells and whistles.
So I guess I could give you some routes and you could choose which way you want to go, perhaps?
Yeah. So just to kind of set the stage here, what we've got here is we have an SVG. So this whole Corgi is drawn as a vector.
Yeah, so I painstakingly drew this earlier today.
And did you do this in --
No, I did this in Inkscape.
What I did is I found some Corgi images and put them all on the page and kind of took the bits I liked and kind of made this one.
And then I've brought this into a Pen where I've gone ahead and added all the classes and things for us.
Okay. Yeah, I can see --
Already got things in place.
Yeah. And this is, you know, this is really helpful because otherwise we would have to go in and, like, hide these to see what disappeared, and that's kind of a pain. And not really good TV. So --
I've noticed I left it on stylus, but that isn't too much of an issue. We can convert it to CSS if we need to. If you've not used stylus before, it's a first time to have a look.
You know what? We're going to use stylus today. I get this. It's just CSS with no punctuation.
Basically. It accepts punctuation. It's kind of interesting.
You can put it in and it will -- yeah, all I've done here, I actually haven't done anything crazy in here. All I've done is set all the colors for the Corgi. So you can change HSL in places and it will switch colors out. All I've done is change the hats and things. That won't do much. That's the shadow on the bottom.
Yeah, this is for -- this is like bonus level, if we get that far.
Okay, cool. So, what are a couple of things that we could do today?
So, I didn't know if you'd had anyone on yet that had made a party Corgi, so I assumed we would make one.
We absolutely can make a party Corgi. Chris and I have made -- we made an animated GIF generator. Chris, we need to resurrect that. I see him in the chat right now. That was a fun idea, but this is kind of a new angle.
And obviously I went through that stage of, like, I created all the party eggo, party bear, through all the discords.
Yeah, yeah, yeah.
I thought naturally it might be a good idea to do that for this. So what we can do is, one route we can do is party up this Corgi.
And the pieces are in place. So we can -- that's probably gonna be quite a fun one to do.
I think we have to. I think if we don't, you know, if we don't, the chat will be furious with us. They're already -- we're, like, above 30 Corgis already. It's been a while since we've had a Corgi storm.
I'm waiting for it. Come on, chat. So, where to start? So we can start in -- so if you go into the SVG, and you see there's like a -- there's some commented out stuff there?
If you go up a little bit more, there might be some more. Yeah, there is. There is this piece here. So if you uncomment out the --
Oh, here we go. Stampede. I got to get this sound back in. These are -- these are very fun, but they need to have -- we need more. Oh, no, I broke it.
Oh, yeah, just remove that top one. I was just messing around with it, so I --
Now it's a Corgi gem or whatever it is. Ice gem. If you take the click path off of that thing that we just did --
Take the click path off?
You can uncomment that one as well if you like, but I was actually going to show how this is working behind the scenes. So if you take the clip-path off of that group, and then his this should just show a big -- there we go.
So that's what's actually happening. If you scroll up, you see a defs tag. You see these rectangles, that's essentially that element and it's inside here.
And then what we're doing below is we're just saying use that group here. In this --
So, what I'm gonna --
Well, and so -- so when we say -- so, here we're saying use the party, right? So that's that kind of square of rainbow. And then the clip-path, we're able to -- we're able to say, like, this is the body.
To get to that body.
So we're just saying the party is only visible inside the area of the body?
This is -- so this is something that is really interesting to me from the standpoint of SVGs. Like, if you haven't worked with something like, you Know, Photoshop where you've got the concept of masking, it might seem like any time you've got an SVG if you wanted to do a different color or whatever you would have to create different versions of the same vector, but with the clip paths here, we can put a photo in here and the size of the body.
This is a really important trick, especially for this -- especially for these party lines. Like, it's kind of one of the things that prompted me to get into doing more clip-path stuff. So, if you were to -- so, I kind of want to explain the problem in a way that you can see what the issue is. So, if you were to go into -- let's go into the scripts. And we're gonna do something -- yeah, we're gonna uncomment that top line.
All right. Here's some -- here's some GSAP Greensock. What is the AP in GSAP?
Not animation party?
We're doing a Skypack import. I don't know if you've seen that yet.
I have not, and this is very cool. And does that mean that we're just straight up -- this is any NPM module, well, that can be supported by Skypack.
So any NPM module is available through that CDM.
As long as your script is type module.
You can use it like a basic import, which is quite interesting and makes life pretty easy when you just want to pull anything in.
So, I'm gonna be annoying. I'm going to say go back to the SVG.
We're just going to keep going around in circles.
Take the -- take the clip off of the -- take that clip-path body off for a second. One way to, like, do it sometimes is just comment the line, yeah, or do that.
Oh, yeah, that's a good point.
No, that's cool.
Let me do that so I don't, like, lose my clipboard and then have to remember how to do this.
There we go.
So, if we go back to the JS, and if we do a-- uncomment the fourth, fifth, sixth. That little block. GSAP.partyset. So what I'm saying there is I want to rotate the lines. So they're gonna go at an angle, if that makes sense.
So we went negative 45 degrees.
And we could also do -- so you could put X percent in here to do, like, 0 and kind of see how it manipulates it around. Sometimes it's a bit trial and error. There we go. 0 puts it kind of where we want.
But the issue here would be, now if I did the next line, which would be GSAP.2.
This is where we're going to start animating. If you want a breakdown of this, we get a really good intro to this from Cassie Evans. So let me grab that episode real quick. We talked about the GSAP.2, and we played with some of the features there. So that's -- but I -- and I can see what you're saying here, this is -- it's kind of not staying where we want it to be.
Yeah, so the issue we have here is that, like, to make this animation continuous, we need an extra set, so that's why if we go back into our SVG, then what we can do is create a second group. So you see the G party? Not the set, just the one inside it.
So, if you take that group and then duplicate it --
Yeah. Now you have two.
Now, if you go back to the script -- [ Laughter ] And you see that one that we've left commented out? That's essentially saying move it down 100% so it's beneath, and then move the whole lot.
Oh, I get it. Okay.
So you see what's happening now?
And that's how we ended up with the 50%?
Or 50%, is that put it is in the middle now.
Yeah. And then the clip will rainbow line inside the lines.
And, like, check this out because we can see what's happening here, is that it's moving and you can see, like, just for a brief second, you can see the top of this one and then the bottom of this one comes out. And so it's -- it's just running on loop, but you created enough length that it can fully cycle, which is pretty cool. And so then when I come up here, I will get rid of this one and we'll uncomment this one. And now we have Party Corgi. That is slick. Okay, and now for the face, we would do this with --
So, we don't need to do any more in here, but what we can do is we can take this whole -- so we have, like, the party set.
But we want to duplicate the party set. So if we take --
Don't we also need to get a --
We don't want the clip-path piece. We just want the set.
Oh, I got you.
So if we take the set and move that into the defs up above. So you see how we've done "party?" We're gonna create a new one and give it an idea of, like, I don't know, Block Party.
And then if we take that -- and then we use Block Party where we did the body clip, so --
So now instead of a group, we'll just do a use href, if I can spell it right. It's block party, I think is what I just called it.
Yeah, that should work.
And then where the face was, we can apply it to the face as well.
Okay. And now the face, we're gonna copy and then we're gonna find the face, which I assume is lower because --
SVGs, the thing at the top of the SVG is the bottom, and it, like, layers on top, right? So because this is behind the face, then we can look lower. SVG detective work right there.
If you ever do, like, the single div or no div CSS stuff, it's the other way.
Oh, come on. Couldn't just be predictable, right? I broke his face. No, there it is. Okay.
So now he parties.
Now we got a party Corgi.
You'll be able to, like, update his duration to make it speedier or however you want to do. Or whatever we want to do.
That's really fun. And so, you know, this duration is -- this duration seems good, but if we want him to be faster, like really party, we can go say, 1, now it's like turbo party. If that was maybe too much, we could go to 3. Now we've got a pretty chill party.
I do like 2. I think 2 is good. Here is our Party Corgi. We're partying. I love this. This is fun.
Next, we could do -- so we got two options here. We can either do -- we can do some mouse movement stuff.
Or we can hook up -- maybe we should animate the features of his face a bit. Make him a bit more --
Should we put it to the chat?
Chat, what do you want to see? What are the options again? So, we can animate the face?
So we can do some face stuff or so, like, it would be features, movements, or we can do speech recognition.
Animate. Two votes for animated face, face, face. I think everyone wants the face to move. Face stuff.
It's okay. The speech recognition stuff is, like, in place, ready.
So maybe we can just play with that at the end. Let's do face animation and then we'll play with the speech recognition at the end.
Okay, cool. So I've got kind of an idea how -- so, let's say we wanted to just do, like, head tilt or eye movement or something like that. What we could do is if we set like a bounds that we want, so if we imagine that if we move the mouse on the left side of the screen, we say we want the eyes to shift, like, to the left 10 pixels or likes 10 pixels either way depending on where the mouse is --
GSAP gives you a nice little utils thing you can use.
To do a mapped range of values. So what you can do with that, if you add an event listener.
All right. Add an event listener. Just like a -- like --
Yeah, if we do it on Window Or Document. And then we did something like pointer move.
It needs to be Window, doesn't it? Is it Document? I can't remember.
I always opt for window.
Yeah, I feel like for the window, for mouse movement especially.
And then if you did, like, what I tend to do is I destructure the XMY in the -- yeah, in the -- and then what I might do here is I might say, like, outside of here, I might define, like, eye bounds or something weird like that. So I might say, like, eye bounds is, like, 10 or something like that.
And then inside, I would say new, new x or something like that.
Like that? Camel cased?
Yep. And then 0 inside it. And then window inner width.
Okay. And then minus eye bounds. Sorry, that should have been a comma. I meant, like, negative eye bounds.
Oh, I got you. I got you.
Yeah, my bad. And then eye bounds and then x as the last.
Okay. So let me see if I can talk through what we're doing right now. So, with this, we're saying the range we want is -- if this is 0, we can go to negative 10 pixels to the left or 10 pixels to the right?
And whenever the pointer moves, which is mouse movement like this, we're saying we want the X and Y position of the pointer. So wherever my mouse is.
And then what you're -- what this util is doing is it's saying take the 0 to the inner width, which is, like, left all the way to the right, and then map that range. So if I'm at, like, let's say this is 100 pixels wide and I'm at 50 pixels, I'm right in the center?
And so then that's gonna take that percentage and apply it to the range of eye bounds, of negative eye bounds to eye bounds which in this case would be 0 if we were at 50, but if I were at 25, it would be, like, negative 5 pixels.
It would work out proportionally.
The first two are the inputs and the second is the output for it, and the last piece is the value to map on to the inputs.
I get it. I get it.
So, then after that line, if you did a GSAP.set, and then we can do comma. Is that right? Apostrophe. I'm not one for grammar. It's a class here.�.Corgi__eyes. And then X is new X.
X new X.
And that should do something.
Oh, look at it go. Way too much but --
Way too much, but that's fun. That's pretty fun. Okay, so let's turn this down. Let's call it, like, 4. We'll make it pretty subtle, I think. Or even that feels like a lot.
That's pretty big.
Maybe we just go 2. Maybe it's a real subtle.
I think I might have done it -- I think when I put it together, I put it on such a small scale that it might have to be, and I sized it up in a transform, so now it's probably, like, one or probably.
Okay. So I can do -- I can even, like, do this again. Let me see if I can do this on my own. So if we wanted to also do a little bit of up and down, let's see, X bound and we'll do X bounds and then we can do Y bounds and Y bounds.
One little trick there is sometimes just to invert the X.
So if you do the opposite. So negative eye bounds, eye bounds. Then negative eye bounds, negative eye bounds, and if you go down, it will go up.
Oh, interesting. So you're saying, like -- so if I do X of newY, newY, so now it's kind of following me around here. Which is fun. And then we can probably turn that down a little bit. So you're saying if I swap this --
Yeah, so originally when -- if you use the same X, I think, and then you flip it so it kind of, like, inverts.
If that makes sense.
Oh, okay. I don't know that I'm fully following that. But we're getting a cool -- like, we're getting a cool effect here. It's kind of looking around with us. Like, that's pretty fun. And that is way easier than I would have expected. Like, and then it --
This is a little head-bendy math. What is -- get away from me, Slack. I swear, I always close that window and it opens up on its own. Slack just keeps pulling me back in every time. I think I got out.
The trick after this would be. So then you'd then add it to all the little features. So, like, you could group the entire head and make the head tilt.
Okay. Yeah, let's do that.
You can make the head tilt. You can make the hat, like the top of the hat move.
That's really fun.
I may or may not have catered for this. But I haven't grouped the head. So that will be something that we need to look at.
So we've got the Corgi white, the Corgi stroke. Corgi outline. This -- so, I'm gonna make a guess that this is where the head starts, am I correct in making that assumption?
We're gonna find out.
Okay, let's see. [ Laughter ]
This is like, yeah, this is the realistic experience of working with SVG, right? This is like the pain you go through when you have to convert it all. Like, if you want to do this stuff, you have to spend of time and expect it to work out.
So, there's a couple of hidden elements in here. So, like, we could have done something like make the tongue wag and things like that.
But there is actually a Christmas cracker hidden in here as well.
Good. I would have been -- I would have been heartbroken otherwise. So, okay, so I think I just styled the head. So, let me just test that by quickly decapitating our Corgi.
We're just going to go for a display none?
Oh, wait, I used punctuation.
That's fine it it will let you do it.
Did it work? I did something.
Did you wrap them all in a group?
I thought so.
Let me have a look.
So, I've got my -- Corgi head.
Oh, it's because it's the indentation. I think. Yeah.
Come on. Okay, so, I missed a piece. This Corgi white I think needs to come up. Let's move that up.
Now it's an ice gem with a leg.
Okay, that's a little bit better. Corgi outline, Corgi stroke. Let's maybe pull this one up and see what happens. Yep, that needed to be out there. Let's pull this one up and see what happened.
Chat's echoing the sentiments about your Minecraft power.
Hey. Come on. It is a party potato. I like -- yeah, this is our party potato.
I thought it was a mushroom.
Yeah, that's --
Getting closer. What are you?
I think that's all of it. Just missing one. His back leg.
Yeah, back -- okay, so, back leg. Maybe Corgi head.
Almost there. Just a bit of Corgi whiteness.
Whoops. Here. Yes.
And then this is actually head. So, oh, I also --
Halloween, the headless Corgi.
So this is collision, so I'm just gonna group that real quick. Okay, so now we've got -- we've got a head group.
And we can use this class however we want. Let's revive this Corgi. And now we're ready. So if I wanted to move this, I could -- what -- how would you -- what would be a way that you would approach this?
So you can go about it exactly the same way and see what happens, but generally I would go to set the transform origin on the group first. And then find, like, an origin that feels more natural. So, like, 50/50 probably won't feel right because, you know, your head doesn't pivot on your nose.
It's gonna be super weird, but let's try it. So, to do this, I guess we can just like GSAP.2.
Yeah, even just to test it, run it in the set and let it rotate and see what it looks like and kind of get a feel for the bounds without actually doing any animation.
Oh, jeez! No, that was incorrect. Okay, maybe 10%? That's worse. That's so much worse. Let's stick it to the bottom. Then what happens? Oh, jeez, what are we doing? What am I doing wrong?
It looks brilliant, though. Its expression says it all. That's strange because the transform origin should be correct.
50/50 and if that is a group, 50/50 should be right, so I'm wondering what is happened there.
Oh, I wonder if I -- oh, another stampede. Oh, oh, oh, here we go. I'm wondering if I put the party group inside of this group, which would blow out the bounds, I think.
It shouldn't --
I think I did.
It shouldn't matter, though, because it needs to be in there. Because otherwise it will lose the animation.
Couldn't we -- but couldn't we move it outside of the group, though?
Oh, yeah. Yeah, we could, and then the -- yeah, we could, so it wouldn't rotate with it.
Let me try --
Oh, but then it won't animate.
That would be interesting, though,. Yeah, actually, do this. This will be interesting because something -- yeah, something will happen here, which you can kind of see.
So it did -- it did fix that initial problem, which is that we want it to be -- so if I set it to 100%. That's a little more. I think it would probably be a 90, but -- that feels a little more natural, right? It's a little closer to what you would expect -- the head stays where the head is supposed to be. Jeez.
I kind of like the headless version.
Yeah, Nearly Headless Corgi. But this feels good. That kind of looks like a dog cocking its head, which is what we're after. But we lost our party clip.
Yeah, and I think the way we would resolve this is at the same time as rotating the head group, we'd actually need to rotate the idea face because we need to rotate the clip so it goes with the block. If that makes sense.
Gotcha. I wonder if this is just gonna do what I want.
Yeah, if you put them in -- yeah, that's --
That's -- oh, it's so close but not quite there.
It just needs -- it's because the block is now moved, oh if you actually put the block back in, it will probably be all right.
But wasn't this was blew out the origin? Because the party is too big?
Oh, yeah. How do we get it in front?
So I think the way we get it in front is we make the fur transparent, right?
Yeah, we could just remove --
Oh, but then we would lose the --
No, because there's extra -- so what I've put in place, I've put in place -- I did all the rotations before I did the party lines. I've not done rotating party lines before, but there is extra element in her for outline. There will just be an outline of the head with no color in it, purely for the purpose of blocking out things that you don't want to see. So what you can do is you can just adjust the stroke on it and make it bigger. We need to work out which one that is. It's probably that one, which is Corgi clear.
Yeah, I think you're right. So if I knock this one out.
So that's gonna be --
Nope, that's not the one. Where's the fur? I thought I had the fur for a second. This one.
Yeah, that one.
Just got a little lost in the SVG there. You know, this isn't perfect, and if we were trying to, you know, do, like, production-grade something we were going to ship, I would say we should probably mess with it because it looks like we've got, like, a couple of pixels of misalignment. However, for our purposes, I am extremely happy with this. Like, this is super fun.
It would purely be a little bit of -- there is an extra element in there, and it will just be a case of bumping the stroke size and it will just block whatever's behind it. There's not much to it. I think it would be -- and this one here, stroke width, we could just go, like, 1 or something?
You can probably just change it insight the CSS and it would bumped it up.
Okay. Let me get in here. And this was called?
Corgi stroke. There we go. 1.25 or something. 2 might blow it up.
That's way too much. You were right.
Fine margins. There you go. That's almost hidden. It's slightly.
I mean, you have to look pretty hard to see that and I don't care, so let's ship it.
It looks good, though,.
I think this is super fun and now we've got, like, we have a Corgi that's looking around and, you know, when you first load the page, it rotates its head, which is really fun. And we could, I guess, how would -- like, could we do this on, like, a -- well, I kind of want to make sure that we get to everything that you want to get to. Instead of me coming up with ideas.
No, you're driving the ship here. You just make requests.
My thought is, can we have it on, like, a little bit of a loop?
What, so like it nods back and forth?
Yeah it would be kind of formal or looking straight on. After a few seconds it would cock its head.
I have a little trick for this because I don't like it to feel the same all the time. So I do this a lot for eyes, and I actually pretty much use too in any Pen where I have eyes and I'm using Greensock, I use the same little block of code over and over. What I'd to is create, like, a timeline and I'll call it, like, so if I was doing it for eyes, I'd call it, like, blink. For us, we can create a function called nod or something like that.
A function called nod?
Okay. You can do cons nod equal whatever if you like. Or we can do function.
Yeah, I'm up for whatever.
And then in here I'd just create a new timeline.
And that's GSAP timeline?
I have to pass something through that, right?
Well, you could -- you don't -- what I tend to do in here is so I would use one of the call back functions. So, essentially the trick here is to create a timeline where you say, right, nod one way or another, and then when I've nodded to that point, and maybe I repeat and come back to the middle, and then I say on complete, call this function again.
Oh, I got it.
It will generate a new timeline. And then what I'd do is just say every time around create a dynamic delay.
So each time might be like, oh, he blinked after 2 seconds, then it was 4 seconds, then it was 10.
And you can take that even further with, like, you could have the speed of the blink or in our case, like the number of degrees or all that stuff could be kind of calculated every time the function fires. So you would get randomness, which is really interesting.
Yeah, and that's something I really -- when I first started playing around with Greensock it was something I was interested in. I don't blink myself, like, every three seconds. I want it to feel more natural like there's more gaps. Or sometimes I blink twice.
I feel like that's the magic, right? That's why I think with a lot of animation stuff, if it doesn't get -- if it gets too close to realistic and it isn't obviously a cartoon or whatever, we hit that uncanny value where it's like almost unsettling to look at it. I think a lot of humanoid robots that we see are kind of unsettling because they look real but they don't act real. Like, they feel unnatural, and that's kind of unnerving. And so what you're talking about here is kind of disarming that. It doesn't have the mechanical repetition that a robot would have. It has a sort of organic quality to it, which is really nice.
Yeah, try to just give it a bit. Yeah, a bit more, like you say, not so uniform. A bit more character to it.
So I always say to anyone that asks about it, just, like, look for small winds. So one thing that always stuck with me is that the best animation is the animation that goes unnoticeded. So something that almost feels natural that notice, but because it's there, it feels right.
If that makes sense.
Yeah, it --
Philosophical over here.
It feels appropriate to the setting versus something that demands ranges.
Yeah, as opposed to I learned this thing, now I'm gonna use every single feature on the page.
I saw somebody shared a theme the other day on Twitter that was, like, somebody had learned how to do the fly-in animation on Scroll and every element on the page flew in from a different direction. So it was just, like, unbridled chaos. As you scrolled down this page, it was like pew, pew, pew. You could tell somebody just learned that and they were so excited about it.
That kind of backs on to -- so, obviously I was very fortunate to get early access to Scroll Trigger, which is what powers that DJ demo. Naturally, the ideas were, right, we need demos for scrolling demos. Well, most people instantly think of the fancy, you know, publication layouts. And my first idea was scrolling through a book, and then it was scrubbing music. Like --
You did one with an apple, too, right? Where as you scrolled, the apple would get more and more bites taken out of it?
Yeah. That was -- I ate three apples that night.
So, I mean, it's great. It was good for your health. [ Laughter ]
I genuinely like -- I got my partner to -- she has a proper DSLR camera and she set it all up with lighting to take photos of this apple. Right, I've got to eat another apple, I've got to eat another apple. Mark it out, spin it. Yeah, I just tried to do a take on as you scrolled, it did the stop motion and then it did, like, SVG masking with, like, a video behind it. So, like, an apple would shoot out and then reveal a video.
Which is cool, so, like, I did that purposely to mess around with those turquois and learn -- techniques and learn how to reveal video. That wasn't for ScrollTrigger. I did one where Pinocchio's nose grew and I did one where it fired a gun as you scroll.
Oh, I remember. It had like the bang flag. That was so good.
With the Greensock on it. It was all sitery and turbulence. Like, yeah, I didn't want to --
Yeah, yeah. Oh, Chris has terrible ideas in the chat. And now you all get to live with this terror. Everybody get ready because you're gonna have a nightmare. Oh, it's the worst. You got to have the creepy voice with it after that. It's like, hello.
It's "The Exorcist" Corgi.
Would you like to party?
What about if when we spin its head round, then his eyes go green.
No, okay. All right. This is -- this is the worst. All right. So let's make this timeline work.
Hey, this is what happens, right? This is where the ideas come from. Just tangents of ridiculousness.
Oh, my God. Absolutely. Give myself nightmares with that. Jeez. Okay. So we have -- we have a timeline, and I'll be honest, I think I've used timeline, like, twice before. So I don't really know how any of this works. So you'll have to kind of guide here.
So the joy of timeline is that you can essentially just chain everything you need.
So you can do -- and in the older versions of the API, and I was terrible for continuing to write it in this way that you don't need to anymore. You can just write things -- so, a general timeline. Like, if we said, right, the Corgi's head's gonna spin 180 degrees and then his eyes are gonna go green. We'd do GSAP.timeline.2 Corgihead. But the joy is that when you do something with a timeline, obviously you have a block of something that you can use or reuse or even generate elsewhere. So, like, commonly in some of my demos, I might generate a timeline dynamically and then add it to a master-like, a main timeline. So each time I get, like, a different behavior. So a good example of that would be -- I don't know if you've seen the demo where it's like a toggle and the bear paw comes out?
Oh, yeah. Yeah, yeah.
So each time that happens, it generates a new timeline with different timings/actions because it wants to, like, decide what it's gonna do at that point. So it might be like this time it's a head. This time it's gonna swear. You know? It's not added beeps yet. That's what needs to come in. It gets progressively angrier and then --
Bear growl. That's really fun.
Did the V2 recently which was the light bulb one.
Oh, that's right. That's right. I remember. Oh, let me share a link to that before I -- yeah, and then we've got the -- your light bulb. Is that on the homepage here?
That will -- it's probably easier for me to find that one. My problem is if you go into public, it just takes. I didn't realize -- obviously it's getting near the end of the year and people are starting to do, oh, what did you do this year? I'll have a look. My word, I created a lot of pens.
Yeah, you did. Holy crap. This one, impossible light bulb. This is fun. So you can pull it any direction. [�Door slams�] So these are all timelines then?
Yeah, this one is different timelines. So I think -- yeah, there we go. And then you're like angrier. This one's more of a speedy one. [�Door slams�] It's quite interesting, the check box one was, like, one of the first -- probably one of the first Greensock things that I did. Because I wanted to see how you'd use with React, so, cool, I'm going to make this bear with React and GSAP and see what happens. Yeah, and then this one was -- I was trying to come up with -- I don't know why. I was thinking of light toggles for site design and I thought what if I could make a cord? What if I added a bear? Actually, when I dropped it on to the site, no, it doesn't look right. It was a cool thing to make.
It is a cool thing to make. It's a lot of fun. So with this, this is just kind of a tangent question, but you made a like sort of physics here. [�Door slams�] How exactly is this --
So, this is actually why I'm rebuilding my site, so I can write about all these things because they just get lost and people don't -- I forget how I do them sometimes. But there's a trick to doing these. So for this one, what I did was I got the cord and I actually found, like, I looked at gifs of light toggles.
What a fun Saturday evening. And what you can do -- if you actually open a GIF in preview, you can see it frame by frame. And then you can click through it. And what I did was I worked out -- so the infamous notebook. Where is it? Okay, I don't know if you'll be able to see it, but what I did is I sketched out the different steps.
Oh, my God.
Of what needs to happen.
And then draw each path and then morph between the paths.
And just happened I got the timing pretty much right first time. So that was a nice relief.
Yeah, no kidding. That's really cool. This is really fun that you can do something, again, that this feels kind of alive. You got that bounce and you know --
So there's two things happening here. There's a draggable plug-in.
And there's a morph SVG plug-in.
So, essentially what happens is -- and I got some help from Zach at Greensock with the draggable part because I wasn't 100% sure how to do it. But there's like a big circle in the SVG there, like a hit spot.
And that's like a proxy for a drag handle.
And when you click on it and then drag, the cord moves to wherever pointer X and Y is, and then on release, I just shoot it back, and then what I do is I quickly do a morph SVG between the five or four stages of the cord.
And then it does the click at the same time.
So it's --
Yeah, it's good, and it feels natural, which is nice. Okay. So, tangent complete. I am satisfied. I feel like I've got more things to go learn now. Let's get this randomized Corgi head going. So what I've done is I've moved this rotation. So let's get it back to where it was, so 15 degrees. And then right now if I just call nod, I think this -- that will probably break, won't? It won't do anything.
It will just do an empty nothing, which would be fine. Yeah, what you could do then -- so let's say you do of the 2. If you're only doing a 2, like, if you only want to nod between certain degrees, what you could do is in the 2, you wouldn't need a timeline for it at all. You could just do an on complete and then call nod again and it will just call GSAP.2. What you can do outside of the 2 is rent rate a random delay or use GSAP's random delays. So where you've written "rotate."
So, instead of making a timeline, we would be able to do this and then on complete.
We can call nod?
We probably don't even need to do that. We can just pass it in as --
So, to see, like, to see something interesting, if you just change the 15 degrees to plus/equal 15 degrees, I think it will work.
Oh, no. This is gonna be so bad. Oh, God. Come play with us, daddy. This is horrifying. This is the worst thing that we've ever done. No, no, okay, we got to stop that. That's too much. That's too much. A little too much -- a little too much jolly.
There must be some audio we can find to go with that, surely.
Just a creaky door. But what we could do that would be kind of fun is we could do -- we could do, like, degrees and we could do, like, a math random.
But then the -- the real magic is that --
Oh, you got some stuff?
This is built in.
What? Come on.
If you change that rotate string to random.
To straight random?
Yeah, random inside the string and then give it, like, an up or a down vary. So, I don't know. Yeah. I think -- I don't know if that will work like that or if there will need to be.
Look at it randomizing the -- I mean, this is -- okay, so this is fun, but we have to figure out how to move these as a unit.
Yeah, so, what we could do is we could generate the -- so what's happening here is because it's obviously taken the array. It's doing a different one for each.
So what we could do is we could generate the randomness outside, but there is -- you can use this function standalone as well. So you could do, like, cost, r degree, minus 15-15 and then pass it in.
GSAP.random, like this? Utils.random and then as strings?
I've not done it before like this. Let's find out.
Let's find out. And then we'll drop this in here and let's see if it works. That does not work. So let's go with --
Let's just go with a number and then -- yeah, that should be fine. That should work with the number.
There we go. That's fun. Okay. So then we need, like, a delay. So, yeah, for delay we could do -- we can just do the same thing again. We can just do a random, but it will need to be outside so it said sets on both. Otherwise, they'll probably go off on their own accord. We set a delay. GSAP.utils. We'll say, oh, it's in seconds, isn't it? We'll do between one and four seconds. Okay.
Actually looking at this and now it just reminded me, I actually made this nodding recurring thing not long ago.
I did a "Men in Black" themed Codepen. It's like Orion's Galaxy, like the cat. You click it, it zooms in and reveals a space turtle inside his necklace. But, yeah, I had to do, like, a random nod for that.
So do I just do delay?
Oh, no, sorry, so what you can do is you can just pass delay in as a property.
Oh, like in here?
Yeah. So you won't need to -- yeah, okay.
Did I do it?
This is awkward. That should be fine.
Maybe it needs to save or something. Hello?
Is it called something else or, like --
No, that should be.
GSAP something. Oh, look at that weird thing that I did up there.
Oh, I couldn't see it in the of the -- I'm watching the call not the --
Look at our happy little Corgi.
That's good head bobbing. That's fun. I like that. I am definitely happy with that. That makes me smile. So, we've got about 25 minutes left. What would you like to do next?
What does chat want to see? I mean, I thought it would be fun if we tied up speech recognition with the party lines. Just because it would be kind of cool. And I have -- I do have like a clip of audio you could put with it, potentially. So, this whole block that's all commented out is all the speech recognition stuff, but to do this, what we need to do first is stop those lines moving and set them as a timeline. So this is like the neat thing about having a timeline, is that you can pause it on and off.
Okay. So to do that, I'm gonna come up here.
So just that -- put that last block is the one. So we could call it, like, "party." Yeah.
That's gonna be a GSAP timeline. And then I can just pull this 2 right off of it?
Yeah, and just chain it right on the end. And then what you want to do, is inside the brackets for timeline.
If you put an object inside there. And inside it give it paused true.
Okay. That should stop. Cool. So, now we just have a Corgi chilling.
And if we go down and have a look at this speech recognition block --
Yeah, let me uncomment this so we can see what's happening.
Yeah, there's quite a bit here, but it's --
Okay. So, immediately what happened is it asked for access to my microphone, which is really fun. And, actually, something that's really interesting here, you are not importing a new module for this. So this is built into the browser?
Yeah, I think it's -- I think Safari will do it and I think Chrome does it.
I hope Chrome does it because that's what we're doing.
I couldn't remember if Safari did it or not. But what we -- so, what I've got in here is setting up speech recognition essentially in enUS Lang with continuous listening.
What I've set -- what I've done here is basically written a small block of code which will make it behave like Alexa or like Okay Google. So what we have here is these are the commands, and I'm just setting the background color to a different color just so it's clear that, like, it's listening.
And what will happen is -- so you can leave -- so the commands which come through are actually the things we say.
Oh, I get you. I get you.
So, yeah, what I've done is mapped commands of things we can say and then --
So is this the one you needed to update?
Yeah, if you change that to party timeline.
Okay. So now if I say "party."
No, you need to say the magic word first.
Magic word? Please party.
You can change it to -- so, that's the keyword.
Oh, I see. So you see set this up when you said Alexa like, what you meant is that you have to, like, tell it to listen. So it's not just if I'm saying, yeah, I'm gonna go to a party later, it's not gonna start doing something. So I have to say Corgi party.
It's very sensitive.
Oh, that's so much fun. And this is incredible because this is just working on -- I did activate at least just one Alexa. But this is really, really fun because is it means that, you know, yeah, if I -- so I can change these.
Yeah, so if you change that. And I just -- you see where it says party.pause, if you change that to partytimeline.pause. What's happening is after a while it will stop it again.
Time of, like, ten seconds or so.
Please. Party. Boop. Boop. That might not be a word. Let's change it back to party. That's easier. Please. Party. [ Laughter ] That's so much fun. Okay, this is -- I mean, and this is the kind of stuff that, like, how much fun would it be to hide little things like this on your website? Like, this is the sort of stuff that, like, I am immediately gonna find ways to abuse this speech recognition on Jason.-- immediately
It's party Corgi. It would be brilliant if I could say Corgi party instead. I was sitting there. So when you say boop, it would be interesting to see what the transcript is. So, what you can do is you can actually see all the transcript results come through and you can see what the browser actually thinks you're saying, which is sometimes quite interesting.
Yeah. So how do I do that?
Go up a little bit higher. There should be --
Transcript, console info. Oh, so, we already have it. Wow. Boop. It's like that's not even a sound. Boop. Boo. It doesn't like that little boop.
It did like that one.
I got to smack that "P." Boop. This is -- honestly, this is better than I expected a built-in browser speech recognition to work.
It's really impressive, isn't it?
I mean, it really is because -- well, look at this, it actually -- it got all of that. This is honestly -- this is -- yeah, I mean, the fact that I can't speak in full sentences is readily apparent here --
Even hyphenated, built-in.
Reading a transcript of yourself is a great way to realize that, you know, even though English is the first language, doesn't mean you're good at it. Enunciate. Yeah, I need to enunciate. But this is really fantastic. I am legitimately blown away. Excellent job to the standards committee in putting together speech recognition because this is impressive.
And it opens up just loads of fun doors like this. So, you know, you can't complain.
Definitely. Well, cool. So, yeah, I think, you know, we've got about 20 minutes left. We can play with something else or we can -- we can also always wrap it early and just call this a resounding success. Because now we can Corgi. Come on, man. Corgi. Corgi.
Did you change the keyword?
Please. Party. Okay. I got to change that back. It's way more fun to say Corgi.
Well, you know what we haven't done?
So many things.
We -- we didn't -- so one of the ideas I had was if we had a -- I think if you go into the stylus --
It depends if it's caught in the head group. Yeah, so right there. Cracker, display none.
Oh, that's right.
If you take that out --
It is caught in the group. Oh, look at it. Oh, that's the cutest thing I've ever seen.
And what I was thinking is, you could do -- I don't know if we'll be able to squeeze it in, but we can try. We can do Corgi drop. And then we could --
Animate the cracker down to the floor.
All right. Let's see if we can do it. So let's start by building a drop. So we'll do a drop. And that is going to be a GSAP.2, and it's Corgi cracker.
Well, I think maybe a timeline. So I think what we'd want to do is make --
Oh, yeah, because you want to make it feel real.
You want to make the head go into the middle first because I don't have any physics anticipated for the cracker.
So if we did -- first, if we set the head and the face to go to rotate 0. So, if we did 2 -- yeah --
We're gonna have to figure out how to, like --
We can pinch that whole block.
Pause this, aren't we? Cooperate. So we're gonna rotate.
Yeah, if we just did rotate to 0 --
-- and then after it, if we just did Corgi cracker and then just do, like, Y%500 or something like that. Just see what happens.
So it will need to be 1,000?
Yeah, we could do it with pixel coordinates, but --
That's pretty close. Let's call it 1,100, and I think that will be good.
So the interesting thing here is we have, obviously it's rotating and the cracker is moving with the head. So there was a trick I was gonna speak about here. But we could hook this up to voice and see if it works first. But the trick here would be when the timeline goes to the point where the rotation is straight, --
Swap the cracker out for a duplicate cracker that drops that isn't inside the head group.
Oh, so -- so, like, this Corgi cracker, we could drop it and then we could hide that one and show -- or show the other one and hide this one.
Yeah, so the one that's in his mouth, when he goes to drop it, just hide it, then a duplicate one drops that isn't affected by the rotation.
Yeah, we could do either of those things. So let's -- well, I guess let's start by doing the JS because I think that will be fun. So, down here we have another command. So, we'll say drop. That'll be drop. And then --
And then --
Here, if transcript.
If transcript equal --
Command, drop. Then we would want to call drop.
Okay. And then that one doesn't really need to be paused. So let's just give this a shot. We'll say --
Do we want to stop it from -- yeah, stop that one. There we go.
Okay. So, you should be in good shape. All right. Did change it back to Corgi. Corgi, drop. Good boy. That is -- it's cute enough that I, like, have to provide the praise at the end. That is adorable. Okay. So, then oh -- so what you're saying is to make that --
To make that better --
Yeah. What we could do is we --
We need a cracker.
We can duplicate the cracker.
Corgi cracker, Corgi cracker. It's all grouped. Perfect.
Yeah, it's a big group with, like, the individual pieces inside it.
So, we've got our cracker. And then I can put this --
So we've got two ways you can do this. You can either duplicate it or we can just copy it for now, if you want.
We already showed how to do the use, so let's just do it down here, I think. This big group, is that, like, the whole thing? Or where -- in fact, I'm up here. Let's just do it the right way. So, we've got our Corgi cracker.
And then --
And then if you swap out the original cracker for the use, but we'd probably want to wrap it in a group. This will be quite good actually because we can create a new group and call one, like, "mouth cracker" and "drop cracker" just to distinguish between the two.
Yeah, that does make sense. I do valet good mouth cracker. So, we've got our mouth cracker and this one's already got a transform in it. So I'm gonna drop this out and I think it should -- okay, that's back to where it was. Do I go all all the way to the outside like here?
Well, just as long as it's outside the head group.
Outside the head group?
Yeah, so it needs to be in the same. So when you rotate --
That's the right place?
Should be able to see it. Is it right? Can't tell.
Yeah, yeah, yeah, yeah, so if I zoom way in here we can see it's like --
Oh, yeah, cool. So this is where you end up with, like --
Here's the thing I was saying, like, if we -- because we, like, when we rotate up, we could just swap them out and, like, it will look like it fell out of its mouth. It's gonna happen so fast that I don't. We might want to deal with that again in a production-grade app, but I don't think we need to worry about it here.
Yeah, so, like the other thing that I would probably have done here as well. So you can see that now his mouth isn't over the top. So, like, you'd need to duplicate the mouth or snout or muzzle, whatever I've called it. Also to outside when he shifts to 0, drop one and then hide it on complete. So it looks like the real deal.
Yeah. Well, and maybe a way that we can do this is we can go with the drop cracker and go debt display none." Okay. And then here we can go mouth cracker and drop cracker. And then when that's done, we'll to mouth cracker. Display none.
You can use a set for that.
Oh, just a regular set. That makes sense.
You can change in a set as well. Essentially a set is a 0 duration tween.
And then this will unset at some point, right? Like, or we need some kind of a --
Well, the way I thought it would work would be -- so, both crackers -- so, originally -- whichever one's rotating, so mouth cracker is visible.
And drop cracker is display none. And then at the "on complete" of rotate 0, so where you do to Corgi head group face at the top there.
Yeah. Inside there, if you do an "on complete" there and write a function inside here. So this is the trick. At this point, you'd do GSAP.set.
Oh, you're doing it in here.
And do the switch here. So, like the smoke and mirrors bit happens here. So you just swap one out for another and only animate the one that's visible.
Okay. So let's try that. So we've got.
So you don't need to animate the mouth cracker because the mouth cracker never goes anywhere.
I see what you're saying.
But the dropped cracker.
I gotcha. We should see it really clearly because the drop cracker will actually appear over the mouth.
That's what I was thinking it would drop first and then got at the tend it would switch, so when it rotated next it wouldn't take the cracker with it, but still look like it came from under the mouth. So, let's try this. So we've got -- Corgi -- Corgi, drop.
Oh, we broke everything. So, does it reset when it gets to the end here? Because it looks like it did what we want, but not quite.
Oh, I see what's happened. You've sort of chained the set on to the set.
Oh, I don't do that?
Is that possible? Maybe it's possible.
I don't know. Let's try it. Corgi, drop. Okay, so we got closer, but then when we get back to here, it's -- is it -- is this too much, maybe? Let's try like a --
Is it because it's now out of bounds now, right? It's gone outside the SVG.
Corgi, drop. Yep, it's just dropping out of bounds.
Yeah, so that's because in CodePen, you have to do an --
Corgi, drop. That's pretty good and still inbounds, so I think we can leave that.
Yeah, if you ever get stuck with them, you can do -- so you can set an overflow on the SVG because obviously by fault they're overflow hidden. Some reason in CodePen you have to do overflow important. You'll see it drop to wherever you want to. The view box, you can see outside of it.
This looks good to me. What happened is the cracker scale was different because we moved it or something. Because 1,100 on the other one, mouth cracker, put it barely below this. 600 put is almost exactly where we wanted.
It's probably been offset was the other cracker --
Corgi, drop. Yeah, weird. Weird, weird. But, yeah, so this is -- this is fun. Like, I am kind of blown away by how much fun this is. What I like about it, too, in the span of an hour and a half here, we took this, you know, already fun Corgi drawing and we breathed a bunch of life into it. We've got eyes that interact with your mouse. We've got the head. This cracker. And, Corgi. Party. Corgi, party. That's a lot of fun that we can just do that. So this is -- like, we accomplished a lot here.
Yeah, I'm just thinking that. I was quite worried we weren't gonna get anywhere near as much of this done.
Yeah, I mean, this was an absolute blast. So, with the five minutes we have remaining, where should people go if they want to keep going down this path? Like, what -- should say -- we're gonna say they should follow you, so make sure you go follow Jhey on Twitter. Make sure you go to the CodePen. And where else? What should people do?
I mean, they're the main hot spots. I think if people wanted to follow this path, though, my actionable take is just to write down every idea you have. And no idea is a bad idea. Just follow it. Like, just make it. Don't think about why, how, who. Just do it. That's, like, genuinely how I try and live by it. And, yeah, just all these weird ideas come out.
So, the cracker idea for the -- for the Corgi sort of -- there was another piece of this which obviously we didn't have time for. There are some eyebrows in there. The idea was when we've done the blue background, the eyebrows that do, like, the startled look. Originally it would have the cracker. If you mouse over the cracker, he'd make a growling noise and show you the angry eyebrows.
I very much look forward to where you take this after. So, stay tuned. That's your motivation to go follow Jhey on CodePen because you're gonna get to see how this evolves even further. Go look at the source.
Twitter. My stream, because I do these obviously on my Twitch channel. And then, yeah --
Is your -- what's your Twitch username?
It should be Jhey3YY, I think. I've been a bit slack this week, though. So.
Go do a follow. Oh, wait, I have a shout-out command now. Does it work? It does work. Yes. Oh, but my shout-out lost its subscription so it doesn't do the emotes anymore. WOMP, WOMP. All right, y'all, so I have had so much fun today. Go make sure you follow Jhey on all the channels. This show is live captioned by White Coat Captioning. All of whom kick it to make the show a little more accessible, which means a whole lot to me and I hope you enjoy it as well. Make sure you go out and check out the schedule because we have so much fun stuff coming up. We've got one more week until Christmas. So, next week I've got Scott coming on. We're going to do more animation with svelte. Thanks for sending us out with a stampede. Chat, you are the best. We're going to do animation in Svelte and then we're going to go on break and enjoy the holidays. I'll be back on January 5th. We're going to learn Typescript. I've got Ali coming on. We're going to do let's Learn React, not on the schedule yet, but the Tuesday before Scott Moss comes on. I'm really excited about all the episodes. Really excited to what 2021 holds for us. I'm hoping for all of us it ends up being a big improvement and I just really want a hug, you know what I mean? So, chat, as always, thank you for hanging out. Stay tuned. Jhey, thank you for hanging out with us today.
Thank you for having me on.
This was so much fun.
All right. This was a blast, y'all. We will see you next time.