Image Editor With Effects and Filters Using HTML, CSS, and JavaScript

By Bytewebster - October 02, 2023



In this web development tutorial, we will teach you how to create an image editor using only HTML, CSS, and JavaScript. With this project, your JavaScript will become stronger, and we will tell you the complete process of making it in this tutorial.

Working

This JavaScript image editor has many features for editing images. Such features as saturation, grayscale, blur, contrast, sepia, invert, and many more are available. We have given two options for uploading images. The first option is that you can upload the image directly from your device, and the second option is to upload the image through an image link.

                     
                 

This JavaScript image editor is functional only with the help of JavaScript, but if you want, you can add some additional functionality to it. We have divided the code for this project into three parts to explain.

In the first part, we will explain to you how to create the structure of this image editor with the help of HTML. And in the second part, we will style this image editor with the help of CSS. Finally, after these two, we will come to the last part of this project, which is JavaScript.


HTML Structure


Let us first understand the HTML part of this image editor. But first of all, let us tell you that the code given below is just to explain to you; it is not the complete code. If you want the complete source code of this project, then simply go to the end of this project, and there you will get the option to download the source code. As soon as you click on it, your source code file will start downloading.

There are two div elements to represent the left and right sections of this image editor, where the left section contains our image, which we want to edit. and the right section contains various controls for image editing.

then after that, we set an image element with an empty onerror attribute and an initial src attribute. The uploaded image will be displayed using this image element. The input element of type file comes next. Users are able to choose and upload an image file.


<div class="left">
    <img id="img" src=""
      onerror="this.src=''" />
    <input class="upload" type="file" name="myImage" accept="image/*" onchange="readURL(this);" />
  </div>
  <div class="right">
    <i class="fa fa-camera" style="font-size:40px; color: white;"></i><br />
    <button class="btn btn" type="button" onclick="$('.upload').trigger( 'click' )"><i class='bx bx-upload'></i> Upload Image</button>
    <form class="url on" action="/action_page.php">
      <input class="inpt" type="text" id="fname" name="fname" placeholder="www.bytewebster.com/logo.png" />
      <button class="sub"> Submit</button>
    </form><br />
    <label class="switch">
      <input class="switch" type="checkbox" /><span class="slider round"></span>
    </label>
    <div class="skew">
      <label for="brt">Brightness:
        <div class="s" id="brt">100%</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range brt" id="range" type="range" min="0" max="4" value="1" step=".05" name="brt"
        oninput="pcnt(value, '#brt')" />
    </div>
    <div class="skew">
      <label for="cnt">Contrast:
        <div class="s" id="cnt">100%</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range cnt" id="range" type="range" min="0" max="4" value="1" step=".05" name="cnt"
        oninput="pcnt(value, '#cnt')" />
    </div>
    <div class="skew">
      <label for="gs">Grayscale:
        <div class="s" id="gs">0%</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range gs" id="range" type="range" min="0" max="1" value="0" step=".05" name="gs"
        oninput="pcnt(value, '#gs')" />
    </div>
    <div class="skew">
      <label for="inv">Invert:
        <div class="s" id="inv">0%</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range inv" id="range" type="range" min="0" max="1" value="0" step=".05" name="inv"
        oninput="pcnt(value, '#inv')" />
    </div>
    <div class="skew">
      <label for="opa">Opacity:
        <div class="s" id="opa">100%</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range opa" id="range" type="range" min="0" max="1" value="1" step=".05" name="opa"
        oninput="pcnt(value, '#opa')" />
    </div>
    <div class="skew">
      <label for="sat">Saturate:
        <div class="s" id="sat">0%</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range sat" id="range" type="range" min="0" max="4" value="1" step=".05" name="sat"
        oninput="pcnt(value, '#sat')" />
    </div>
    <div class="skew">
      <label for="sep">Sepia:
        <div class="s" id="sep">0%</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range sep" id="range" type="range" min="0" max="1" value="0" step=".05" name="sep"
        oninput="pcnt(value, '#sep')" />
    </div>
    <div class="skew">
      <label for="blr">Blur:
        <div class="s" id="blr">0px</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range blr" id="range" type="range" min="0" max="20" value="0" step="1" name="blr"
        oninput="blr(value)" />
    </div>
    <div class="skew">
      <label for="hr">Hue-Rotate:
        <div class="s" id="hr">0deg</div>
      </label>
    </div>
    <div class="sliders">
      <input class="range hr" id="range" type="range" min="0" max="360" value="0" step="1" name="hr"
        oninput="hr(value)" />
    </div>
  </div>

Next in the structure of this image editor is a form element with a class and an action attribute. It is for fetching the image from the image URL. We also set a placeholder attribute in the form input field, which provides a default placeholder text for the input field and suggests the format of the URL.

This image editor also includes several input elements of type range, which are used to create sliders for adjusting various image attributes like brightness, contrast, grayscale, invert, opacity, saturation, sepia, blur, and hue-rotate.


Styling With CSS


Now that the structure of this image editor is almost complete, the only thing left is its design. Which we will do with the help of CSS. So let us tell you how this image editor has been designed.

For background and layout, we style the body element, making it a flex container, which allows for easy layout control. After this, we have styled the structure of the left section. The left section takes up 80% of the width and centres its content both vertically and horizontally.

And then comes the turn to style the right-side section of this javascript image editor. It takes up 25% of the width and has a radial gradient background. The text is centered horizontally, and it allows for vertical scrolling if content overflows.


html, body {
  margin: 0;
  height: 100%;
  font-family: Arial, Helvetica, sans-serif;
  font-size: large;
}

body {
  display: flex;
  background: linear-gradient(#161a1d, #2b2d42);
  overflow: hidden;
}

.left {
  height: 100%;
  width: 80%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.left img {
  width: 60%;
}

.right {
  width: 25%;
  height: 100%;
  text-align: center;
  padding: 10px;
  background-image: radial-gradient( circle 311px at 8.6% 27.9%,  rgba(62,147,252,0.57) 12.9%, rgba(239,183,192,0.44) 91.2% );
  color: #fff;
  overflow-y: auto;
  z-index: 99;
}
.right .skew {
  text-align: left;
  text-indent: 15px;
}
.right .skew .s {
  transform: translateY(-15px);
  text-align: right;
}
.right .range {
  width: 90%;
  transform: translateY(-7.5px);
}
.right .fa {
  color: #667eea;
}
.right .switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
  margin-bottom: 10px;
}
.right .switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
.right .slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: black;
  -webkit-transition: 0.4s;
  transition: 0.4s;
}
.right .slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: 0.4s;
  transition: 0.4s;
}
.right input:checked + .slider {
  background: black;
}
.right input:focus + .slider {
  box-shadow: 0 0 1px #2196F3;
}
.right input:checked + .slider:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(26px);
}
.right .slider.round {
  border-radius: 34px;
}
.right .slider.round:before {
  border-radius: 50%;
}
.right .inpt {
  padding: 14px;
  border-radius: 8px;
}
.right .inpt:focus {
  outline: none;
}
.right .btn {
  margin-bottom: 12px;
}

.on {
  display: none;
}

.upload {
  display: none;
}

button {
  margin-top: 8px;
  background: black;
  border: none;
  color: #ffecd1;
  padding: 15px;
  font-size: 15px;
  border-radius: 10px;
  transition: 0.5s;
  font-weight: bold;
}
button:hover {
  transform: translateY(-2px);
  box-shadow: 0px 2px #0a001a;
  filter: brightness(1.3);
}

@media (max-width: 600px) {
  .left {
    width: 100%;
  }
  .left img {
    width: 100%;
  }
}

After this, we come to the styling of sliders and toggle switches. It includes styling for slider handles, switches, and their animations. Next, we use padding, border-radius, and focus styles to specify the styling for input items and buttons.

We have also styled some hidden elements in the CSS code of this image editor. The names of those classes are on and upload. These classes are used to hide elements with the class "on" and "upload.

And finally, we have used some media queries. Those media queries adjust the layout for screens with a maximum width of 600px, making the left section and its contained image occupy the full width of the viewport.


JavaScript Explanation


Now we have completed the two main parts. We hope that you have understood by now, but now comes the most major part, which is JavaScript. because JavaScript is only responsible for handling various interactions and functionalities in this image editor with effects and filters.

First of all, we created a function here in the javascript. which is the readURL (input) function.This function is called when a user selects an image using the file input element. It reads the selected image file and sets the src attribute of the image element to the data URL of the selected image.

Next, we created a function for the toggle switch. This function is triggered when a user clicks on an element with the class switch. With this feature, you can switch between showing a URL input box and a button for sending the URL.


function readURL(input) {
	if (input.files && input.files[0]) {
		var reader = new FileReader();
		reader.onload = function (e) {
			$("#img").attr("src", e.target.result);
		};
		reader.readAsDataURL(input.files[0]);
	}
}
$(".switch").click(function () {
	if ($(".url").hasClass("on")) {
		$(".url").removeClass("on");
		$(".btn").addClass("on");
	} else {
		$(".url").addClass("on");
		$(".btn").removeClass("on");
	}
});
$(".sub").click(function () {
	$("#img").attr("src", $(".inpt").val());
	return false;
});
function pcnt(x, name) {
	$(name).html(Math.round(x * 100) + "%");
}
function blr(x) {
	$("#blr").html(x + "px");
}
function hr(x) {
	$("#hr").html(x + "deg");
}
$(document).change(function (e) {
	let brt = $(".brt").val();
	let cnt = $(".cnt").val();
	let gs = $(".gs").val();
	let inv = $(".inv").val();
	let opa = $(".opa").val();
	let sat = $(".sat").val();
	let sep = $(".sep").val();
	let blr = $(".blr").val();
	let hr = $(".hr").val();
	$("img").css(
		"filter",
		"brightness(" +
			brt +
			") contrast(" +
			cnt +
			") grayscale(" +
			gs +
			") invert(" +
			inv +
			") opacity(" +
			opa +
			") saturate(" +
			sat +
			") sepia(" +
			sep +
			") blur(" +
			blr +
			"px) hue-rotate(" +
			hr +
			"deg)"
	);
});
function zoom(event) {
	event.preventDefault();
	scale += event.deltaY * -0.01;
	scale = Math.min(Math.max(0.125, scale), 2);
	$("#img").css("transform", "scale(" + scale + ")");
}
let scale = 1;
const el = document.querySelector(".left");
el.onwheel = zoom;

And next function we created for submit button, This function works when a user clicks on an element with the class "sub". it just sets the src attribute on the #img element.

And now the most major task is image filter handling. This section listens for changes in input values for various image filters like brightness (brt), contrast (cnt), grayscale (gs), etc. It creates the corresponding CSS filter property value and applies it to the image element whenever one of these input values changes.

And lastly, we created a zoom function. With the help of this function, we will be able to zoom in and out of the image. But the zoom is limited to a range between 0.125 and 2 times the original size of the image.


We are grateful for your time and attention, and we trust that you have found the project to be interesting.




Video of the Project


Download Source Code File

From here You can download the source code file of this JavaScript Image Editor.
If you are just starting in web development, these snippets will be useful. We would appreciate it if you would share our blog posts with other like-minded people.


Download Source Code
Please wait ...
If the download didn't start automatically, click here

Take This Short Survey!

ByteWebster Play and Win Offer.

PLAY A SIMPLE GAME AND WIN PREMIUM WEB DESIGNS WORTH UPTO $100 FOR FREE.

PLAY FOR FREE





Connect With Us

we would like to keep in touch with you..... Register Here.

JOIN US JOIN TELEGRAM