Wouldn’t it be nice if we could optimise images before they’re sent to the server. This can save bandwidth, result in a cleaner database, and allows the user to have more control over their own content. Use the techniques described in this article to enable your users to edit profile pictures, photo albums, or any other imagery that they upload to your server.

We’ll set up a basic DropzoneJS vanilla JavaScript drop area, extend it to better integrate with a third party image cropper and then show how to link it up with three popular image croppers: Cropper.js, Croppie, and last but not least Doka

Let’s start by setting up DropzoneJS first.

Setting up DropzoneJS

We’ll create a basic HTML page and add the DropzoneJS styles and scripts like shown below.

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>JavaScript Image Cropping with DropzoneJS</title>

<link href="https://unpkg.com/dropzone/dist/dropzone.css" rel="stylesheet"/>

</head>

<body>

<div class="dropzone" id="myDropzone"></div>

<script src="https://unpkg.com/dropzone"></script>

</body>

</html>

With our basic page set up, we can now focus on configuring DropzoneJS. Before it’s going to do anything it wants us to set up a location for uploading the files to, let’s do that now. We can pass options to our specific uploader using the id we assigned to the DropzoneJS <div> .

Note that we’ve zoomed in on the code just before the closing body tag.

<div class="dropzone" id="myDropzone"></div>

<script src="https://unpkg.com/dropzone"></script> <script>

Dropzone.options.myDropzone = {

url: '/post'

};

</script>

We should now see the following appear on the page, and if we drop an image DropzoneJS will show a small thumbnail.

We can handle the file object on the server just as we would a normal file posted using a <input type=”file”/> with a classic multi-part form. This tutorial will focus on editing the image on the front-end before it’s uploaded to the server. So we’ll leave the server solution be for now.

Extending Dropzone it with an image editor popup

Dropzone has a special callback function called transformFile we can ask our users to edit a file when this function is called. Let’s

Note that we’ve zoomed in on the code inside the <script> tag.

Dropzone.options.myDropzone = {

url: '/post',

transformFile: function(file, done) { }

};

Dropzone locks up. We need to call the done function (second parameter) when we’re done editing the file, we’ll keep this in mind. For now this is fine.

Alright, we want to edit the file in an image editor overlay, on top of Dropzone, this automatically moves the user focus to the editor.

transformFile: function(file, done) { // Create the image editor overlay

var editor = document.createElement('div');

editor.style.position = 'fixed';

editor.style.left = 0;

editor.style.right = 0;

editor.style.top = 0;

editor.style.bottom = 0;

editor.style.zIndex = 9999;

editor.style.backgroundColor = '#000';

document.body.appendChild(editor); }

The result below seems all kinds of wrong but it’s actually what we want. The black layer will be the location of our editor later on. Hang in there.

We need a way to escape from this black void, so let’s add a button with a click event to the editor element.

transformFile: function(file, done) { // Create the image editor overlay

var editor = document.createElement('div');

editor.style.position = 'fixed';

editor.style.left = 0;

editor.style.right = 0;

editor.style.top = 0;

editor.style.bottom = 0;

editor.style.zIndex = 9999;

editor.style.backgroundColor = '#000';

document.body.appendChild(editor); // Create confirm button at the top left of the viewport

var buttonConfirm = document.createElement('button');

buttonConfirm.style.position = 'absolute';

buttonConfirm.style.left = '10px';

buttonConfirm.style.top = '10px';

buttonConfirm.style.zIndex = 9999;

buttonConfirm.textContent = 'Confirm';

editor.appendChild(buttonConfirm);

buttonConfirm.addEventListener('click', function() { // Remove the editor from the view

document.body.removeChild(editor); }); }

Yay! We can now escape the void. Wonderful!

The is all we need to set up to integrate with our first and second image cropper candidates, let’s give Cropper.js a go.