skip to content

Build a Realtime Twitch Game

What happens when Cassidy Williams joins Jason to build an interactive game? A whole lot of shenanigans, we hope! Join the fun as Cassidy & Jason build something fun together & try to make each other laugh

Full Transcript

Click to toggle the visibility of the transcript

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.

Hello everyone. And welcome to another episode of Learn with Jason. Today on the show we have the most recent developer on the Netlify developer experience team and contractually, through a clause I snuck into her contract, my new best friend, Cassidy Williams.

Yeah. I had no choice!

I'm so happy to have you here. This is going to be a whole lot of fun for so many different reasons.

Yes. I'm pumped.

I imagine that everyone in chat here is familiar with you, but just in case, do you want to give a quick background of who you are, what you're into, all that good stuff.

Oh, man, what am I into. I'm Cassidy and I recently joined Netlify and I'm a developer experience there and we're getting people to use react and other cool tech and stuff. What do I like? I really like keyboards. I talked about them a lot on the internet and I don't want to turn this into a keyboard stream but we could. But we have coding to do. I build mechanical keyboards. I have many next to me. I won't bring all of them out now, maybe later. We'll talk about it. That is who I am. I like memes and dreams and Fortnite.

I'm into it. Okay. So we are going to mostly just screw around today, I think. But first, I wanted to make a couple quick announcements. I have some really exciting stuff going on on the show. As of today, we have live captioning. We brought in White Coat Captioning, they're amazing, and we have Lora today is helping us out and going to be captioning everything. You can see that at LWJ.Dev/liv. If you want to follow along in a written format, you can switch over and see that. Let's look at the screen. This is the live view. So you'll be able to follow along with what we're doing today. So this is, I'm really, really happy about this and big thanks to Netlify and Fauna who are sponsoring the captioning. So yes, definitely check out that live captioning. The bonus of this is it also means we're going to have transcripts that will go with the videos later on. With that being said, I think we should talk about what we're going to do today. What are we going to do today?

We talked a lot about what do we do that would be both amazing, useful and kind of stupid. So we were realizing, okay, we're both in the Pacific Northwest, we should do something with a hipster, blah blah blah, and I said the hipster should be Jason and we brainstormed a lot. Long story short. We're going to make a game where the chat is going to participate in the game. Oh, you have a subscriber now.

Thanks, very much, Dark Master Mind.

So Jason is going to be the subject and chat is going to decide if his beard should grow or his hair should grow. So the CSS will adjust depending on what the chat says and I'm very excited about this.

The way that we're picturing this is a tug of war. A chat command will cause either the beard to grow and the hair to shrink or the hair to grow and beard to shrink. I have a suspicion about the chat that I'm going to be the only one wishing I had hair. I'm going to be running the hair command and everyone else is going to be growing the beard. So I think we should, let's, how do you want to start this? What's the ideal starting point?

I could start --

Thanks for the sub.

Yeah. I can do the CSS of your face.

Yes.

And we can work from there. Or we can start a collab'd code pen and start from there.

Thank you for the gifs. I appreciate this. Cassidy it's almost like we talked about this before and we're ready. I have a collaborative code pen and we're ready to go. Through the magic of television, hopefully buckets, y'all, thank you so much y'all for the gifs, that is absolutely amazing. Really, really appreciate that.

That's so great. Kennifer asked what keyboard I'm rocking. It's a case that I got in Korea that you can't buy in the U.S. and I don't know what it's called because it's in Korean.

That is the most hipster, sorry, you can't get this in the United States.

And so the switches are tactile Zilens (ph.) 67-grams of force. And I have a combination of SA oblivion and SA round five. Just the num row is so rare. This is getting into keyboard territory and I'm excited about it.

Cassidy, we only have 90 minutes here. That is really cool though.

I love this keyboard and it's quiet enough that if I start clacking on it (music ...)

So no joke, before we started the stream because the captioning is brand new, I had to like give a primary warning, hey, the stream is a little wild. Get ready for the weirdness that is going to happen. All the new subscribers keep in mind that you can absolutely drop a ton of boops from the top of the screen. If you're motivated and you work with each other, you can bury us in boops as we go. Be mindful, don't go too over the top on that because you want to be able to see what we're working on.

All right. So code things.

Code things.

I started, I added some preprocesses and Hamil and CSS because I don't want to type divs all over the place. There is a photo of you on your website. I don't know if you have it easily accessible but it's a view of you with one eyebrow up and a cup of coffee and a purple shirt on?

Where is that one? Down here.

Yes. I grabbed my color picking tool beforehand to get the colors of your shirt and your flesh. So we can use that. I said that menacingly. Your skin.

Your flesh.

I have your flesh.

You have the resting murder face so I have to catch up.

Thank you for another gif. What's up Dave?

I'm going to put everything in a container and separate everything properly. We can have a background and a foreground. And we'll put you in the foreground. If we want to get fun with the background and put you amongst trees or something, we can do that. But, now we need to actually construct what it's going to be. And this is generally how I work with CSS. I figure out how I'll break up whatever I'm building first and then apply the CSS. So it looks like nothing and then it will look like something. In the foreground I know we want to have Jason. And then we're going to -- the main thing we want to control is your head. Because that's where the hair is going to grow out of. So I'll just have the head. And then we'll put a body in there, too, and your body will be a purple blob. Now that we have the head and the body in there, on your head we know that we're going to want to have your hair. And you know what, because you don't have it -- I didn't mean that, to bash you -- because you don't have it we should start with no hair and then remove the hair and add it as it goes on or something like that. Let's see, you have glasses, you have eyes. You actually have two eyes.

Two of those.

Left and right eyes. You have -- we don't need you to have ears but let's get detailed. We'll give you one ear so we have a side perspective like I'm looking at now. And then we'll keep the beard for now and add the class --

It's a bad scene if I have neither hair nor beard. I look like a baby that isn't doing so hot. Like maybe a baby that --

Needs a little break.

Somebody feed that kid a vegetable, he is looking puffy and weird.

We want to have black color. And this again, I have just -- you know what, I copied all of these in my color picker here. We have variables. We have our light purple part of your shirt, the regular purple part of the shirt. White. I don't know if we'll actually need white but we have it. And then your skin and your hair. Let's do this. We're also going to want to kind of do some normalization. I should have some kind of keyboard command for this but we're doing it live. Where the whole thing is width and height 100 percent. The margin is 0. Padding is 0. Okay. Everything is normalized. Now let's see, the foreground is what's going to be containing all of you. Let me just put foreground in here. Probably, yes, I'll just stick this. In the foreground we want to, I want to make you stand on the bottom of the screen and in the middle. So I'll do a position absolute here and left 50 percent. And we want to do a transform translate, X. And then negative 50 percent. And then?

We have a request from the chat to rename skin to flesh. So I'm going to make that happen.

Perfect. We're now working with flesh, people. Okay. Cool. So in the foreground I think that's all I need for that right now.

So can I ask you, you just did something.

Yes.

When you positioned the foreground absolute you did a left 50 percent and a translate X negative 50. What's the benefit of doing that? Doesn't it just cancel each other out?

It doesn't. Actually, let me show something really quick. I'll do with is 100 pixels and background is flesh. And then I'll do height is 100 pixels as well. So what happens here is when you have the left 50 percent, it puts the left side of the div at the 50 percent mark. So it's not perfectly centered unless you scoot everything over ever so slightly?

I'm going to comment things out just to see what happens.

Nice, go for it. See how it scooted a little bit.

It's not centered. We started out and it sits over here. Right. And then we bump it over to the left. This 50 percent is relative to the container, the full width of the thing.

Right.

Then when we translate it.

That does 50 percent of the divs width is scooted to the left.

Sneaky, sneaky.

That is how you can make sure something is always centered on the page. I did translate X, but if you just did translate negative 50 percent and negative 50 percent and top 50 percent here that's how you --

Like vertically.

Yes.

Who says it's hard to vertically center in CSS.

Easy. Cool. Now we have to work with Jason. I'm going to take out this blob of flesh here. I'm going to say that we want you to be positioned relative in here. The reason why I'm doing that is because as I start positioning things inside of you, I want it to be positioned relative to this whole Jason thing rather than the foreground and this is resetting that point there. In case we add other things to the foreground. Because we can technically add many Jasons. Cool. We have that. Let's do your head first. Your head is going to be the hardest part I think. There is actually a lot of elements to --

I've been told that.

Jokes. Okay. Yes, I'm going to do a position relative in here. I want it to be kind of facing to the side. I'm going to, I'm choosing some kind of arbitrary numbers based on things. The width of your head is going to be 130 pixel, congratulations and the height is going to be 180 pixels. Because we have a decent proportion there?

Not quite spherical.

Of course. And flesh. I keep typing flash and it's bringing me back to my days. Cool. We have something on the bottom. This is going to be your head. Let's make your head a little bit more round. Quarter radius of 30 pixels. And that will be the bottom of your head. And then I'll make the top of it a little bit more round. So I'll do border, top, left radius is 60 pixels and border, top, right radius will be another 60 pixels. Look at that. It's starting to look like a head. Kind of. Cool. And so now I also want to be able to add some shadows and stuff. Okay. I'm going to make this a thing. Okay. So first of all, I'm going to -- hum -- I want to start adding your beard and stuff. I'm going to do one thing at a time. Let's actually instead of starting in on all of this, let's actually get your neck going?

Okay.

So your neck is inside the head because that is how we structure it in there.

I remember that from biology.

Yes, that's a thing. And I actually didn't add that in there. I think the neck could have a nice little shadow in there. It will be cool. I'm going to do a neck, it's going to be a lot of CSS. I hope y'all are ready.

So ready.

We're making CSS Jason, correct.

We are indeed making CSS Jason.

This is going to be positioned in the head. To position absolute here. We're going to stick it on the bottom of the head. I'm picking numbers. We want the width to be less than that. I'm just going to try this. 96 pixels. And then the height will be 60 pixels. And then we want the background of that neck to be flesh. And then let's see, we don't need to worry about Z indexes or anything yet. But I would like to add a little shadow so we can have some depth to it.

Look at that.

Oh, it's showing up, yeah. I'm so glad. It's slower to refresh so I can see it better on your screen than on my own but that's okay. Okay. Cool. So we want to add a little shadow in there and so I'm going to do position -- if you ever want to turn a pseudo-element into something, every single div that you make is multiple divs and you can do a lot with it. If you want to turn a before into a full div, you can turn it by doing display block and then content blank. When you do that, suddenly it's a blocky div. Now I want to do a funky triangle thing?

While you're setting that up, you know Lynn Fisher is a single div. I'm going to show the chat this real quick because it's so amazing. This is all CSS art done by Lynn Fisher, Lynn Fisher is one of the most creative minds I've seen. A designer, creative thinker, all that. She made a cyber struck. She does it with a single div. She does it can pseudo-elements and shadows is kind of how she makes this work. Go and check this out. It's really eye opening stuff.

Look what I was able to do in that little bit of time.

Holy crap, you got so far.

Me spastically typing as fast as I could. What I did in there, I added this little border pack is how you make triangles in CSS. Borders are weird. If you ever want to make a triangle borders are little triangles in themselves. So what I did is I make a blocky div and I made the left side of the div and the bottom part of the div is going to be a transparent triangle. And the border right and the border top is a solid triangle. So that is how we made that little bit of shadow there. And then I quickly added a bit of a, like, we got some 5 o'clock shadow going for Jason here. Truly I just kind of copied some of the dimensions in there and made this bit shorter. And I made the background is just black with .1 opacity. And I added the same border radiuses that I had before. This looks a lot more impressive than it is. Truly I was just copying and pasting very rapidly between these. So yes, CSS is fun. I just saw someone comment, I quit CSS. Don't. No. Cool.

That's Michael Jolly. Right now he is cooking up something fun to do with CSS and a puppet.

CSS and a puppet?

He built like an animatronic puppet that announces his Twitch events.

That's amazing.

Go and check out Bob the builder some time.

Cool. Below the neck class I'm going to start styling your eyes to put the glasses on your eyes. I'm going to do position absolute. Notice how I have them have the same eye class and left and right. This is how I style both eyes at once and reposition them separately. I'm going to do 80 pixels from the top. I'm going to say width 10 pixels and height 10 pixels. And then we want a border radius of 50 percent. If you ever want circles or ovals you do 50 percent border radius. And then the background is black. In terms of ordering on CSS, I generally do positioning things on top and alphabetical. I don't know what's right. I just roll with it. Eyeballs, they're coming in there?

My dream of having eyes in the back of my head is finally true.

Your mom was right. Left, we're going to do it just scoot it in slightly. I'll do this 10 pixels and then we'll do the same thing with the right eye. And that will be right 60 pixels. So they're 50 pixels apart. Look at that. You have eyes?

Look at that.

Now let's see. I can do something more with the eyes. I will do that later. Let's get things going first. Now I'm going to -- I wrote down a couple variables that I wanted to remember. It's really just the colors. I don't know why I'm looking at this. I'm going to do your ears next really quick before I get to your glasses.

Okay.

Ears, we're just going to have one ear -- not eat, ear. The same color as the rest of your skin or flesh. I just want, like if only we could hear the chat and here them, flesh, flesh, flesh. Nice and unsettling. Have you ever seen the Tweet about being in the dentist's office and everyone chants teeth, teeth, teeth. I love that so much.

The chat delivered.

Yes. Flesh, flesh, flesh. Okay. So we're sticking it, the top about 80 pixels which I think that's what I did for the eye in there. I'm minimizing things because there is so much CSS happening on my screen right now. I'm trying to minimize things as I go. We got the top 80 pixels, left negative 20 pixels so it's off to the side of the actual head itself. And then we'll do another circle thing. Width 40 pixels.

Okay.

Height, 40 pixels. We did the background as flesh. And then we also want to have, look at that, you have an ear. Let me do border radius 50 percent.

I'm helping.

Thanks. Wow. Look at that. You got an ear. It's happening. Okay. I am pleased. Okay. Actually I made a glasses class and I don't know if I need to. I bet I can just do it with pseudo-elements on the eyes. Let's do that. Because that is going to be fun?

Yes.

And edgy. Instead of using this glasses class, glasses are dead to me. I'm just going to plop it here and I'm going to say -- before and I'll do the whole display block, content nothing. And then I'll position it relative compared to the eye that we're currently on. So I'll make it a block then. The eyes are like 30 pixels -- or 10 pixels, so we'll make it a little wider than that. I'll say the width is 30 pixels. You know what I'm going to do? I'm going to add eyebrows first so you can have your signature one eye brown up. This is now an eyebrow and glasses. Glasses are no longer dead to me. I like the idea of that better. Sorry, we're doing this live. We're kind of just rolling with it. So we're going to have the eyebrow. We have the color hair instead. Background hair. Then I'll do height of 10 pixels. Oh, look at that, oh my gosh, I'll do a border radius of 10 pixels. We don't want it oval, just rounded edges there. And we want to make it so that way one is up and one is down. This is so fun. Okay. Bottom, we'll just scoot it up a little higher. I'll say 22 pixels. Oh my gosh, this is so fun. Okay. Let me scoot it to the right a little bit more. I want it to be half of that. We'll do right 10 pixels so they're a little centered there?

I love this.

What I really like about this, too, is you can totally go for the full Muppet look.

Yes.

This is so fun. You know what, I'm going to -- bottom and then I'll do half a second there. Now if you do edit it, your eyebrows will move up and down.

Your wishes are coming true, chat.

Now we want to make it so that way we have, we've got the two eyebrows there. I wanted to make one go down and one go up. So I'm going to do -- what is it? It's going to be the ampersand and just the right eyebrow and then before. This is getting some funky selectors here?

This is where I think, I feel like CSS gets a bunch of flak for being, like, oh, people are like it's not a real programming language or CSS gets in the way of doing cool stuff. When you start looking at the power of -- we have the ability to do the cascade. We can create pseudo-dom elements right from here. It really starts to show how incredibly powerful this stuff actually is.

Okay. We've got one eyebrow up and one eyebrow down. I'm very pleased with this. Because we were doing before, maybe glasses are still dead to me -- maybe we can just do the after now. And then with that I'm going to copy and paste the display block. Content none, position relative. All that jazz. Paste it in there. I agree with you, CSS is one of those things where it can get very complex very fast if you're not careful. Let's see --

Hold up. Divorsky, in the chat why are people in the Pacific Northwest good at CSS?

Because they live in Cascadia.

That's the best joke I've ever heard. Oh my gosh. That was amazing.

So good. Thanks for stopping by. Have a good day.

That just made my day. That was incredible. Okay. So we want to have your glasses but we don't want -- we want to make squares with just like emptiness inside. Background transparent. And then a border with, I'll make them thick glasses and we can thin them out if we need to. Solid and black so they match. Oh my gosh, look, there they are. We need to position that a little bit better. We want it to be centered and it's 30 pixels and crap. I'm going to do left negative 15 pixels. And then bottom 20 pixels to scoot it up. I think that should be enough?

Beautiful.

Great. Oh, I'll make them a little bit round. You have nice glasses. I'll just do a really small radius though. Cool. Nice. We have glasses. Oh man, this is so fun. We have a majority of your face and now we don't need that glasses class. I'm going to minimize a couple things on my end so we can see what we styled and see what we need so we can make this a little more real. We have the neck, the eye, the ear, the head. We need the rest of the beard and your mouth. Your mouth -- I'm going to do something kind of hackey with your mouth. That sounded funky.

Let me think through the language that would be used when talking at programming as anthropomorphi.

With 40 pixels. Oh my gosh, the backspace button. With 40 pixels and height of 5 pixels. Background.

Chat is still chanting flesh.

Flesh, flesh, flesh. Okay. So we have a mouth but it's over there. Did your parents ever talk about having a mouth on the back of your head, Jason?

They did not. That is straight nightmare fuel. First let's make it nice and rounded before we fix it. That's cute. Now that we've done that I'm going to position it. We did a position absolute so we could position it absolutely within your face. I'm going to put it on the right of your face. I think we have around 15 pixels from the side of the eyes. I'm going to do the same thing. Right 15 pixels and bottom 30 pixels-ish. There it is. I'll add a little bit of border your beard doesn't go right up to your lips. So border and then I'll do 5 pixels solid flesh.

Flesh, flesh, flesh.

Oh, you know what? The beard shadow that I have there, if you recall it's like, it's black transparent. So the flesh -- it needs to be on top of everything. I'm going to do a Z index of 1,000. Z indices are not something I mastered. Look, now you have, like, skin there or I guess I should say flesh. Cool. I think we have a majority of this done. I'm going to work on the beard after doing your body so that way you have a body to work with. I'm going to minimize head and add a body class in here. So that way you have something to stand on. Maybe not two legs because I don't feel like doing begs. And the body we'll have a purple chunk, that was my name in high school. Position, relative, width 220 pixels. That is almost double the size of your head. And then we'll do a height, I don't know, we're making a glorified rectangle here. Background is purple. Oh, heavens, look at that?

It looks just like me.

I know. That's what I thought. We'll just make it round border, top right radius will be round. 90 pixels. Border top left radius will be 30 pixels. Look at that, I think I have -- I'm going to not get ahead of myself. You got to just get it working first. Okay. I'm going to add like a lump for your right arm. So that way, it's not a lump, you have lovely arms I'm sure: I haven't actually met you in person yet, so I don't know?

Right now it looks like I'm twisted this way. We need to roll that back.

Display block, content blank. I really like the chat, solid flesh, solid flesh. That is so funny. Position absolute. We're just going to stick this right at the top here and we're going to give you an arm that's kind of slightly to the back. Because it's slightly to the back we want it to be slightly to the left, negative 30 pixels. The back is that light purple here and we need various border radii. I'm going to copy and paste some of these from lines above and add my own lines in here really quick so we can do that and that. Okay. Now we have roundedness.

Does it need a height.

It does need a height. It also needs a width. I just didn't do anything. Oh, yes, this is working in my brain. 160 pixels. And height, height, we'll make it a little more than half of what you have. There we go. Does it show up on your end. There it’s cool.

There we go. We got it.

Great. So we have that. I want the Z index to exist, you know what, I don't think I need to worry about that yet. We'll worry about that when you have a beard. You also don't have a neck anymore. I think I need to add a margin to the bottom of your head so we can have that. I'll do margin bottom of 10 pixels or so. There it goes.

There we go.

Cool. You know what? Oh, ideas. Okay. I want to make it so your neck is in between these. This part doesn't matter. I shouldn't get caught up in this. I'll do this later. Now that we have this generally done, we can start actually working with your beard and working with your hair so that way we can do stuff with it.

The chat is killing me right now. They're calling me flappy Jason because it looks like a wing. This is super fun.

There is great. Cool. Let's get your beard done first. We're going back to the head and I'll do this right after the mouth here. Beard. So with the beard class of none we'll just have -- because when the beard is gone, we don't want it to show up. I'll say when that beard has a class of none, we'll do the opacity at .1 or something. Otherwise we'll have a position absolute and we're going to do this whole she bang thing. I'm going to style it exactly as -- I'm moving my mouse if as people can see it -- we're going to style it exactly like I did the current shadow. So I'm going to copy some of that. But it's grow-able. Excuse me while I scroll up and copy all of that really quick and paste it in here. Look at that, you have a period.

Wow, that happened so fast.

I truly just copied it and added the background of hair right in here.

Awesome. Very cool.

But now what we can do is with the height, I have this little transition on the height right here. If I were to make the height 180, it grows.

Oh my god.

And it grows slowly. This is where we can start to turn this into thing more amusing. Let's see, we should do something similar with the hair. I admit, I wasn't sure what to do with your hair because you don't have much. So I didn't have a reference with which to draw it. So when I was thinking about this, I'm just like I'm going to yellow it and give you a bit of a quaff for this. (music ...).

Left 0. Normally because it's at the top of your head I would style it from the top. But because we want it to be able to grow vertically, I'm going to style it from the bottom. That means the bottom should be 120 pixels. We'll see what it looks like. We want the width to be 100 percent of your current head and the width to be 65 pixels. And the background is hair. Like that. Look at that. You know what I'm going to do 125 pixels. So we have some hair growing. Let's actually make it look like something. So I'm going to --

Thank you for all the subs, Chris, I really appreciate it.

Thank you, Chris. This is where border radii are very, very, very annoying. I'm just going to kind of roll with it and I may have to make adjustments along the way.

Eco is pointing out the bald patch at the top. Exactly, that is why there's no hair.

I want it to be more round on one end and less round on the other end. And I want to do a little bit of a quaff. I'm going to do a border bottom right radius of 160 pixels and see what that looks like.

Did we just Johnny Bravo my head.

We did. I'm going to add, the second parameter of the border radius property is fascinating to me and I'm going to roll with it. I'm going to try 60 pixels again.

Hold on. You're doing things I've never seen before.

Truly, I'm experimenting here. The second parameter of the border radius blows my mind. Did you know you can put 8 different parameters just in the border alone.

I didn't know you could do more than one.

You can do 8 of them. But for each of the individual ones, you can have one for one angle and one for the other angle.

Whoa.

And truly, I just threw some numbers in here and guessed and it generally worked.

That's wild.

I can turn this into 180 and we can see what that looks like. It's a little too blocky. You can poke around with it until you have something that you're happy with.

That is wild.

Yes. It is very funky and I am in no way a master of it. It's truly something that I just throw numbers in there and if it looks good I'm like thank goodness, because I don't understand this thing.

Isn't that how we all code anyways?

That is true. I'm going to add a transition on this for the height. And I'll do the same thing that I did with the beard. One second and then opacity is one second. Now, if we were to change the height of your hair and I change this to 155, it grows. Cool. Oh, yeah, and I'll do the same thing that I had where if it's none, then I'll do the light opacity. Although, I'm going to just have opacity be zero if you don't have hair because we don't want it to be slightly hazy?

Right.

Okay. So I think we have something generally workable to poke at with JavaScript.

Yes. At this point what I think we can do, I want to try something that I believe will work. And I guess we'll find out quickly. What I'm going to do, I just built a -- can I get this over here? What are you doing? Oh, I'm in full screen mode. Let me go over here to LWJ scenes and I just built this thing. So my Twitch overlay now is completely driven by web. Like it's HTML now. This was really fun to build.   I basically set it up like what we're in now is the pair screen. So we have content and there is where Cassidy's video is and my video is here and this is where the desktop lives. And then the lower third and stuff down here, you can see all the content that is rotating and this is driven by CSS and stuff. But the exciting part is I hooked up this thing, so stream Blitz is a tool I built for streaming that lets you use serverless functions to define your effects and stuff. So I'm on, this is a different browser. Let me sign in on the browser that's logged in as me. And I'll show you what it looks like. This is like, these are the effects that you can run on my stream. So any of these, if you type these in the chat, they will trigger an effect and do some stuff. These are really fun. But what's cool about it is these pull from GitHub. So if I go and look at my serverless functions here, each of these is driven by something like this. So the bullet super vision is a stream Blitz handler and you give it a name and a description. So I was thinking we can use this and send an effect. So if I really quickly go in here, let's also open up LearnWithJason.Dev. From here, let me stash all my work, I guess. I have some stuff that I'm in the middle of trying to fix. That's going to be good enough. I'm going to create a new function. So these live in my site folder under functions and I'm going to copy and paste. Let's just copy paste. I have a new adult supervision. What should the command be, chat? Should it be beard? Should it be grow? Grow and shave?

Oh. I like shave. That's a good one.

Bosley. Bosley is funny. I think that could be a copyright thing. Let's call it bearded hair. That's a good call. We'll call this one beard. What I think we can do is just like leave everything else out. So we'll give it a name -- or we'll give it a description. Grow the beard. And then we'll duplicate this. Not that part, sorry. We're going to duplicate this file and call this one shave. We'll say shave the beard. Okay. So now if I commit. Let's add site functions. And then I'm going to commit new beard/shave commands. I'm going to push these. Then what should happen here is in a couple minutes, once the site rebuilds, I will have -- let me go and look at my deploys real quick. Okay. So I have out here, just pull this across. Here's the deploy that is running. This will take 3ish minutes. And once this is done, we will have access to these beard and shave commands. While we're waiting for that, what I want to do is pull over this web socket stuff. Because we can just detector a web socket from stream Blitz. I think we can legit pull this right into code pen. That is my hope at least.

I may or may not have made you flat. If you hover over it, it makes your arm flap and eyebrows go up. Your eyebrows go up and you start flapping when you hover. I was trying to do it like keep talking Jason, I'm almost done?

We have a web socket established and that should mean if I go into the chat and run a command. Channel is not defined. I need to make sure we have message dot channel and 9. Where are you getting your variables from? Message, oh, does not equal channel. We'll just filter. Okay. Let's try that again. So let's try this one more time. I think I might need to refresh the page to get that to pick up. Let's see here, we have a web socket connection. Now if I run, yes. There we go. Now we have events. So what we should be able to do is check these events for the name and then add a class or modify a thing. So chat, this code pen will 100 percent be open source. The reason it's not right now is because it's collaborative and I don't trust you to not mess with this.

Correct. I was like don't share it yet, Jason.

So, yeah, once the stream has ended we will share this. It will be on Twitter. You hackers, you dirty hackers.

That is you. You're not the hackers. What am I saying. We are just about done here. As soon as this finishes, it will say site is live. Okay, site is live. Now, if I refresh, we'll see beard exists and now if we go over here and you run beard, there we go. We get beard and shave. Now we have these commands that we can listen to. At this --

You hackers, you dirty hackers.

So at this point what we can do, I think we can say, if message dot name does not equal beard, or message dot name -- I can probably do this more efficiently somehow but I'm not going to worry about it now.

We're doing it live.

We're just going to return. We're only going to log this, we're only going to do stuff if it is a shave or a beard. If you want to run these, we can do a beard and it should show up -- did I break it? I mean it's web sockets.

It's finicky.

It's probably not the most -- oh, I think I must have just done something wrong. It's not picking up any of this. Oh, wait. What did I do? Console log message. That was definitely working before. Message dot name. What am I doing?

Expected token. Was there a typo?

I think it tried to evaluate while I was typing. For some reason -- you know what, we're not going to worry about it. Message dot name. Can you work with that? Beard.

There it is. Beard. It just logged on my end at least. Just logged twice on my end now?

What is happening? Oh, so I think my console just lost the link.

Because it's logging both beard and shave.

There it is. Perfect. Now we have the ability to use beard and shave. So that message dot name, I don't know why it didn't like this part but I don't care. Let's maybe do it -- hello? Hello.

Hum. The shaving and the beard working but not the hello. Hello fresh, too.

I'm so bad at these. Here is what I did wrong. One of those will always be false. So there's always --

There you go.

Okay. Grade A doofus over here. Now we have a beard, shave, okay. Now it's actually logging. So we can turn this off. We can turn this part off. And now we can do stuff. Cassidy, what would you, like what do you think we should do to actually control these? Also, should we make -- no, we can probably do this because we know it works?

What we can do is make it so just, like, whenever beard is, that command grows, goes, then we can increase the beard height by 10 pixels or something. Maybe 5 pixels depending on the activity. That also decreases the hair height and vice-versa, whenever the hair -- or whenever the shave command goes, the head starts to increase and the beard decreases. If it ever adds zero, we have a class of none?

I have an idea that would be kind of fun but it's going to make things messy in the CSS since you're using SCSS. Can I use CSS custom properties?

I don't know.

Let's see what happens.

Let's find out. I think you can.

If I say like beard length, and we'll set it to be, what is it right now? Let me start collapsing things so I can see.

I have everything collapsed, too. The original beard height is 80 pixels.

So let's use the beard height. It's here. So we're going to say beard length, is that what I called it?

Yes.

And beard length, 80 pixels. Now, if I change this, it works?

Yes.

It didn't trigger the transition.

I wonder why.

I know why. I know why.

Is it re-rendering the HTML?

I think so. Here is what I think will happen. Let's try a test real quick where I'm going to -- let's get the beard equals document query selector beard. Then I think what we can do is do beard, style, set property -- if I can spell it right. And we'll say beard length and let's set it to be 180 pixels.

I think that changes a re-render, but if you just change the height value, the height style itself -- look at that. It transitioned. Maybe something was just being weird.

I think mine was --

Its transitioned on my end. We'll see.

There we go. Okay. What I think we can do here is then I think we can say when we start, we will just declare -- we'll say let beard length equal 80 pixels. We're going to have to do this as values. And then let hair length equals -- what was it -- like 30?

Yes. I'm checking it again. Hair. The height is 55 for the hair. Good head of hair.

That's me. Oh, but are we starting with it hidden.

Yes. We're starting with the class none on it. But we can say whenever it gets below 55 or whenever it gets below 80, that is when you add the class.

So I think what we want to do then, we want to set our hair increment -- we'll call it increment. And we'll make it 10 pixels at a time. It's going to grow a little bit because I imagine the chat is going to go pretty wild with this. We don't want to blow off the screen.

People with wondering what happened with the hair. There was a class one and I just deleted it.

I think we can get property beard length. And I will -- say the current equals -- and I'm going to number the current beard length and let's console log that. That should give us the value. Get property is not a function. Oh, okay. Get style property. Get property value? Get property value. I think that's what we need. Let's get property value.

Trexy codes called that. Nice.

Okay. For whatever reason the console -- save and then we'll reload and let's try this one more time. Object current is zero?

Yes.

That means that we probably need to set this in the beard itself and not in the root. So we can just set it right up top like this, I believe. I think that will just do what we want. Still gives us a zero. I wonder if I'm doing a number on it and that's breaking it. Let's find out.

I haven't actually --

I wish it wouldn't dump the whole thing every time. Okay. I think what -- maybe I'm overthinking this and we can just set the height correctly.

I think we should just do that.

Fine. We don't use fun stuff. You're right. I'm thoroughly overcomplicating this. Let's set that to 80 pixels and now instead we will get the height.

And then increase it or decrease it by whatever.

We'll say beard. Still doesn't get a value though. Maybe I just need to like get the height?

Do that instead. Because that's an actual value that will be on the object.

Refresh. Okay. Why are you not getting any values?

I'm going to poke around in the console. Let's see.

Beard, style, height. Query selector, beard. That's a thing, yes?

Yes.

And if we go beard style height, it's empty.

Oh is it because -- I wonder if because we're setting it in CSS and not like on the div itself in the HTML, it's yelling at us.

Maybe. Maybe what we can do is we can do something like this up here and we'll just set it to be --

Yes. And then set dot style dot height equals the values initially.

  1. Is that going to break? Let's see what happens if I set it to 100. I think it needs to be a value.

There it is. Nice.

If we set it like that, then, down here, do we get the height? Let's find out.

I think we do. We do. Nice. Yes. That was it.

Okay. I'm still having that problem where every time that code pen -- every time I change something. Here is our beard. If I change this to be a number, I should get.

In theory.

I should get the actual number. Oh, get out of time.

Is it because of the PX.

It should parse that. It should get the number. Maybe I need to do a plus coercion thing instead?

Does the plus work? I've never seen that.

That's so annoying. Instead we're going to do this. Let's replace PX with nothing --

Yes, that's what it is.

And we will number and then we can reload. Parse INT is what I was looking for, not number. Jeez.

That makes more sense now. Man, I didn't know you could wrap it in number like that.

In my head what I was doing is parse in and I was using the word number.   It is technically number dot parse INT.

But now we have a number. From here what we can do is we can say if message dot name is, equals beard, then we can say that the beard dot style dot height plus equals current plus increment. Or no.

No, no. It's plus equals. Just equals. It will increase very fast.

Okay. Plus equals. The increment. Let's reload. All right. Try it chat. Hit us with some beards.

Do it. I'm going to do it, too.

Oh, not yet. Not yet because I didn't set it to a pixel value.

Oops.

One more tweak and I think -- oh, pray -- this is going to work.

Eat, pray, love. Nice. There it goes.

Let's do it. Hit those beards. There it goes, there it goes.

Yeah.

I love it.

All right. So then we're going to go a step further and say if it's shave, we're going to subtract the increment.

Yes.

Now, chat, you can have a tug of war. Right. So let's, shave. We got to set it lower.

We have to set our boundaries and we have to make the hair go. Oh, it's happening though, this is awesome.

Yes, it's working. Everybody in chat hit beard real quick. Let's get the beard to grow. Here we go. Here we go. Old man winter. I love it. Okay. This is super fun. This is an absolute blast. Let's set a limit on the shave so if we say like current minus -- say that if the current is less than or equal to increment, then we will beard dot last names add none. If beard --

Holy buckets, did that just work?

We'll put that in an else so we don't change the style any further. So then if beard dot class names contains --

Yes. It's contains and then the first parameter is the thing. I think.

None. Then we will beard dot class names remove none.

Oh, it's class list.

Class list.

Yes.

Whoops. Can I do multi-select? I can. So this, I think, will work. If we go to shave. Then it should -- nope, not doing it. What did I miss? Current is part INT. If message name is shave, current is less than or equal to the increment which is

  1. Oh, we need to set the -- we're going to just hard code this. If it's less than 80. Okay. Let's try that again.

We could make your beard turn rainbow if it gets past a certain length.

That would be fun.

Okay. One thing at a time.

So we're going to shave, shave, shave and it disappears. No beard.

Beautiful.

If we add a beard, it grows and it grows and it grows. Beautiful. This is exactly what we wanted. Let's now add in the hair. Or okay, question: We have about 20 minutes. Would it be more fun to re-implement this for the hair or turn the beard rainbow when it gets above a certain length. Chat, we have one vote for rainbow. We have many votes for flaps. I think we should do the rainbow, because the hair is basically what we just did. We're just going to change that logic up to reflect the hair instead of the beard. I think the rainbow will be more fun.

Actually, I think the rainbow would be very quick, too. We can potentially do both.

Okay. I'll let you take over. Let's do the rainbow and if we get it fast, then we'll come back and do the hair. And 100 percent once this is over, just so you know, chat, I'm adding this as a game to the overlay so we can play this while we stream.

Okay.

You need to flap when the beard grows, that is also a fun idea.

Can just do it on hover whenever you want. So because it's just -- it's just a div. (music ...)

So because it's just a div, we can just make it so if it has a certain class on it, we change the background to be a rainbow gradient. That should be pretty dang easy. So what I'll do is I'll just add a class of rainbow to it so we can test with it. And I'll say ampersand rainbow up here. And I'm in the CSS at around line 160, if you wanted to show it on your screen?

Yes.

So what we can do -- there's a lot of different ways to do gradients. One of my favorite websites is CCS gradient generator. We could just do some kind of, just gradient on that.

Which one is the -- I just found a bunch.

That color Zilla one.

Okay.

If you go back to the CSS, I just copied one really fast. So we can have this and theoretically -- I'm trying to think how to do this -- I can make the background a little bit bigger and make it so that way it transitions between it. So the background position changes. So it can be a constant moving rainbow.

Oh, that would be fun.

That would be fun. I haven't done this in a very long time.

Could we also set the background repeat and it would tile itself? If we lock the size?

That's true. Yes. Background, if the beard starts growing now, feel free to do the beard command chat.

Give me one second to refresh. I'm going to reload. Okay. So the grow and -- what's going on -- grow and shave should work again.

And it is. Wow. I kind of like it the way it is.

That is pretty fun.

We could have the background size be limited so it grows and stays the same, but I like the stretching gradient there.

If the background size was 100 percent, wouldn't it still scale but also we can set the offset and it would --

Right. Yes.

Yes. Okay.

Yes. So if we just did a background repeat, repeat Y and background -- it's just background size, right. Background dash size?

Yes.

Background size. And then, I don't know, let's just say -- how wide is the beard? 80 pixels, 100 pixels, 110 pixels? I want to see 20 and see what happens. Nice. That actually was intended. So we could make it start with the 100 and as it grows it will just keep repeating that way. And it should -- actually let me end this on violet again. As it grows, this is awesome. As it grows, it should do that. And then I can, I'll manually change the height for a second just to show it. Slowly, for some reason it's not doing it?

Because the JavaScript is overriding.

That makes sense. So I'm going to manually do it in the JavaScript then for a second. Okay. Cool. Then, yeah, we could move the background -- hum, I have not done something like this in a while. But we can do something like this?

What I was thinking we could do, if we set up an animation to translate from negative 100 pixels or like negative 100 percent to 0 percent on the top offset, then the scale was 100 percent tall, then theoretically it should just be like a rotating rainbow that will grow to whatever size. I think.

I think you're right. We could -- let's see -- I'm going to scroll to the bottom and add a bit of a key frames thing. Key frames and in there I'm just going to do rainbow beard as the thing. What we could do -- in there we could have background position be at like 0 and then 100 percent. And then we won't actually see the transitions rotate. Does that make sense? So I think background position zero. I'm pretty sure that's what we can do. We can also just do top and then bottom.

Okay.

Man, this is -- left top and then we can do background position bottom. I think we have to do the left and the right before top and bottom. That should theoretically work. But we will find out. If I scroll back up to the beard and do animation rainbow beard, I'll just do one second infinite and see what that does. Okay. Nothing is happening. Hum.

So, yeah, I think like, I think if we were to go, like, zero and then 100 percent. Oh, but it will change every time it gets --

Every time it grows.

Yes.

Also it's not working at all right now.

I'm not sure why.

Background position.

What if I added background attachment? That might have to do with it. If I did background attachment is fixed. Because that will make sure it's solidly in there. There it goes. That's not it.

Hum.

Hum.

Background size is 100 pixels. Background repeat, repeat Y:

Hum. Background attachment is clearly not it.

Okay. Let's make sure it's not the JavaScript. So I'm going to comment everything out. And now it's going. So I think we might be, it might be the --

I love that it's moving. That is so fun.

It's definitely working.

It's something with the JavaScript. But what?

But what? What about if we make it a percentage, does that make it tile seamlessly.

Wait a minute. It's because we added the class beard rainbow. I think we need to add the class beard rainbow in the JavaScript. We've only removed none?

Yes.

I thought we were just removing --

It doesn't like my -- this background position really should be, like if I change the background position of the beard to be like say negative -- where did it go -- the rainbow. Background size. If we set like background position and we say negative 50 percent. That should change --

Hum.

I don't know what it's -- I don't know what it's arguing about.

It's very strange.

I'm sure it's something simple that we're just not thinking of. But that's okay. This is a problem we can solve later. For now what this will do is turn off the animation and get rid of this debugging that I did, then what we should see is if everyone wants to start running the beard command.

We should uncomment the JavaScript first.

I suppose. Let's run that. Get it in place. There we go, the beard is growing. Just grow that beard or if you want, shave the beard. I'm not going to tell you how to live your life. I definitely think it looks better with a beard.

And we can say if the beard length is past a certain point, that is where you add the rainbow class, otherwise remove it.

Yes. I'll let you do that.

Let's see. If message name is beard, class list contains current -- got it. So we'll say if beard -- I'm going to copy this whole thing really quick. Class list contains rainbow and, this is just going to be the not case. And current is less than -- how big do we want the beard to be for the rainbow to trigger?

Say 160. So like double its usual length.

Great. So then we will remove the rainbow class. Otherwise, we want to just add the class. So if current is greater than or equal to, man, typing is hard. Greater than or equal to 160, then we will add the class list right there. Bill wants the eyebrow to tweak in triumph. What is great about this, because all this is done in CSS, all of these things are possible. Once this is out and open source, if anybody wants to come in and play with this and make it do silly things or build variations of this, you totally can. If you want to, you are also completely welcome to go in and submit new sound effects to learn with Jason. Bear in mind, this is a family friendly show so don't be weirds, don't be gross. But if you want to, I would love to see more sound effects on the show. These are really, really fun. There are a bunch of things you can do. Like this one, this is a great quote from Gant. I think stream Blitz got interrupted by the -- I think it might not be able to connect from multiple places. I think when we hooked it up here, it might have shut it off on the stream.

Oh no.

It's okay. There are lots of fun sound effects you can make. That should work. We can just remove the rainbow class by default. Right.

Yes.

Save. Refresh. All right, Jack, grow the beard. Let's see if this rainbow works.

I'm typing in the chat, too.

Got it.

Yeah. That's so much fun.

Oh, that's great.

I mean this, I'm not going to lie, the amount of progress we were able to make in what has it been, 83 minutes of -- so we started with an empty canvas, and completely empty screen and from there Cassidy was able to build out an HTML document using Hamil. This is just class names and the listing. And wrote out the CSS to do a full -- look at this. All these animations and all this stuff is happening. And Cassidy was able to put that together in 40 minutes or so. And then we spent the rest of the time hooking up to web socket and we're now interacting with the Twitch chat so we can grow or shrink this beard based on chat commands which is super fun. Let's make sure that it shrinks enough and loses the class. So let's shave, shave, shave.

It rate limited.

We're in a full tug of war now.

Oh, dang, it's still rainbow. Why isn't the class list being removed?

Let's see.

Rainbow and the current is less than 160.

That should definitely work.

That should definitely work. That is a very, very simple thing.

We can also just do the check, like not worry about whether or not it contains the class.

That's true. And just take that out.

Yes. Let me refresh to make sure.

It shall grow.

We grow. All right. Now shave. Everybody shave.

Shave.

Shave, shave, shave. It does not want to be --

Oh. Oh.

That was weird.

Yeah. Huh.

Interesting. So it stays rainbow until it's nothing.

Oh, it needs to be in the shave event. Good catch chat.

Good call.

Thanks, Ben.

That was smart.

So then we can move this straight out to the shave event and we'll do that. How about that.

That should definitely be it.

We'll save this. Reload the page. All right, one more time. Beard. Beard. Beard. Now shave, everybody shave, shave?

Shave. I'm doing it myself.

There we go. We did it.

Yes, yeah.

Victory. So I think this is a great stopping point. I'm going to build on this. We'll make -- actually I guess what we can do now since we are done. We'll change to the editor view. I'm going to pull this off to here. If anybody wants to -- let me make it public, too. Go public. Save. All right. Here we go. Now if anybody wants to go and play with this, you can go and set up your own Twitch chat enabled thing. And from here, I think, let's figure out where we should go if we want to follow Cassidy. Where would you recommend people go if they want to keep up with you?

Look up Cassidoo. If you look up my name, there's this Scooby Doo character named Cassidy Williams and I'm not her. So look for the other one and that will be me. Cassidoo is my user name for Twitter and GitHub and code pen. Everybody but Instagram.

Thank you so much for coming on chat. Y'all with champions today. I really, really appreciate you coming in and growing the beard, shaving the beard. Couple solid assists in there from Ben. Thank you all so much for the new subscriptions .I appreciate you all gifing.

Cassidy, thanks for coming on.

Thanks for having me. Get to get these muscles going again.

It's amazing how much you can get done with CSS. With that Cassidy, I'm going to switch over and do a bit of fun stuff. So thank you, Cassidy. We'll see you soon.

Okay. Bye.

And here we go. New scene. I have a monologue scene now. (music ...). So we have sponsors for the show now. So the live captioning is very, very important to me. It's super important to make this show as it's been expanding more accessible to people. So I want to make sure that everybody who wants to can participate in the show, and that's why the live captions are here. And the live captions are provided by White Coat Captioning and White Coat Captioning needs to get paid. As a result, the show is sponsored by Nullify and Fauna. Thank you for making this more accessible to more people. I can still use a little more help. I'm paying for this out of pocket now. So if your company wants to make streaming more accessible to people, I'm looking for sponsors, hit me up. We have a bunch of really fun stuff coming up. Tomorrow on the show I have Thor from stripe coming back. We're going to do a pair programming on subscriptions in stripe and JAMstack. If you are looking to sell things online and you want to get better at accepting money, selling of product, managing access, protecting areas of a site, this is going to be such a good stream. I am so excited about it and what it's going to enable you to build and we have Ryan Warner. A party corgi. He is going to teach an introduction to fig ma. A lot of great stuff going on this week. Thank you chat, we're going to raid. Stay tuned and with that, we'll see you tomorrow.

Closed captioning and more are made possible by our sponsors: