Hey friends, today in this blog, you’ll learn to create a new project named Build An Basic Image Editor in HTML CSS & JavaScript. Previously, I shared a blog on how to Build A Word Guessing Game in JavaScript that is similar to hangman.
In this project (Image Editor in JavaScript), as you’ve seen in the preview image, users can apply different filters to their image like grayscale, inversion, saturation, and adjust the image brightness. Additionally, users can also rotate or flip the images and save their edited images.
This project is made with vanilla JavaScript. If you’re excited to view a demo of this image editor or want to know what this editor looks like. You can watch the given YouTube video or click here to view a live demo of this basic image editor.
Video Tutorial of Basic Image Editor in JavaScript
In the above video, you’ve seen the demo of this Image Editor and how I built it with HTML CSS & Vanilla JavaScript. If you’re too beginner in JavaScript and didn’t build projects before, then this image editor code could be difficult to understand.
So, I want to suggest you build some JavaScript projects before continuing to create this image editor. But, if you’re familiar with JavaScript, the codes and logic of this project shouldn’t be difficult to understand for you.
Canvas part of the codes could be difficult to understand for you and canvas is used only to save the edited image. So, please watch the above video multiple times to understand the codes because I tried my best to explain the main JavaScript lines with written comments.
If you liked this image editor and want to get source codes and files, you can easily get them from the bottom of this page.
You might like this:
- QR Code Generator in JavaScript
- Simple Alarm Clock in JavaScript
- Typing Speed Test Game in JavaScript
- Create A Todo List App with Localhost
Basic Image Editor in JavaScript [Source Codes]
To build an Image Editor using HTML CSS & JavaScript, you need to create three files: HTML, CSS & JavaScript file. Once you create these files, just paste the given codes into your file. If you don’t know how to create these files, where to paste the codes, or don’t want to do these, you can simply download the source code files of this Image Editor by clicking on the given download button that is at the bottom of this page.
First, create an HTML file with the name index.html and paste the given codes into your HTML file. Remember, you’ve to create a file with a .html extension.
<!DOCTYPE html> <!-- Coding By CodingNepal - youtube.com/codingnepal --> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Image Editor in JavaScript | CodingNepal</title> <link rel="stylesheet" href="style.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://unpkg.com/[email protected]/css/boxicons.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"/> </head> <body> <div class="container disable"> <h2>Easy Image Editor</h2> <div class="wrapper"> <div class="editor-panel"> <div class="filter"> <label class="title">Filters</label> <div class="options"> <button id="brightness" class="active">Brightness</button> <button id="saturation">Saturation</button> <button id="inversion">Inversion</button> <button id="grayscale">Grayscale</button> </div> <div class="slider"> <div class="filter-info"> <p class="name">Brighteness</p> <p class="value">100%</p> </div> <input type="range" value="100" min="0" max="200"> </div> </div> <div class="rotate"> <label class="title">Rotate & Flip</label> <div class="options"> <button id="left"><i class="fa-solid fa-rotate-left"></i></button> <button id="right"><i class="fa-solid fa-rotate-right"></i></button> <button id="horizontal"><i class='bx bx-reflect-vertical'></i></button> <button id="vertical"><i class='bx bx-reflect-horizontal' ></i></button> </div> </div> </div> <div class="preview-img"> <img src="image-placeholder.svg" alt="preview-img"> </div> </div> <div class="controls"> <button class="reset-filter">Reset Filters</button> <div class="row"> <input type="file" class="file-input" accept="image/*" hidden> <button class="choose-img">Choose Image</button> <button class="save-img">Save Image</button> </div> </div> </div> <script src="script.js"></script> </body> </html>
Second, create a CSS file with the name style.css and paste the given codes into your CSS file. Remember, you’ve to create a file with a .css extension.
/* Import Google font - Poppins */ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap'); *{ margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } body{ display: flex; padding: 10px; min-height: 100vh; align-items: center; justify-content: center; background: #E3F2FD; } .container{ width: 850px; padding: 30px 35px 35px; background: #fff; border-radius: 10px; box-shadow: 0 10px 20px rgba(0,0,0,0.1); } .container.disable .editor-panel, .container.disable .controls .reset-filter, .container.disable .controls .save-img{ opacity: 0.5; pointer-events: none; } .container h2{ margin-top: -8px; font-size: 22px; font-weight: 500; } .container .wrapper{ display: flex; margin: 20px 0; min-height: 335px; } .wrapper .editor-panel{ padding: 15px 20px; width: 280px; border-radius: 5px; border: 1px solid #ccc; } .editor-panel .title{ display: block; font-size: 16px; margin-bottom: 12px; } .editor-panel .options, .controls{ display: flex; flex-wrap: wrap; justify-content: space-between; } .editor-panel button{ outline: none; height: 40px; font-size: 14px; color: #6C757D; background: #fff; border-radius: 3px; margin-bottom: 8px; border: 1px solid #aaa; } .editor-panel .filter button{ width: calc(100% / 2 - 4px); } .editor-panel button:hover{ background: #f5f5f5; } .filter button.active{ color: #fff; border-color: #5372F0; background: #5372F0; } .filter .slider{ margin-top: 12px; } .filter .slider .filter-info{ display: flex; color: #464646; font-size: 14px; justify-content: space-between; } .filter .slider input{ width: 100%; height: 5px; accent-color: #5372F0; } .editor-panel .rotate{ margin-top: 17px; } .editor-panel .rotate button{ display: flex; align-items: center; justify-content: center; width: calc(100% / 4 - 3px); } .rotate .options button:nth-child(3), .rotate .options button:nth-child(4){ font-size: 18px; } .rotate .options button:active{ color: #fff; background: #5372F0; border-color: #5372F0; } .wrapper .preview-img{ flex-grow: 1; display: flex; overflow: hidden; margin-left: 20px; border-radius: 5px; align-items: center; justify-content: center; } .preview-img img{ max-width: 490px; max-height: 335px; width: 100%; height: 100%; object-fit: contain; } .controls button{ padding: 11px 20px; font-size: 14px; border-radius: 3px; outline: none; color: #fff; cursor: pointer; background: none; transition: all 0.3s ease; text-transform: uppercase; } .controls .reset-filter{ color: #6C757D; border: 1px solid #6C757D; } .controls .reset-filter:hover{ color: #fff; background: #6C757D; } .controls .choose-img{ background: #6C757D; border: 1px solid #6C757D; } .controls .save-img{ margin-left: 5px; background: #5372F0; border: 1px solid #5372F0; } @media screen and (max-width: 760px) { .container{ padding: 25px; } .container .wrapper{ flex-wrap: wrap-reverse; } .wrapper .editor-panel{ width: 100%; } .wrapper .preview-img{ width: 100%; margin: 0 0 15px; } } @media screen and (max-width: 500px) { .controls button{ width: 100%; margin-bottom: 10px; } .controls .row{ width: 100%; } .controls .row .save-img{ margin-left: 0px; } }
Last, create a JavaScript file with the name script.js and paste the given codes into your JavaScript file. Remember, you’ve to create a file with a .js extension.
const fileInput = document.querySelector(".file-input"), filterOptions = document.querySelectorAll(".filter button"), filterName = document.querySelector(".filter-info .name"), filterValue = document.querySelector(".filter-info .value"), filterSlider = document.querySelector(".slider input"), rotateOptions = document.querySelectorAll(".rotate button"), previewImg = document.querySelector(".preview-img img"), resetFilterBtn = document.querySelector(".reset-filter"), chooseImgBtn = document.querySelector(".choose-img"), saveImgBtn = document.querySelector(".save-img"); // Initial filter values and transformations let brightness = "100", saturation = "100", inversion = "0", grayscale = "0"; let rotate = 0, flipHorizontal = 1, flipVertical = 1; // Load image from file input and display in preview const loadImage = () => { let file = fileInput.files[0]; if (!file) return; previewImg.src = URL.createObjectURL(file); previewImg.addEventListener("load", () => { resetFilterBtn.click(); document.querySelector(".container").classList.remove("disable"); }); } // Apply current filter settings and transformations to preview image const applyFilter = () => { previewImg.style.transform = `rotate(${rotate}deg) scale(${flipHorizontal}, ${flipVertical})`; previewImg.style.filter = `brightness(${brightness}%) saturate(${saturation}%) invert(${inversion}%) grayscale(${grayscale}%)`; } // Set up filter options event listeners filterOptions.forEach(option => { option.addEventListener("click", () => { document.querySelector(".active").classList.remove("active"); option.classList.add("active"); filterName.innerText = option.innerText; // Set slider max value and current value based on selected filter if (option.id === "brightness") { filterSlider.max = "200"; filterSlider.value = brightness; filterValue.innerText = `${brightness}%`; } else if (option.id === "saturation") { filterSlider.max = "200"; filterSlider.value = saturation; filterValue.innerText = `${saturation}%` } else if (option.id === "inversion") { filterSlider.max = "100"; filterSlider.value = inversion; filterValue.innerText = `${inversion}%`; } else { filterSlider.max = "100"; filterSlider.value = grayscale; filterValue.innerText = `${grayscale}%`; } }); }); // Update filter values and apply changes when slider input changes const updateFilter = () => { filterValue.innerText = `${filterSlider.value}%`; const selectedFilter = document.querySelector(".filter .active"); // Update the relevant filter value based on the selected filter if (selectedFilter.id === "brightness") { brightness = filterSlider.value; } else if (selectedFilter.id === "saturation") { saturation = filterSlider.value; } else if (selectedFilter.id === "inversion") { inversion = filterSlider.value; } else { grayscale = filterSlider.value; } applyFilter(); // Apply updated filter settings } // Set up rotation and flip options event listeners rotateOptions.forEach(option => { option.addEventListener("click", () => { if (option.id === "left") { rotate -= 90; } else if (option.id === "right") { rotate += 90; } else if (option.id === "horizontal") { flipHorizontal = flipHorizontal === 1 ? -1 : 1; } else { flipVertical = flipVertical === 1 ? -1 : 1; } applyFilter(); // Apply updated transformations }); }); // Reset all filters and transformations to default values const resetFilter = () => { brightness = "100"; saturation = "100"; inversion = "0"; grayscale = "0"; rotate = 0; flipHorizontal = 1; flipVertical = 1; filterOptions[0].click(); applyFilter(); // Apply default settings } // Save the current image with applied filters and transformations const saveImage = () => { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); // Set canvas dimensions to match the image canvas.width = previewImg.naturalWidth; canvas.height = previewImg.naturalHeight; // Apply current filter settings ctx.filter = `brightness(${brightness}%) saturate(${saturation}%) invert(${inversion}%) grayscale(${grayscale}%)`; // Center the canvas context ctx.translate(canvas.width / 2, canvas.height / 2); // Apply rotation if needed if (rotate !== 0) { ctx.rotate(rotate * Math.PI / 180); } // Apply scaling for flips ctx.scale(flipHorizontal, flipVertical); // Draw the image centered on the canvas ctx.drawImage(previewImg, -canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height); // Create a download link and trigger the download const link = document.createElement("a"); link.download = "image.jpg"; link.href = canvas.toDataURL(); link.click(); } // Set up event listeners for UI controls filterSlider.addEventListener("input", updateFilter); resetFilterBtn.addEventListener("click", resetFilter); saveImgBtn.addEventListener("click", saveImage); fileInput.addEventListener("change", loadImage); chooseImgBtn.addEventListener("click", () => fileInput.click());
That’s all, now you’ve successfully built a Basic Image Editor in HTML CSS & JavaScript. If your code doesn’t work or you’ve faced any problems, please download the source code files from the given download button. It is free and a zip file will be downloaded that contains a project folder with source code files.
good approach
Good content.
Saving of a rotated image does not change the dimensions. I tried to rotate by 90 degree a horizontal picture with the dimensions 1920 x 1174. The resulting picture has been saved with the same dimensions, but it was vertical with empty spaces to the right and to the left.
Who’s having the same issue as mine? Choose Image button doesn’t work
hello sir can you edit this script and give a add text in any image
jus filters not working in safari.
Everything works in chrome. help. Thank You
Thanks bro
nice
Please coding Nepal post a new video on how to add changing of background in the image editor’s filter. Please am new here
I hope you make a php mysql of comments with likes in hearts or emojis.
Thanks for this use full information
You’re welcome 🙂