Introduction:
In this tutorial, we will walk through the process of building an image cropper to Crop and Download an image using HTML, CSS, and JavaScript. An image cropper allows users to select a specific portion of an image and crop it according to their desired dimensions. Throughout this tutorial, you will learn how to implement the necessary HTML structure, CSS styling, and JavaScript functionality to create a dynamic and user-friendly image cropper. This project is ideal for web developers looking to enhance their frontend skills and provide a practical image manipulation tool to their users.
Things You Will Learn:
- Setting up the HTML structure to handle image selection and display.
- Utilizing CSS to style the image cropper and create a visually appealing interface.
- Implementing JavaScript functionalities to interact with the selected image and enable cropping.
- Utilizing the FileReader API to read the content of the selected image.
- Understanding the Cropper.js library and how to use it for image cropping.
- Incorporating aspect ratio options for more precise image selection.
- Dynamically adjusting the crop box dimensions using user input.
- Displaying a preview of the cropped image before downloading it.
Video Tutorial:
To complement this written tutorial, you can find a detailed video walkthrough on my YouTube channel. The video provides a step-by-step demonstration of the entire process, making it easier to follow along and understand the implementation.
Project Folder Structure:
Before diving into the code, let’s set up the project folder structure:
- index.html
- style.css
- script.js
- cropper.min.js (Downloaded from https://github.com/fengyuanchen/cropperjs)
HTML:
The HTML file contains the necessary elements for the image cropper:
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Crop and Download Image</title> <!-- Google Fonts --> <link href="https://fonts.googleapis.com/css2?family=Rubik&display=swap" rel="stylesheet" /> <!-- Cropper --> <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css" /> <!-- Stylesheet --> <link rel="stylesheet" href="style.css" /> </head> <body> <div class="wrapper"> <div class="container"> <div class="image-container"> <img id="image" /> </div> <div class="preview-container"> <img id="preview-image" /> </div> </div> <input type="file" id="file" accept="image/*" /> <label for="file">Choose A Photo</label> <div class="options hide"> <input type="number" id="height-input" placeholder="Enter Height" max="780" /> <input type="number" id="width-input" placeholder="Enter Width" max="780" /> <button class="aspect-ratio-button">16:9</button> <button class="aspect-ratio-button">4:3</button> <button class="aspect-ratio-button">1:1</button> <button class="aspect-ratio-button">2:3</button> <button class="aspect-ratio-button">Free</button> </div> <div class="btns"> <button id="preview" class="hide">Preview</button> <a href="" id="download" class="hide">Download</a> </div> </div> <!-- Script --> <script src="script.js"></script> </body> </html>
Â
CSS:
The CSS file is responsible for styling the image cropper and creating an appealing user interface:
* { padding: 0; margin: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body { background-color: #025bee; } .wrapper { width: min(90%, 800px); position: absolute; transform: translateX(-50%); top: 1em; left: 50%; background-color: #ffffff; padding: 2em 3em; border-radius: 0.5em; } .container { display: grid; grid-template-columns: 1fr 1fr; gap: 1em; border-radius: 7px; } .container .image-container, .container .preview-container { width: 100%; } input[type="file"] { display: none; } label { display: block; position: relative; background-color: #025bee; color: #ffffff; font-size: 16px; text-align: center; width: 250px; padding: 16px 0; border-radius: 0.3em; margin: 16px auto; cursor: pointer; } img { display: block; /* Important for cropper js*/ max-width: 100%; } .image-container { width: 60%; margin: 0 auto; } .options { display: flex; justify-content: center; gap: 1em; } input[type="number"] { width: 100px; padding: 16px 5px; border-radius: 0.3em; border: 2px solid #000000; } button { padding: 1em; border-radius: 0.3em; border: 2px solid #025bee; background-color: #ffffff; color: #025bee; } .btns { display: flex; justify-content: center; gap: 1em; margin-top: 1em; } .btns button { font-size: 1em; } .btns a { border: 2px solid #025bee; background-color: #025bee; color: #ffffff; text-decoration: none; padding: 1em; font-size: 1em; border-radius: 0.3em; } .hide { display: none; }
Â
JS:
The JavaScript file contains the logic to handle image selection, cropping, and preview functionalities:
let fileInput = document.getElementById("file"); let image = document.getElementById("image"); let downloadButton = document.getElementById("download"); let aspectRatio = document.querySelectorAll(".aspect-ratio-button"); const previewButton = document.getElementById("preview"); const previewImage = document.getElementById("preview-image"); const options = document.querySelector(".options"); const widthInput = document.getElementById("width-input"); const heightInput = document.getElementById("height-input"); let cropper = ""; let fileName = ""; fileInput.onchange = () => { previewImage.src = ""; heightInput.value = 0; widthInput.value = 0; downloadButton.classList.add("hide"); //The FileReader object helps to read contents of file stored on the computer let reader = new FileReader(); //readAsDataURL reads the content of input file reader.readAsDataURL(fileInput.files[0]); reader.onload = () => { image.setAttribute("src", reader.result); if (cropper) { cropper.destroy(); } //Initialize cropper cropper = new Cropper(image); options.classList.remove("hide"); previewButton.classList.remove("hide"); }; fileName = fileInput.files[0].name.split(".")[0]; }; //Set aspect ration aspectRatio.forEach((element) => { element.addEventListener("click", () => { if (element.innerText == "Free") { cropper.setAspectRatio(NaN); } else { cropper.setAspectRatio(eval(element.innerText.replace(":", "/"))); } }); }); heightInput.addEventListener("input", () => { const { height } = cropper.getImageData(); if (parseInt(heightInput.value) > Math.round(height)) { heightInput.value = Math.round(height); } let newHeight = parseInt(heightInput.value); cropper.setCropBoxData({ height: newHeight }); }); widthInput.addEventListener("input", () => { const { width } = cropper.getImageData(); if (parseInt(widthInput.value) > Math.round(width)) { widthInput.value = Math.round(width); } let newWidth = parseInt(widthInput.value); cropper.setCropBoxData({ width: newWidth }); }); previewButton.addEventListener("click", (e) => { e.preventDefault(); downloadButton.classList.remove("hide"); let imgSrc = cropper.getCroppedCanvas({}).toDataURL(); //Set preview previewImage.src = imgSrc; downloadButton.download = `cropped_${fileName}.png`; downloadButton.setAttribute("href", imgSrc); }); window.onload = () => { download.classList.add("hide"); options.classList.add("hide"); previewButton.classList.add("hide"); };
Â
Conclusion:
Congratulations! You have successfully created an image cropper using HTML, CSS, and JavaScript. Throughout this tutorial, you have learned how to set up the project, handle image selection, and utilize the Cropper.js library for efficient image cropping. Additionally, you implemented aspect ratio options and enabled users to adjust the crop box dimensions for precise selection. The final result is a user-friendly image cropper that allows users to preview and download their cropped images. I hope you found this tutorial helpful and that it enhances your web development skills.