This course has been updated! We now recommend you take the Svelte Fundamentals course.
Transcript from the "Polishing UI & Adding Transitions" Lesson
>> All right, so it's time for the final push. We have a functional game and all we need to do now is polish up the UI a little bit. So the first thing we're gonna do is fix these button styles, because this looks a little bit ugly. So let's go to our welcome component and find the bottom of the styles block and, Just give that a little bit of polish.
[00:00:50] And we're gonna have a media query again 640 pixels, that's our breakpoint. So on mobile the buttons gonna stack, but on desktop they're gonna exist side by side. Okay, that one was way nicer. All right, next thing we're gonna do is we're gonna make sure that when each round starts we've already pre-loaded the images for that celebrity space.
[00:01:32] Otherwise what happens is the image gets created and at that point the browser starts downloading it, but the image is already visible on the screen. So that can create this nasty flickering effect. And we can fix that by loading the image at the same time as we load the data for the celebrities over the network.
[00:01:48] So inside our utils.js, we're gonna create a new function called load image. Which takes in a source and returns a premise. Use the image constructor to create a new image object. This is similar to doing document.create element image. Give it an unload handler, which fulfills with the image object just in case that's needed on error handler, which is just going to reject with the error.
[00:02:28] And then finally we apply the source. And that's gonna tell the browser that we need to go and fetch that image. And then inside the game component, we can now use that import it at the top here, load image from utils.js. And then inside our load details function where we're going and getting the JSON for each individual celebrity.
[00:02:53] We're not gonna return straightaway, we're just gonna store that for minutes. Const details equals the JSON, and then we're gonna wait until we've been able to load that image. And once we've done that we can return those details. So now you'll notice that there's no flickering between rounds.
[00:03:20] The images are there immediately, not flickering. That's a much nicer experience. And while we're at it, we can go to our app.svelte import the same helper. And once we've mounted we can just preload the icons that will otherwise again, only load once we first get the result, which can cause that ugly flicker.
[00:03:59] We don't need to await anything here. We're just gonna kick those off in the background, so that by the time they needed, they'll long since I've been loaded. Okay, on the game component, right now it's just appearing there and then kind of gets replaced like that. What we want is for the games have a nice subtle transition.
[00:04:23] And we're gonna use the fly transition that we saw earlier when we were going through the tutorial. And if you remember, we just need to import fly from svelte/transition. Gonna import an easing function as well, or a complete set of easing functions from svelte/easing. And then on div class equals game.
[00:04:55] You're gonna wanna apply that fly transition. When it comes in, We're gonna come from 20 pixels below. When it flies out, we're gonna go to 20 pixels above. So now you got that nice there. But there is a bit of a problem, you might have just seen that flicker there.
[00:05:26] What's happening is the new round is being rendered while the old round is still out showing, and that causes a little bit of upset. So we're gonna make sure that that doesn't happen by blocking the rendering of the new round until the last round is fully off the screen.
[00:05:42] And that's easy enough to do by adding a new value, let ready equals true. And then only rendering the screen when ready is true and then setting it to false when the outro is happening. So we can use that on outro start event, To set ready to false, and then we'll just set it back to true again once the outro is finished.
[00:06:16] So that will prevent that error from happening. They'll go out next one comes in, everybody's happy. Now you will notice on the the deployed version. If I click on one of these, I'm gonna guess Andy King has got to be, the icon is gonna fly and then it's gonna go down to the results block.
[00:06:42] And that is an example of a crossfade transition like we saw in an earlier section of this workshop. So we're gonna wanna add one of those, close these components that I'm not looking at. Up here, we already import the fly transition, we're gonna import crossfade as well. And we're just gonna create the send and receive transitions.
[00:07:13] Give it some configuration. This is cubic out, and that's gonna happen in 300 milliseconds. So we're gonna take these transitions and we're gonna apply the send transition to the giant image. So you get sent to the results block, and on the results block we're gonna have the receipt transition.
[00:07:42] So that's gonna come from the center of the screen down to where it belongs. So the element itself isn't moving. There's basically two elements and one is shrinking and fading out. The other is growing and fading, no, they're both shrinking and the other is shrinking and fading in.
[00:08:00] And, All we need to do is find our giant image, and on that we do out. Actually before we do that, we're gonna add an in transition on the giant result image, because we want it to move onto the screen and then come down. So we're gonna fly in from, 100 pixels to the right over 200 milliseconds.
[00:08:33] And then the out transition, that's where we're gonna use send. And we need to give it a key so that it knows what the correspond to. And we're just gonna use the index of the round. And then we need to apply the corresponding received transition to the little icon down here.
[00:08:57] We need to have the index into the results array visible. So we're just gonna add a comma i, same signature as when you using dot map and dot for each on an array. In receive equals key i, k, let's see if that's working. It is not working. What did we miss here.
[00:09:30] Okay, so a moment ago, I was trying to figure out why the crossfade transition wasn't applying, we click on one of these spaces it flies in and then it just snaps it to the new place. And the reason for that is that we're immediately going from removing the result to advancing to the next round.
[00:09:48] And we need to have break for that animal to come down into its new home. So we're gonna add here a weight sleep 500 just give that a chance to get where it belongs. And now we should see that comes in and goes down to the results array.
[00:10:14] We're just gonna add a few more transitions just to make things nice and slick. On the card component, we'll import the scale transition. And we're gonna use our friend elastic out from spell easing. And we're gonna apply that to the price, so that when the price is displayed, those sort of [SOUND] come in like that which is a sort of a fun effect I quite like using.
[00:10:57] And we'll do the same thing for the done screen. At the scale transition from self transition, and then find class equals done. Apply the in scale equals give it a very short delay, a duration 100 milliseconds or so, easing, We use the same one for consistency. Okay, now when we click on one of the faces, the price [SOUND] comes in like that.
[00:11:42] It's kind of fun. Subtle tweak on the car component, I'm gonna add a border radius. Using a variable setup in our global.css, and we'll add a nice little box shadow. And that is basically everything in the game itself. All that remains is to do a lighthouse audit and see what it suggests.
[00:12:28] So I maximize this move my Dev Tools over the right hand side. [SOUND] Looks like we do in fact have something to fix here, which is our buttons need to have, A width of 100%. I'm gonna add that to the welcome screen.