Build An Image Editor tool in HTML CSS & JavaScript [Free Source Code] in 2023

Bijan
6 min readAug 4, 2023

--

Today In this article, I’ll show you how to create an Photo Editor Tool Using HTML, CSS JavaScript. This type of photo Editor Website is used on websites For Photos Editing , You can Edit your image after create this tool easily.

What is photo Editor tools?

A photo editor tool is a software application or online service that allows users to modify and enhance their photos by applying various filters, adjusting colors, cropping, and other modifications. Photo editor tools can be simple and basic, with just a few editing options, or they can be more advanced and feature-rich, with a wide range of options for modifying and enhancing photos. Photo editor tools can be used for personal or professional purposes, and are commonly used to improve the appearance of photos, create special effects, or prepare photos for printing or sharing online.

A style.css editor tool allows users to modify and enhance their photos by applying various filters, adjusting colors, cropping, and other modifications. In this tutorial, we will learn how to build a simple photo editor tool using HTML, CSS, and JavaScript.

Build An Photo Editor tool in HTML CSS JavaScript [Source Code]

I have provided all the source code of this Photo Editor Tool and the images that i have used in this project. .

To create this photo editor tool you need to create three files Html Css and JavaScript file. After create these files just copied and pasted the following source code.

Source code of Photo Editor Tool HTML

First, we need to set up the basic structure of our HTML page. Create a new file and name it “index.html”. Add the following code to the file:

We also have a div element with an ID of “controls” that contains four buttons for applying various filters to the image. Each button has an ID corresponding to the filter it will apply.

<!DOCTYPE html>
<html>
<head>
<title> Image Editor From Scratch - Codewithzan</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="src/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://unpkg.com/boxicons@2.1.2/dist/boxicons.js"></script>

</head>
<body>

<div class="container disable">
<div class="wrapper">
<div class="editor-panel">
<div class="filter">
<label for="">Filters</label>
<div class="options">
<button id="brightness" class="active">Brightness</button>
<button id="contrast">Contrast</button>
<button id="blurs" >Blur</button>
<button id="grayscale">Grayscale</button>
<button id="saturate">Saturate</button>
<button id="opacity">Opacity</button>
</div>
<div class="slider">
<div class="filter-info">
<p class="name">Brightness</p>
<p class="value">100%</p>
</div>
<input type="range" min="0" max="200" value="100">
</div>
</div>
<div class="rotate">
<label for="">Rotate</label>
<div class="options">
<button id="left"><i class="fa fa-undo" aria-hidden="true"></i> </button>
<button id="right"><i class="fa fa-repeat " aria-hidden="true"></i> </button>
<button id="vertical"> <box-icon name='reflect-vertical'></box-icon> </button>
<button id="horizontal"> <box-icon name='reflect-horizontal'></box-icon> </button>


</div>
</div>
</div>
<div class="preview-image">
<img src="src/img/placeholder.png" alt="">
</div>
</div>
<div class="controls">
<button class="reset-image"><box-icon name='reset'></box-icon> Reset Image</button>
<div class="row">
<input type="file" class="inp-file" accept="image/*">
<button class="choose-image"><box-icon name='image-add'></box-icon> Choose Image</button>
<button class="save-image"><box-icon name='save'></box-icon> Save Image</button>
</div>
</div>
</div>



<script src="src/js/script.js"></script>
</body>
</html>

Source code of Photo Editor Tool CSS

Next, we need to style the page using CSS. Add the following code to a new file named “style.css” and link it to your HTML file by adding a link element in the head of your HTML file:

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500&display=swap');


*{
font-family: 'Poppins', sans-serif;

padding:0;
margin:0;
box-sizing: border-box;
overflow: hidden;
}


body{
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #E0DEFF;
}



.container.disable :where(.editor-panel, .save-image, .reset-image){
opacity: 0.2;
}


.container{
width: 800px;
background-color: #F3F4FC;
padding: 30px;
box-shadow: 1px 1px 10px #00000052;
}


.editor-panel{
border: 1px solid rgba(0,0,0,0.1);
padding: 15px;
}


.editor-panel .rotate{
margin-top: 15p;
}

.editor-panel .filter{

}

label{
margin-bottom: 5px;
display: block;
opacity: 0.4;
}

.filter-info{
display: flex;
justify-content: space-between;
margin-top: 12px;
}

.slider input{
margin-top: 5px;
width: 100%;
accent-color: #ed7575;
}

.editor-panel .filter .options{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

.editor-panel .filter .options button{
width: calc(100% / 2 - 3px);
padding: 8px;
margin-top: 6px;
border-color: rgba(0,0,0,0.2);
}


.editor-panel .filter .options button{
background-color: white;
cursor: pointer;
}


.rotate .options{
display: flex;
}

.rotate .options button{
cursor: pointer;
width: calc(100% / 2 - 3px);
padding: 8px;
margin-top: 6px;
border-color: rgba(0,0,0,0.2);
}



.editor-panel .filter .options button.active{
background-color: #ed7575;
border-color: #ed7575;
color: white;
border-color: rgba(0,0,0,0.2);
}


.editor-panel .slider{
margin-top: 15p;
}



.wrapper{
display: flex;
}

.controls{
display: flex;
justify-content: space-between;
margin-top: 15px;
}

.controls button{
border-color: rgba(0,0,0,0.2);
padding: 8px;
margin-top: 6px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: revert;
cursor: pointer;
}

.controls .row{
display: flex;
}


.save-image{
margin-left: 8px;
}


.preview-image{
display: flex;
align-items: center;
justify-content: center;

}


img{
width: 405px;
height: 350px;
object-fit: contain;
text-align: center;
}

.row input{
display: none;}

@media screen and (max-width: 760px) {
.container{
padding: 25px;
width: 90%;
}
.container .wrapper{
flex-wrap: wrap-reverse;
display: flex;
justify-content: center;
align-items: center;
}
.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;
}
}

This code styles the image container and image to be centered and sets a maximum width and height for the image. It also styles the controls div to be centered and adds some margin to the buttons.

Source code of Photo Editor Tool JavaScript

Now, we can add functionality to our photo editor using JavaScript. Add the following code to a new file named “script.js” and link it to your HTML file by adding a script element at the end of your HTML file:

inpFile  = document.querySelector('.inp-file')
chooseImage = document.querySelector('.choose-image')
previewImage = document.querySelector('.preview-image img')
container = document.querySelector('.container')
filterName = document.querySelector('.slider p.name')
inpRange = document.querySelector('input[type="range"]')
filterValue = document.querySelector('.slider p.value')
selectedFilter = document.querySelector('.filter .active')
rotateButtons = document.querySelectorAll('.rotate button')
resetImage = document.querySelector('.reset-image')
saveImage = document.querySelector('.save-image')




let brightness = 100
let contrast = 100
let blurs = 0
let grayscale = 0
let saturate = 100
let opacity = 100
let rotate = 0;
let vertical = 1
let horizontal = 1




saveImage.addEventListener('click',function(){
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = previewImage.naturalWidth;
canvas.height = previewImage.naturalHeight;

ctx.filter = `brightness(${brightness}%) contrast(${contrast}%) grayscale(${grayscale}%) saturate(${saturate}%) opacity(${opacity}%) blur(${blurs}px)`;

ctx.translate(canvas.width / 2, canvas.height / 2); in JavaScript
if(rotate !== 0) {
ctx.rotate(rotate * Math.PI / 180);
}
ctx.scale(vertical, horizontal);
ctx.drawImage(previewImage, -canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);

const link = document.createElement("a");
link.download = "image.jpg";
link.href = canvas.toDataURL();
link.click();

})




resetImage.addEventListener('click',function(){
console.log(resetImage)
brightness = 100,
contrast = 100,
blurs = 0,
grayscale = 0,
saturate = 100,
opacity = 100,
rotate = 0
vertical = 1,
horizontal = 1
filterOptions[0].click()
inpRange.value = brightness
filterValue.innerText = brightness + "%"
applyFilteronImg()

})



rotateButtons.forEach(function(option){
option.addEventListener('click',function(){
if(option.id=='left'){
rotate -= 90
}
else if(option.id=='right'){
rotate += 90
}
else if(option.id=='vertical'){
vertical = vertical == 1 ? -1 : 1
}
else if(option.id=='horizontal'){
horizontal = horizontal == 1 ? -1 : 1
}
applyFilteronImg()
})


})



function applyFilteronImg(){


previewImage.style.transform = `rotate(${rotate}deg) scale(${vertical},${horizontal})`
previewImage.style.filter = `brightness(${brightness}%) contrast(${contrast}%) grayscale(${grayscale}%) saturate(${saturate}%) opacity(${opacity}%) blur(${blurs}px)`;

}




filterOptions = document.querySelectorAll('.filter button')

filterOptions.forEach(function(option){
option.addEventListener('click',function(){
document.querySelector('.filter .active').classList.remove('active')
option.classList.add('active')
filterName.innerText = option.innerText
inpRange.max = 200;
if(option.id === 'Brightness'){
inpRange.value = brightness
filterValue.innerText = brightness + "%"
}
else if(option.id === 'contrast'){
inpRange.value = contrast
filterValue.innerText = contrast + "%"
}
else if(option.id === 'blurs'){
inpRange.max = 10;
inpRange.value = blurs
filterValue.innerText = blurs
}
else if(option.id === 'grayscale'){
inpRange.max = 100;
inpRange.value = grayscale
filterValue.innerText = grayscale + "%"
}
else if(option.id === 'saturate'){
inpRange.value = saturate
filterValue.innerText = saturate + "%"
}
else if(option.id === 'opacity'){
inpRange.max = 100;
inpRange.value = opacity
filterValue.innerText = opacity + "%"
}
})

})

function loadImg(){
file = inpFile.files[0]
if(file){
previewImage.src = URL.createObjectURL(file)
}
container.classList.remove('disable')
}



inpFile.addEventListener('change',loadImg)

chooseImage.addEventListener('click',function(){
inpFile.click()
})


inpRange.addEventListener('change',function(){
filterValue.innerText = inpRange.value + "%"
selectedFilter = document.querySelector('.filter .active')
if(selectedFilter.id == 'brightness'){
brightness = inpRange.value

}
else if(selectedFilter.id == 'contrast'){
contrast = inpRange.value
}
else if(selectedFilter.id == 'blurs'){
blurs = inpRange.value
}
else if(selectedFilter.id == 'grayscale'){
grayscale = inpRange.value
}
else if(selectedFilter.id == 'saturate'){
saturate = inpRange.value
}
else if(selectedFilter.id == 'opacity'){
opacity = (inpRange.value)
}

console.log(selectedFilter.id)
applyFilteronImg
})

If this code is not working or you want to download source code click here

--

--

Bijan

Hi I'm Bijan this is a valuable source of information on various aspects of web development such as HTML, CSS, and JavaScri