 Welcome to another episode of GUI Challenges, where I build interfaces my way and then I challenge you to do it your way. With our creative minds combined, we will find multiple ways to solve these interfaces and expand the diversity of our skills, and in today's creepy spooky GUI challenge, we're building this Halloween projection. That voice is ridiculous, it sounds like a WWF wrestler is trying to be British and creepy or something, so much to tell that guy that it's a terrible creepy accent. Well anyway, today we are building a Halloween projection and I saw one on the wall and I was like, I could totally make that one CSS plus, it makes for a great GUI challenge this month where you too can build a spooky projection, so I'm looking forward to whatever it is that you build that kind of emulates this infinite projected concept that you can put on the wall. Anyway, let me break down how I built mine and perhaps it will inspire you to build one of your own. So the setup here that I have is I have four SVGs, we can see them over here, I currently have the overflow set to hidden on the body so I can't scroll it down, but you can just just trust me that there's four like nice SVGs and you can see they scale up really nice, I've made them lime green and here we can see that in the Halloween projection here. Look, I used the handy dandy shorthand hex with alpha. So I'm just doing red at zero green at maximum blue at zero and then a little bit of alpha. So a being somewhere in the middle, you can go up to F or down to zero. So that fourth parameter there allows you to specify some opacity. So right, these need to be kind of ghosty, kind of spooky. And so I made them a little transparent. So if we go back to here, we've got our SVG. Now one of the first things that I did is I took my general setup here, which was I just put a display grid on the body and I place everything in the center. But if you set this and you target each direct descendant and you assign them the same area, they'll stack on top of each other. Look at that, we got ourselves a little pile, a grid pile. And maybe you've even heard me talk about that. It's such a handy dandy layout concept. So now they're all in the center. And that is really helpful because I kind of want everything to revolve around the center of the screen and we're going to go in and kind of tweak those. But that's the setup here. I've also imported the open props easings. And that's because there's a couple of them in there that are really dramatic. And I really want that like, you know, push and then slow skid to stop. Almost like this ghost is launching out of the wall or something like that. Anyway, and open props has those stash and they're nice and easy. Then we're going to import some animations and we will pull in our projection Halloween projection styles. So let's go look at some of the animations just so we know what it is that we're working with because the way that I like to build my animations is in a way that you can layer them all together. So let's check that out. I've got this one. This one's called across the screen. And so in general, what it does is it sets the translate X to negative 110 and then animates to positive 110. And that's going to make it go across the screen. And you can see that I've added a rotation custom property in here. So there's an optional amount of rotation that you can pass to this just by having this custom property present on the element. And that's going to allow me to rotate one skull head one direction and the other skull head the other direction, but still have them launch across the screen. I have this other one called crossfade and it is kind of a little bit tricky in the syntax here, but not really once I explained it to you. Basically, we're going to be at zero opacity for zero to 10% of the animation and then 90 to 100% of the animation. So we're going to kind of fade in and fade out and then we pack our opacity animation and then we hold our animation from 220% to 30%. And you can see that as the shoot across the screen, they'll very subtly fade in, but also subtly fade out. And so I just kind of timed those animations with the easing. So I got a nice crossfade. Again, I want it to look ghosty, right? And ghosts kind of come in and out of appearance. And the last one here is that flicker. This is just a handwritten opacity animation where I've got at zero. It's invisible at 2%. It shows right after that it hides again. Then we kind of hold that hide until 5%. And then we show again, and then we hide, and then we show and we hide. And at the end, we just kind of hide for a long time. And that's why we'll see that these skulls in the center that do this sort of flickering, they go invisible for like a pause. And that's so that there's sort of like a dramatic moment where you're like, is it gone? Is it coming back? Oh, no, the ghost is back. And it's so spooky or whatever, right? Maybe? I don't know. And then if you notice too, we'll go over it, but those skulls that were in the center were slightly offset, which give them this like unnerving amount of combining and flashing and showing. And anyway, good thing to note here before we get into the rest of this is there is going to be a decent amount of flashing on the screen and a lot of motion. So if that makes you uncomfortable, I would just skip this episode and go right to the demo where it does respect your preferred reduced motion and you can kind of go inspect just the generic way that the animation was done. So anyway, that's where we're at that. And now we can get on to the good part of how did I combine all of these animations and these skulls together to make something kind of creepy? Well, the first thing I did is I have a size here. So they're all about 50% of the smallest part of the viewport, which means this does work good on a portrait phone, a landscape layout, you know, a big screen, a small screen. The skulls are going to scale with the viewport. And then we're going to rotate them so that they kind of move around inside of there. All right, so let's look at skull teeth. Or should we start with another one? Let's start with skull scream because that one kind of goes across or wait, let's do these are so hard. There's so much fun. Let's do skull sad. No, we're going to do skull stare and skull teeth. I should probably have put these next to each other because these are the two that layer on top of each other. So let's bring both of those in and see what we got. All right, they're flickering. That's good. So we're going to open up skull sad and just set it to display none really quick. We don't need to see this guy at the moment. And same with skull scream. So we'll pull these in just to hide them because we want to focus on these two. All right, so how are these working? They both are using, oh here, we'll close these out so we can kind of see what we're working with. Skull teeth says, OK, if the user's OK with motion, go ahead and play this flash animation. It's going to last for five seconds and it's got a 20 millisecond delay on its beginning and then it runs infinitely. And this one over here is going to flash for five seconds also with the same amount of easing, nothing extreme here because we're just flashing back and forth and no delay. And now if you look at the monitor and the way that these are flickering in and out, I've just so barely offset their animation and they kind of drift over time and it gives it this like really creepy kind of vibe as they overlay each other. One looks evil, one doesn't, but when they merge together they look super evil. And all that's doing is playing that animation. They both are using the same one forever, which is just a slight delay. And all of a sudden we get this kind of like creepy offset because right, it's like not in line. These things are, they're in disarray and disarray is scary, right? Anyway, all right, let's twirl open skull scream. We'll set the display to none here and pull out these animations just so we can bring in piece by piece what's going on here. So there's our screaming skull. Now one of the first things I'm gonna do is I'm going to, well, let's do this and do this. So we've got a rotation, but remember that rotation is only part of the animation. So that's going to tilt it once the animation kicks in and it goes across the screen. Across the screen is gonna take that rotation. It's gonna rotate it first. Now this is critical. Notice that rotation is first. The transform property, when you set this, you have to do things in order. And so when I rotate first and then travel, it's like turning your own body to the right and then walking straight as opposed to walking straight and then turning right. We want the skull to sort of go across the screen in an angular way, not just be tilted and going straight across the screen. So we need to rotate first. And so it's very critical that that is in there first. So, okay, so we set the rotation and now we can set the position here. If we set position place self to start, that's gonna set both the alignment and the justification properties to start and look at tucks itself into the top left corner. And that's because this was using the display grid pile technique where these things are sharing the screen. It's like one big square, one big single cell grid and I can tuck it into the top left by saying, hey, you place yourself at the start of the inline and the block axis and we get ourselves in the top left here. Next, we can bring in our animation. And so let's bring in just across the screen first. And so now it's going to travel across the screen. We're using this very powerful easing here. This is an easing out five from open props and that's a very dramatic, very strong easing. And if you use this easing with a short duration, it doesn't look very good, but it looks really good with a long duration. Look at how it just like, it kind of like pumps in with all this force and then it really slows down at the end. It's again, it's really dramatic. And also this one's five seconds. So most of these animations are five seconds or something around there so that they sort of harmoniously are infinite, but they also drift. You'll see what I mean in a second. Okay, but also look, it's not as ghosty as it could be. It's not fading out. It doesn't have any kind of concept of fading in. And so we'll bring in that cross fade animation. So look at how we're layering these with a comma. We're going to say cross fade for five seconds. Again, use that strong ease out and do it forever. And we'll turn that on and see the result. And we should see a slight cross fade at the end here. I didn't see it in that last pass. I'm going to reload to make sure that it's really picking up these changes to the keyframes. Boom, there it is. You see it fade out. Now it's got that ghosty vibe, just like we're in Mario and a ghost is coming in the screen and then it turns around and goes out and just sort of like fades out or whatever. So anyway, that is our skull scream. And now we can do our last one here of skull sad. So I'm going to get rid of display none. I'm going to keep our rotation. I'm going to get rid of our animation and just kind of show you how I placed it. So again, the rotation is only going to come into effect once it has been transitioned with the transform property. So then we'll place self. We're going to put this one in the opposite corner. So it's up in the top right. And now we can work on our animation. So the first thing we're going to do is we're going to animate across the screen for seven seconds instead of five. We're going to again, with a really strong ease out. And then here's a couple of kickers. The first thing is we start at negative six and a half seconds. Now that's kind of tricky. And if you look at how animations work, you can kind of reverse them and go back in time. And this is going to allow it to kind of be a little, again, it's like a half second offset. It's going to start in the top right as opposed to like the bottom left and look, we reverse the animation. So we take those key frames and we're like, instead of going from left to right across the screen, I want you to go from right to left across the screen. So I'm going to hit save and we can see that now. So it's going to be turned a little bit and it's going to shoot across the screen and fade out. And again, the fade out is because we have our crossfade set to the same duration with a similar amount of easing. Again, negative six and a half. So these things are linked up and we've got ourselves a really cool looking animation. So that's pretty much the gist of it. I think the kind of coolest things that happened here were the really strong easings, the slight offsets and the durations and then the concept of combining your key frame animation. So instead of making like one mega key frame, which is probably the tempting thing to do here is to add your opacity changes and your transforms and your rotations all in one set of key frames and just make one for each of them. But in this case, I made some more abstract generic key frames that then could be shared across these different instances. Like for example, I could make one of these flash. I doubt it's going to be that great, but let's check it out. So this one's now going to flash at the same duration. The other one, it's got a slight delay. Who cares? We'll just set infinite. This one kind of flicker across the screen and see if it's any creepier than it was before. Oh, did you see it? It kind of drifted off over here. We're just going to catch it. These kind of like awkward moments. It looks like they're kind of consistently awkward moments only there at the end. I wonder if that's because of the way that the key frames were written that had that hold where it like stays out for a little bit. Let's actually set this to like negative two seconds and see if we get a little bit more of it. Oh, there's some flickering over there. Okay, let's get some awkward flickering in the animation here. Oh, that's actually kind of terrifying. Adds to the creepiness. Oh, that's way too stroby though. So I'm going to go ahead and take that out. Anyway, that's kind of the fun part about having these key frames that can be composed together as you can find yourself building a new, more interesting animation by combining things like slide up and fade in, right? And now you have slide up fade in with two generics combined to make something cool. So that is it for today's creepy gooey challenge. I hope you learned something new. I hope you feel inspired and you too should go build a Halloween projection and put it up on your wall, share it on your screen and just this is a good month to spook people out. And I'll see you all on the next gooey challenge.