Learn How to Crop Images With React Easy Crop

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] in this video we're going to be learning about cropping images in react with an npm package called react easy crop this is the project that we're going to be building as you can see we have several pictures on this page if i go ahead and click one of these pictures you're presented with an image crop dialog from this dialog you can zoom into a picture using your mouse or you can go ahead and use the slider below we also have different aspect ratios you can select so you can see that these square boxes over here change depending on the aspect ratio that i select it's like one by two you can see it's really narrow like 16 by nine then we have this wider view let's go ahead and do something interesting with this picture over here so i'm gonna do is i'm gonna be zooming in over here i'm gonna zoom in right onto these tires go ahead and click crop and then we get this interesting picture and go ahead and click it and then edit it this remembers the zoom level that we had and the aspect ratio that was selected once i fine tune it i can go ahead and click that crop button again i can do the same thing with other images over here go ahead and grab this lotus picture maybe kind of zoom in on it click crop the other functionality that we're building is the ability to reset it so if i click reset that picture goes back to what it was and then this picture over here the porsche perfect example of being able to just select one car so we're going to select that porsche click crop and then we have that single image and then some other examples here the 16x9 which i think look really great over here with this lamborghini and kind of just zoom out get it perfect in the shot and then click crop so this is the tool that we'll be building in this video we'll start the project by doing npx create react app and naming the project image cropping with react easy crop we can then open the application in visual studio code by going to the directory and then typing code dot or within visual studio finding the folder clicking the open button and opening that project so for the project setup over here i just have visual studio code on my left and chrome on the right then we'll go ahead and start the application up you can open up the terminal by hitting ctrl tilde on your keyboard or you can go up to the menu go to terminal say new terminal and then all we want to do is run npm start for this application we're going to have a list of pictures so we're going to put those pictures in our public directory and i'm just going to create a folder called images and inside that images i'm going to go ahead and drag in a few images that i have the same ones from the demo you can use any images you like for this project these are the images that i'll be using before we go any further with the code let's go ahead and install react easy crop so from our terminal over here i'm going to click the little plus button this terminal is still running the app this terminal over here will do the installation all we got to do is npm i react easy crop and i'm going to install a specific version of it you can install the latest one and this will most likely work however if you have any issues fall back to 3.5.2 let's go to app.js and start creating our application we'll jump to the app.js file in the rc directory i'm going to close a terminal over here also close the sidebar and then what we'll do is we'll just delete everything that we don't need i'm going to delete everything inside of app and i'll also delete the logo over there and inside of the app we'll just put a div for now that says i and that's all we're going to have on the screen at the moment inside of app.js we're going to go ahead and create a data structure to represent the data that we're going to be showing on the screen i'm going to call this initial variable called init data which stands for initial data it's going to be an array of objects and those objects will have three properties each one will be the id the image url which will be images slash r1 dot png and another property called cropped image url which will be null and then we'll just repeat that for there are other images that we have as well we can just duplicate to that and then using a nice little trick inside visual studio code what i can do is create multiple cursors and update various values so for example i can just change those to two then over here i can select that one over here and just hit command d on mac or control d on windows so i'm going to do the same thing over here and just change that to four and we have our initial data we're then going to take that initial data and set it as the state on our app and the way we're going to do that is we're going to use hooks so we're going to import use state from react then inside the application over here what we're going to do is we're going to set up a constant we're going to call we're going to extract cars from our use state and the set cars method and we're going to say use state and we're going to pass in that initial data that we have next we'll go ahead and use our state information within our return over here we're going to use that to display the images so we'll grab those cars and we're going to do a map and each item is a car and what we'll do is we'll put a div and then we'll close a div over there and then inside of the div we'll put an img and what i'll show you over here is the fact that you can see it's better formatted because i'm using prettier and automatically formatted it for me also make that image tag self closing and then on the image track we're going to add an src and that rc will take in the car and the image url and then if i click save you can see the images and we're just gonna do a bit of styling so that they don't take up so much space on the div above our image over here we're gonna add a class name and we're going to call that image card then what we'll do is we'll go inside of our app css and inside that app.css we can just delete all that contents we don't need that then we'll just add an image card over here selector and we're going to do text align center which won't make an immediate change then on the image card we're going to select the img tag and we'll just set the width to 600 pixels and now the images fit nicely on the screen we'll go back to our app.js over here and we'll just take care of this little error over here that mentions we're missing an alt tag next let's handle the on click event that'll be fired when we click on an image so what we're going to need for that is another piece of state called selected car we'll go ahead and add a selected r and a set selected car and that state is just going to be set to null then inside the image we're going to go ahead and add an on click method and we'll just define an arrow function that arrow function will go ahead and set the selected car equal to the car that we get from our map function if we have a selected car we're going to go ahead and display a new component called image crop dialog and if we don't have it we're just going to return now now when i click save we're going to get an error so to resolve this error we're going to go to our src directory and add a brand new component called image crop dialog we can call that js to speed up my imports i'm using react simple snippets which is a great plugin and you can see how quick it is to go ahead and kind of just create a simple file and inside this simple file i'll just put a div here and we'll say crop and save it then what we're going to do is we're going to go back inside our app.js over here and we're going to import our image crop and now our screen will be working and if i click on any one of these images you'll see it just says crop in our html over here for image crop dialog we're going to pass a few properties in so the first property we're going to pass in is the identifier of our selected car we can pass in the selected car dot id then we'll grab the image url and we'll get that as well from our selected car i'll save that so that it formats it and then additionally what we're going to do is we're going to also grab a few other properties that we need to we're going to have this initial property for our zoom our crop and our aspect ratio if you recall whenever we clicked on one of these images it always remembered what those values were so that information will be on our selected car so we're gonna grab our selected car crop then we'll also grab our selected r.zoom and then lastly the aspect ratio that we've set by default these values will be null which is okay and we have our aspect and these are the values that we'll be passing in let's go into our image crop dialog and now that we have all those properties that we're passing in let's get them over here so we'll get our identifier our image url our crop init our zoom in it and our aspect in it now we're going to use the properties that we passed in we're going to check if the zoom in it is equal to null if it is equal to null we're going to set the zoom init equal to 1. we're going to check our drop in it as well and if that value is equal to null we're going to say that the crop in it is equal to an object that has an x position of zero and a y position of zero so this is the drop and where it starts and then lastly we'll check our aspect init and if our aspect init is equal to null we're going to set it to an aspect that we're going to define in a little array called aspect ratio and we're going to select the first item in that array so aspect ratios doesn't exist we're going to get an error so at the top this file let's go quickly define that little array that we have inside that array it's going to look like this we're going to say it's equal to this array and we're going to have values so 4 divided by 3 is going to be one of them and we'll have a text value that we display in our drop-down so that will just be four over three like that and i'll define two more of those so that we have several different aspect ratios for our project we'll have a 16 divided by 9 or 16 by 9 and then for fun we just have a half over here 1 by 2 and 1 by 2. now when we save we won't get that error anymore let's get to work on displaying that crop dialog so this html that we have over here what i'm going to do is i'm going to leave an outer div and then inside this div over here we're going to have another div that's going to represent the backdrop so when the dialog shows that the back of the screen will go all black it's the same screen but we just have this thing called a backdrop then below that backdrop we're going to put another div and that div over there will be our crop container so all of this is setting up so that we can show the cropping container and then inside here we are finally going to show that crop let's go ahead and import our cropper so we'll import proper from react easy crop then what we're going to do inside our crop container we'll define our cropper here i won't click save just yet one other thing we're gonna do is below our cropper we'll add another div and this div over here is going to contain all the buttons and drop downs controls that we want for our page we're gonna give it a class name of controls and this is where all the controls will go our cropper is going to require a bunch of properties to be passed in and some of those properties will be coming from our state what we're going to do is we're going to go ahead and define some state that our cropper will be using so these initial values that we passed in and set we're going to be setting state for each and every single one of them so for our zoom over here we'll go ahead and set some state for that we'll have a zoom a set zoom and that'll be equal to use state and it'll take in the zoom in it then we'll do exactly the same thing for the drop we'll have a set crop is equal to use state and it's going to get that default prop value and if it's not set it'll be set to y0 and x0 the other one is our aspect ratio so that'll be aspect and set aspect is equal to the use state and we'll get our aspect in it one last piece of state that we're going to want to track is the cropped area pixels we'll go ahead and define that as well before we continue let's go ahead and just resolve a couple of issues here i've noticed that i didn't actually destructure passing into my image crop dialog function here just make sure to put those curly braces so actual destructuring happens and then back inside the app.js over here inside the image crop we're expecting an image url and over here i called it image so i'm just going to rename that to image url and lastly one thing we could do is just quickly resolve this error over here where it says that we need a key a unique key for our list and on our div we're going to do is just say the key is equal to car.id and hit refresh and that error will no longer be there let's go do the minimum require to go show our crop dialog so inside our cropper over here what we're going to do is go ahead and pass in the image and give it the image url that we pass in we're going to give it the zoom value which is just equal to zoom drop which is equal to crop and it requires a function called on crop change and we're going to make that equal to a function that will define inside here we'll just define a function where we aren't going to make it do anything yet we'll say const on crop change is equal to and we'll make it an arrow function that doesn't do anything yet so just an empty arrow function and pass that in over here click save now we'll go ahead and just click on one of these images and represent it with our dialog we can't do anything with it yet because we're missing a few methods we can't dismiss it or click it with the crop dialogue you're supposed to be able to drag this side to side in order to select your crop well that's controlled by the crop and the on crop change so to illustrate this real quick we have our x over here if we change the value to 100 and we click save and you click refresh and then click on that you can see that this box has moved you put it at zero and hit refresh the box will then be in the middle in order to drag the box around all we have to do is update the crop value on crop change on crop change takes in the crop so we just have to call set crop for our state and pass in the crop then when we update our application and we use it we'll be able to drag this box side to side to select our crop value let's also take a look at being able to zoom in and out of our picture the way we can do this is there an event called on zoom change and we're going to create a function called on zoom change and we'll implement that just above over here so we'll do const on zoom change and kind of like our crop as well it's going to take in a zoom value and then all we have to do is call set to zoom since we're tracking that state pass in the zoom value now when we go back to our application and i'm just using a trackpad here so i'm pinch zooming to go in and consuming to go out i can move this around to zoom to very particular parts of this picture if i want to to complement our zooming we're also going to add a slider but before we move forward let's add a little bit of styling because frankly this doesn't look too nice so let's go over to our app css and we're going to style a part of our application so we created something called a backdrop now i'll remind you where that is we go back to our backdrop over here so we added a div and we called it backdrop this div over here so we're gonna add take that and we're gonna go ahead and add a style we'll call that backdrop and then what we're going to do is we're going to create a div that kind of encompasses the whole screen so what we're going to do with that is we're going to position it fixed then we'll set a background color of black then all we're going to do is we're going to take this thing and we're you can kind of think of it like stretching it we're going to stretch it to the top we're going to stretch it to the left so that it just takes up the entire screen we're just setting all these values to zero and then click save and now this backdrop is hiding our main part of our application with all our pictures and then we'll also go ahead and add styles for our crop container over here we'll go back into our app css over here and kind of like the backdrop we're going to also going to position this fixed then we're going to be using these values once again and we're going to say from the top so start from the top take up the entire left take up the entire right but at the bottom leave 80 pixels from the bottom what that means is going to be a gap down over here and that's we're going to put the controls such as the slider then we're going to go back to our image crop dialog inside our controls area we're going to go ahead and add a div we'll add an input of type range and we're going to set several values for this we're going to say min is equal to one max is equal to three so we can zoom three times the number the step which is each little increment of the slider will be 0.1 the value we're going to grab from our state which is the zoom then then we're also going to add an event to capture when the value changes and that's called on input and on input we'll take in the following function we're going to give it the e over there which represents the event that was fired and then we're going to call the on zoom change that we created earlier and all we have to do is say e dot target dot value and then the last thing that we're going to want to do is we're going to want to add a class over here as well so we can add some styling and we're just going to call that slider now when we click save it's not going to show up yet because we need to make the controls over here show up let's also go ahead and add a class on this div that contains the slider and we're just going to call that controls upper area then we can go ahead and go back to our css over here and we'll say controls so we'll start with the controls we'll start with the outer div up here and grab those controls and we're just going to make that div viewable on the screen we'll do that by positioning it on the screen so we're going to call position over here we're going to do fixed once again the bottom of this will be 80 00 pixels 0 pixels as you know the other one goes down to 80 so this one will go up from 0 and we'll also set the height to 80 pixels so now our slider shows up the next thing we're going to do is we're going to do dot controls dash upper area and we're going to do this to make it aligned center so do text align center then lastly we're going to grab that slider and style it itself so grab the slider and we might as well set its width to 50 percent and that will make the slider a little bit bigger now if i zoom over here at my mouse and i zoom in like this you're going to see the slider change you can also grab the slider and you can see it increments little by little there zooming in and zooming out we have our slider working and showing up on the screen next let's go ahead and implement our aspect ratio drop down we're going to put that right after the input over here so we'll use a select element inside the select element it will have options and we're going to map them from our aspect ratios that we defined above i'm going to call each one of these a ratio and then we'll create an option it will need a key value that key value will be equal to the ratio.x value you recall our ratios have two values as a value and a text value we're going to use the text value as its unique value then we'll set the value equal to the ratio.value which will be a number then we have to determine whether or not it was selected and it will be selected if the ratio dot value is equal to the aspect dot value now the aspect to dot value is going to be a number so that's why we use that and that's coming from our state over here as you can see there's our aspect and then over here we just check if it's one of the selected options then the only thing we have left to do over here is to actually set the text value so we have an empty drop down and then inside our options over here all we have to say is ratio dot text close that up it's save and now we have a drop down that has values inside it then we're going to go ahead and implement the on a change or the select over here and create a new function called on aspect change and that on aspect change will define above so we'll just copy that name over there and then up over here we'll do const on aspect change is equal to we're going to get an event argument then from that we're going to grab the value and we're going to say the value is equal to e target dot value then we'll do const ratio and we're going to find within the aspect ratios using this value that will get back we're going to look through this list over here to find which one it is we'll do aspect ratios and we're going to use a method called find that takes in an arrow function we're going to give it the ratio we're going to say ratio.value is equal to the value now this value over here is a string so i'm just going to do truthy lookup where it just checks one is a string one is a number but they're still equal then what's going to happen is we'll do a set aspect and we're going to give it the ratio now down in our cropper we haven't actually used the ratio yet so all we have to do over here is grab our aspect and then we're gonna grab the aspect that's stored in the state we're gonna grab the number and then store that there now when this value changes it's going to change the aspect that we're looking at so this is 16 by nine which fits perfectly we go half you can see it you get this smaller box like this that we can zoom around on and then four by three obviously is this format over here and you can see our zoom is maintained even though we change the aspect next we're gonna go ahead and add the buttons to the bottom of the screen so that will be pretty simple we're gonna find our controls area over here minimize the controls upper area and we're gonna add a new section beside it called buttons we'll give that a class name equal to button area we'll save that and then inside there we're just going to add three buttons we're going to add the cancel the reset and the crop button and then you can see those buttons appearing down here let's go ahead and style those buttons so we'll go to our app css and then inside our app css we'll just add a couple of styles we're going to add one for the button itself and we'll add one for the button area the button area style that we're going to add is just to align the buttons center on the screen so now you can see the buttons are centered and then the button itself will make the buttons look nicer and add some spacing we'll just do a margin left of 10 pixels and then we'll do the same thing with the right as well and then we'll also add we can add a background color if we like and make the background color black now they kind of disappear and then we can add a color and make that white and if we wanted to play around a little bit more with it we could add a border with one pixel make that's solid and yellow then our buttons have these nice little yellow outline to them we could even go ahead and make those buttons a little bit bigger so our font size for the buttons we can set that to 20 pixels and then just to make some spacing between those two different areas we could say in our button area the margin top is 10 pixels and then we get a bit of a gap or maybe go with 20 right there we have a bigger gap between them now our buttons are larger a little easier to read now let's go ahead and start adding some functionality to our buttons let's implement the cancel so for that button we're going to put add an on click and then we're going to fire a method called on cancel and on cancel is going to come from the parent component to the app we're going to pass that in as a property over there so right over here in the destructuring we're getting the on cancel and then inside apogee s inside the image crop dialog we go ahead and pass on cancel is equal to on cancel and then we'll go ahead and implement on cancel and then on cancel is equal to just an arrow function that doesn't take any arguments and all we have to do is call selected car and pass in null now when we click cancel it'll dismiss the dialog next let's take a look at how we're going to be cropping the actual image when we click the crop button so first thing that we're going to do is go back to our image crop dialog we're going to want to track the cropped pixels so this is going to be this area over here it's going to return an object that represents which part of the screen or which part of the image that we're going to be cropping in order to do this the cropper over here has an event that a fire is called on crop complete and the on crop complete we're just going to create a function we'll define that function above over here we're going to call it const on crop complete and that will just be another arrow function that we define and it takes in two values one is the cropped area so we're going to pass in the cropped area and then the one that we're interested in is the cropped area pixels and then we're just going to use our state because remember we're tracking state for that so we're just going to use our method over here so called set cropped area pixels and pass in the cropped area pixels that we have next let's go ahead and set up our click event for the crop so say on click equals on crop we'll go ahead and implement that above and it doesn't take any arguments in okay so to get the actual image the actual cropped image and to get that on the client side we're going to actually create a brand new file over here and we're going to call that cropimage.js and we're going to pass into it basically this code over here that i pasted in so i'm going to have a direct link to it inside of the description it's a little bit more complicated but it's not too bad basically what it's doing is we're using html5 canvas drawing the image to it and then cropping those using that cropped area pixel to figure out what that image is to save time we'll just paste this in over here and you can copy that code from the direct link or from the project that will be on github back inside our image crop dialog at the very top of our file we're going to go ahead and import from that file so we're importing the get cropped image now we can scroll down to the on crop and make use of that method and we're going to do is we're going to go ahead and call that method and get the return value which is going to be a cropped image url now that method uses async and a weight so we're going to have to call a wait over here and then call get cropped image get cropped image takes in the original image url and takes in the cropped area pixels from our state now since this is a weight method over here our method needs to be marked with async once we've got our cropped image url over here we're going to want to notify the app.js to update the state so the way we're going to do that is the app.js is going to be passing in a property a method that we're going to be utilizing so over here inside our destructuring we'll go ahead and add a new method that we're going to destructure that new method will be set cropped image 4 and then we're going to kind of define it here we'll do it kind of backwards so we're going to go down over here onto our on crop we're going to come here and we call set cropped image four and that method will take in the identifier of the image that we modified it'll take in the crop the zoom the aspect and the cropped image url now we could just give it the cropped image url but the next time i open up the picture i want to have the correct aspect the zoom the crop that we can modify that crop if we choose to so now i'm going to go ahead and copy the name of that method that we're going to be defining in our app.js we'll go back to our app.js and remember the image crop dialog over here we're going to be passing in that method then up above we can define that new function that we have here now this arrow function will be taking in a bunch of properties it will have our id our crop our zoom our aspect and the cropped image url then what we're going to do is we're going to take our cars list and make a copy of it so we'll say new cars list is equal to and we're going to give it the cars over there so we're making a copy of that list then next we can go ahead and get that car index we want to find out where that car is in the list we'll say cars.find index and that takes in an arrow function and we'll look for that particular car using its identifier that we pass in over here then once we find it we need to find the actual car so we can use that cars list that we have and go and find it by the index that we just found here so this will give us the object that we have then what we can do is we can define a new car and what we're going to do is make a copy of the car that we have right over here because remember in react state you're not supposed to mutate it so here we're making a copy of the car then we're going to modify the cropped image url the crop the zoom and the aspect so we're basically saying grab all the properties that are on the car and then update them to these values for the ones that defined then inside our new oh i'll need to put in equals over there then our new car list our new cars list what we're going to do is find the one that's in that list the car by car index and then go ahead and set that to the car then all we have to do is call set cars give it to that new cars list and lastly set selected car we're going to set that to null so that once you crop the dialog goes away now this seems this may look really complicated and all of this is just to make sure that you're not mutating the state and if it's something you haven't seen before it's a pattern you'll get used to now when we open up an image over here and we zoom in and we click that crop button it doesn't show the cropped image just yet however if i open it up again it remembers exactly where i was so i'm on the head on the back of the car there and then when i click it it still opens up on the back of the car so how do we get this working well really simple inside our app.js over here we have our src we have two values on our r we have the cropped image url so if it is there we're going to show it so we'll do this and then if it's not there then we're just going to show the regular image url click save and now you can see it's showing the cropped images let's go click this one choose something different drop it and there we go we see that it's working we did the same thing with this one too just to double check and yes they're all working now let's go implement reset image we'll define a function called reset image it'll be a function that just takes in a single identifier and all we need to do is call set cropped image give it the id and the other properties will be set to null by default since we're not providing them inside our image crop dialog we'll pass in reset image inside the component we'll go ahead and extract that property then below on the click event for reset we're going to define the as a new function called on reset image and we'll just define on reset image above over here inside on reset image we're just going to call reset image and we're just going to give it the identifier then if we go to one of our images over here open it up click the reset button you'll see that it gets reset if i change that aspect ratio to half zoom all the way to the side over here and then zoom in what you're going to notice is that when i crop it we're going to get that picture but when i click reset our zoom is reset our aspect ratio is reset and the position of this dropping is also reset if you enjoyed this tutorial please subscribe like and share [Music] [Music] you
Info
Channel: Coding With Adam
Views: 16,200
Rating: undefined out of 5
Keywords: react, react image cropping, react easy crop, crop easy react, crop images with react, how to crop images, easy way to crop images, cropping with react, image crop, crop image, crop images javascript, javascript react crop images, cropping images, crop image react, react crop images tutorial, react tutorial
Id: E_AHkWHhUz4
Channel Id: undefined
Length: 38min 21sec (2301 seconds)
Published: Mon Aug 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.