
Lesson Description
The "Creating an Image Slider" Lesson is part of the full, Intermediate React, v6 course featured in this preview video. Here's what you'd learn in this lesson:
Brian demonstrates how to create an image editor using React. He integrates various editing components into the app component and uses React hooks to manage the state of the image properties. The resulting image editor allows users to dynamically adjust the image filters using sliders.
Transcript from the "Creating an Image Slider" Lesson
[00:00:00]
>> Brian Holt: Okay, so start our template here and then the completed one, we already did that, so we are gonna go into our projects. Nothing in here is particularly interesting. The only thing is here I have an image of everyone's favorite tiny terrorist, which is my dog, Luna. But feel free if you want to just replace Luna.jpg with your image that you want to be edited, cuz we're gonna make a little image editor.
[00:00:28]
>> Brian Holt: Okay, so let's hop into this, and we're gonna create a file here in source called slider.jsx. We're going to export default,
>> Brian Holt: Function Slider, and this is gonna have value, defferedValue.
>> Brian Holt: All right, I just called it deffered, I guess, yeah. Unchanged name and max,
>> Brian Holt: Okay.
[00:01:10]
>> Brian Holt: And then we're going to return, this is actually just gonna be like the actual slider control. So you're gonna have an LI, I'm gonna call this className ="slider". And we're gonna have label and it's gonna be htmlFor=(name).
>> Brian Holt: Name, and then underneath that we're gonna say, if value is not equal to deferred,
>> Brian Holt: Then we're gonna say it's updating.
[00:02:00]
>> Brian Holt: And if it's done, then we'll just not put anything, okay? And then we're gonna have an input here,
>> Brian Holt: And a bunch of stuff. So type is gonna be equal to range, that's what we call sliders in browser speak. Name, id is name, name is name, min is gonna be equal to zero, cuz I think everything that we are gonna be doing is zero, and then the max is just gonna be equal to max.
[00:02:34]
>> Brian Holt: And then value is going to be equal to value, and onChange is going to be equal to onChange.
>> Brian Holt: Okay, close that tag and then we're gonna have an output,
>> Brian Holt: htmlFor=(name), and actual value is going to be value,
>> Brian Holt: And deferred value is going to be deferred.
[00:03:10]
So mostly a lot of this is just so we can actually see how much is lagging across, dragging these sliders. Beyond that, not that interesting. This part is actually kind of interesting right here, this is how you tell if something is out of sync. They don't give you a, is updating flag.
[00:03:33]
So the way that you check that is if you see a value and deferred or not the same thing, then you know that they're outta sync.
>> Brian Holt: Which is good, right? That's actually what we want, we want deferred and value to be different.
>> Brian Holt: Okay, now we're gonna go create a file here called display image.
[00:03:52]
Display image.jsx, and we're going to import img from images/, if you're just using my file, then just do, it's Luna.jpg. But if you put your own file to do in there, just put your path in there. Const JANK_DELAY, we're gonna put 100 milliseconds of delay in renders, and then we're going to export default function display image.
[00:04:24]
And then we're gonna take in a filter style.
>> Brian Holt: This is just gonna be a CSS string of all the filters that we want to apply to something. We're gonna take that same expensive render function that we used before, again, just to really make this super obvious of where this can be helpful.
[00:04:44]
>> Brian Holt: Generally, don't suggest shipping this function in your code, that's a Brian Holt pro tip right there.
>> Brian Holt: Performance.now, it does remind me at my first job, I found Someone was doing UI testing and had artificially slowed down the UI and then left it in there for several years.
[00:05:09]
And everyone's like, this page is always really slow, and no one knew why, but no one wanted to touch it. So it just stayed for a long time.
>> Speaker 2: Then you get to introduce the performance enhancement.
>> Brian Holt: Man, I looked like I was the Greek god of performance.
[00:05:22]
So I was like, I have fixed the [LAUGH] web page. Yep, that's how I got a promotion. That's not true.
>> Brian Holt: But the developer that had introduced it had left already, so we did get to make fun of that person behind their back.
>> Brian Holt: Okay return null, this is the exact same one that we did before.
[00:05:47]
>> Brian Holt: And then we're going to return, we're gonna put this into these empty tags here. Then we're gonna first do an expensive render, and then we're gonna do img src=(img), alt equals whatever you wanna say, I'm gonna say Luna, and then style=((filter: filterStyle)), something like that.
>> Brian Holt: And then we're just gonna say <p>Last render:</p> so that you can kinda keep track of this as well, of how frequently this changes.
[00:06:23]
Date.now(), okay, that is it for display image. Basically, we're simulating that this is a very expensive image to render that the image processing is going on here and then it's not just CSS and it's gonna go really slowly.
>> Brian Holt: Okay, now that we have this, let's go ahead over to app.jsx.
[00:06:54]
>> Brian Holt: Okay, import useState from react. Import slider from slider, and import display image from display image, and export default function app. And we're gonna have some several hooks here const blur, set blur.
>> Brian Holt: useState, and we'll have this one start at zero. This one will go from like 0 to 20 pixels, cuz once you're beyond 20 pixels of blur, it's blurry, right?
[00:07:31]
It doesn't help [LAUGH] to get further blurry. Const, brightness, brightness, wow, damn, that's not capitalized, setbrightness. This one will have start at 100 cuz 100 brightness is a normal image. So useState 100 and then we'll allow people to set it from 0 to 200. Const contrast, I think it's the same thing here for contrast, setcontrast = useState(100).
[00:08:06]
And then const saturate,
>> Brian Holt: Setsaturate,
>> Brian Holt: This action again, retrospect is a 2020 here. But this would have actually been a perfect use case for use reducer. I hadn't really thought about that, but this would actually be really good to use with use reducer. So that's a revision that I leave to you to to do after this is go refactor this to use reducer.
[00:08:38]
Const sepia setSepia, that always happens with me with use reducers, I'll write like this entire function and then I'll realize later this would have been way simpler with the use reducer.
>> Brian Holt: useState(0). Okay, we're gonna make a filter string. So filter style equals blur, and we're just gonna make this a string like this.
[00:09:04]
>> Brian Holt: Blur is going to be,
>> Brian Holt: Blur px.
>> Brian Holt: Brightness is going to be, this is just all valid CSS, but brightness percent, you can actually do the rest of these pretty similarly. So this one, and this one can be contrast, this one and this one can be saturate, and this one and this one can be sepia.
[00:09:43]
If you're not following on VS Code, it's, it's command D that I'm hitting that allows me to select the next version of this. And then I can type both of them at the same time. Most of my expertise in VS Code comes from someone on the VS Code team yelling at me when I was not doing something that they had built.
[00:10:05]
>> Brian Holt: Learn by shame is actually a very powerful way of doing things. That's why I'm proposing a rebrand in front of masters to shaming masters. Send me my check in the mail, okay. <div className="app">. <h1> will be deferred values, okay. And then we'll put our display image up here, and the filter style will be equal to filterStyle.
[00:10:38]
You definitely could have parsed all of these directy into display image and just use that in there.
>> Brian Holt: I liked this because it still encapsulates everything, and it's actually what display images needs, right? So it made sense for me to do that, display image here would still be memoizable, because this will change every time that something changes.
[00:10:57]
That's kinda the thought process that I have in the back of my head. Both are valid, though, okay, and then we're gonna have a <ul> of sliders. Could really go for a slider myself right now. Value equals blur,
>> Brian Holt: Deferred, we're just gonna make this like all the same right now, so it's also going to be blur.
[00:11:27]
>> Brian Holt: And on change is going to be e, setBlur(e.target.value!), name="Blur", and max="20".
>> Brian Holt: Okay, so that's blur, and we just need to do the same thing for all of these. Again, if I was doing this by myself, I would probably just say, hey, copilot, use all these hooks, rewrite all these for me.
[00:12:10]
But let's just go ahead and I don't know, do you wanna see if it works? Let's see if it works. So,
>> Brian Holt: Give me a slider for each of the react hooks that I have.
>> Brian Holt: See how we do.
>> Brian Holt: It's using Cloud 3.7 Sonnet, which is usually pretty good.
[00:12:44]
>> Brian Holt: I think I might have it on the thinking model. It takes a lot longer, but the code you end up getting usually ends up being better.
>> Brian Holt: Man, it even got the max numbers right, which actually I find pretty impressive. So again, all I had to do is generate a slider for brightness, contrast, saturate and sepia.
[00:13:08]
>> Brian Holt: I think I'm most impressed that I actually got the max numbers right. I was expecting to have to fix those at the end.
>> Brian Holt: Cool, any questions about that?
>> Brian Holt: Right, I need to run the server, please do that. This one does not have a server component, so you don't need to do that.
[00:13:34]
>> Brian Holt: So just npm run dev is fine,
>> Brian Holt: And let's try running this again. So we have our tiny terrorist right here. All these are set to correct things. And then kinda jank, right?
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops