This episode is for members only

Sign up to access "Crop and Upload Profile Photos with Livewire" right now.

Get started
Already a member? Sign in to continue
Playing
05. Setting up Cropper.js

Transcript

00:00
Now that we have our modal open with our image,
00:02
we want to initialize some sort of cropping library that we can use to crop our image. And for this, we're going to go ahead and use cropper.js. It's probably the best option at the moment to do this
00:11
and get the feedback that we need, like the region that's been cropped. So we can pass that through to our back end, crop it, and store it.
00:20
OK, so let's go ahead and get cropper installed. Let's go over to our code and just pull this in with npm. So let's do an npm install on cropper.js and just wait for that to finish.
00:32
And now that's done, let's come over to our app.js file and we'll go ahead and pull this in. So let's import cropper from cropper.js. Let's go and import the CSS for this as well
00:43
so we actually get the styling. This can go directly into our JavaScript file and be built up. So this is in cropper.js source,
00:51
and then of course, CSS, and it is cropper.js.css, and we are done. Now, the next thing we want to do is go ahead and add this to our window object
01:00
so we can access it really easily, and that is pretty much it. We now have cropper on the page ready to go. Now, it looks like there's an error here,
01:08
so let's just have a look at what we've got. And I think it's just cropper.css. Yeah, there we go, great. So cropper's on the page.
01:15
Let's go and actually initialize this within our modal component. Now, for this, we're going to go ahead and use alpine.js, which is already bundled in with Livewire.
01:24
So we're going to go ahead and initialize this component with xdata, and we're going to store an instance of that cropper inside of xdata, but when we initialize this component,
01:35
we're going to go ahead and set it up. So let's go ahead and set cropper here to a new cropper instance, and we need to figure out where this image actually lives now.
01:45
So this is going to be the element that we want to target and crop. At the moment, we just have an image in here, which is absolutely fine.
01:51
I'm going to go ahead and wrap this in a div. I think that's required for cropper.js, and in here, we're going to set this to a ref and give it a name.
01:59
So let's just call this image. What that means is that up here, when we initialize this to target the element, we can just say refs and image.
02:07
That will go ahead and target this, and it will turn that into a cropper instance. Great. The next thing we want to do is pass in a bunch of options.
02:14
So we're going to set the autocrop area to one. You can check the documentation for these. We're going to set the view mode to one, just all pretty standard config,
02:24
and we're going to set the aspect ratio here to one, one, just so it's a nice square, but of course, feel free to play around with these and check the documentation out.
02:35
Okay, let's go ahead and run this and see what happens. So let's go and bring up our consult just in case we have any issues, and we're going to go ahead and choose that photo,
02:44
launch that modal, and let's just try that one more time because we've got a refresh, and okay, great. So unexpected, yeah, let's just have a look here, and yeah, I've put this in an object,
02:54
and that doesn't need to be. It's just a initialization script. Let's try that again, and there we go. So we have our cropper up and running,
03:03
but it looks a little bit strange at the moment. Now, the way that cropper.js works is it takes the size to determine where this needs to actually insert it. Now, the problem we've got at the moment
03:14
is that our modal is opening, and we're initializing this immediately, and that means that the sizing is a little bit off. So to counteract this, what we're going to do
03:23
is use next tick within Alpine to wait for the next render, and then go ahead and initialize our cropper. So let's go down here and put all of this inside of next tick and just wait for everything to be rendered
03:37
before we go ahead and initialize this, and then cropper will know which space it needs to contain. While we're here, we'll also go ahead and set the width of the image to full
03:46
to make sure it pulls the entire width, and we'll set a max width of full as well. Okay, let's go over and just try this again. So let's choose a photo, and there we go.
03:57
That looks a lot better. So just go ahead and close off our console, and you can see that we can just about, we'll change the padding in a minute,
04:03
just about go ahead and grab that and start to crop this, brilliant. Okay, so let's go ahead and just finish up by styling out the outer container of this
04:11
just to make it fit a little bit better, and for this, I think I'll just put a padding of 10 in there. It doesn't really matter what we do. Okay, let's go ahead and choose another photo here,
04:19
and yeah, there we go. We've got a little bit of padding, and now it's super easy to crop. So that's cropper.js installed,
04:26
getting around a couple of the render issues with Nextick. Now what we can do is listen to the crop event to determine what size we need to pass back to our profile photo field.

Episode summary

In this episode, we get Cropper.js hooked up to our image upload modal so we can start cropping photos right in the browser. We start by installing Cropper.js via npm and importing both the JS and CSS into our project, making sure it's loaded properly. There's a small hiccup with the CSS import, but it's quickly sorted out.

Next, we dive into integrating Cropper.js with our modal using Alpine.js (which is already available via Livewire). We set up Alpine's x-data to store our cropper instance and grab the image element with a ref. Then, we initialize the cropper with some default options—auto crop area, view mode, and a 1:1 square aspect ratio—so it looks nice and clean.

We run into a sneaky issue where the cropper doesn't size correctly because it's being initialized before the modal fully renders. No worries—we fix this by wrapping the initialization in Alpine's $nextTick to make sure everything's rendered before Cropper takes over.

With a quick tweak to image sizing for full width and some padding on the container, we end up with a modal where you can choose and crop images smoothly. Now we're all set up to listen for crop events and get the cropped region's data for the next step. If you want to tweak the cropping experience, feel free to play around with those Cropper.js options!

Episode discussion

No comments, yet. Be the first!