Image Editing Using HTML, CSS and JavaScript

Hello wizards, I hope you are doing great. Today in this blog you’ll learn how to create the "Image Editing" project using HTML, CSS & JavaScript. 

Preview 

In the above video, you’ve seen the preview of the "Image Editing" project and I hope now you are able to create this type of project. If not, I have provided all the HTML CSS and JavaScript code below. 

Image Editing [Source Code] 

To get the following HTML, CSS & JS code for the Image Editing project. You need to create three files one is a HTML file, second one is a CSS file and the another one is JS file. After creating these three files then you can copy-paste the given codes on your document. 

Remember, you’ve to create a file with .html extension for HTML code, .css extension for CSS code and .js for JavaScript code.

You can also download all source code files from the given download button.

HTML
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Image Editor</title>
    <link rel="stylesheet" href="style.css">
    <!-- Font awesome cdn link -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
        integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>

<body>

    <div class="container">
        <div class="image">
            <img src="panda.jpg" alt="iceland">
        </div>
        <div class="filters">
            <div class="filter">
                <label for="saturation">Saturation</label>
                <div class="input">
                    <input type="range" min="0" max="200" id="saturation" value="100"
                        oninput="this.nextElementSibling.value = this.value">
                    <output>100</output>
                </div>
            </div>
            <div class="filter">
                <label for="blur">Blur</label>
                <div class="input">
                    <input type="range" min="0" max="10" id="blur" value="0"
                        oninput="this.nextElementSibling.value = this.value">
                    <output>0</output>
                </div>
            </div>
            <div class="filter">
                <label for="brightness">Brightness</label>
                <div class="input">
                    <input type="range" min="0" max="200" id="brightness" value="100"
                        oninput="this.nextElementSibling.value = this.value">
                    <output>100</output>
                </div>
            </div>
            <div class="filter">
                <label for="contrast">Contrast</label>
                <div class="input">
                    <input type="range" min="0" max="200" id="contrast" value="100"
                        oninput="this.nextElementSibling.value = this.value">
                    <output>100</output>
                </div>
            </div>
        </div>
        <ul class="angles">
            <li id="vertical"><i class="fa-solid fa-arrows-left-right up"></i></li>
            <li id="horizontal"><i class="fa-solid fa-arrows-left-right"></i></li>
            <li id="left"><i class="fa-solid fa-rotate-left"></i></li>
            <li id="right"><i class="fa-solid fa-rotate-right"></i></li>
        </ul>
        <div class="buttons">
            <input type="file" class="file" accept="image/*" hidden>
            <button class="resetBtn">R</button>
            <button class="btn chooseBtn">Choose</button>
            <button class="btn saveBtn">Save</button>
        </div>
    </div>

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

</html>
CSS
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}

body,
.container,
.buttons,
.filters,
.filter,
.angles,
.input,
.singleEffect {
  display: flex;
  align-items: center;
  justify-content: center;
}

body {
  min-height: 100vh;
  background-color: white;
}

.container {
  flex-direction: column;
  width: 400px;
  background-color: #f5bb00;
  color: black;
  padding: 20px;
  border-radius: 10px;
}

/* Image Container*/

.image {
  width: 100%;
  height: 260px;
  overflow: hidden;
}
img {
  max-width: 360px;
  max-height: 260px;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Filters Container */
.filters {
  flex-direction: column;
  width: 100%;
  gap: 15px;
  margin: 10px;
}

.filter {
  width: 100%;
  display: flex;
  justify-content: space-between;
}

label {
  font-size: 22px;
}

input {
  cursor: pointer;
}

output {
  width: 40px;
  text-align: end;
}

/* Angles Container */

.angles {
  list-style: none;
  gap: 30px;
  margin-top: 5px;
  margin-bottom: 20px;
  background-color: black;
  width: 100%;
  padding: 10px;
  border-radius: 10px;
}

.angles li {
  background-color: #f5bb00;
  color: black;
  padding: 10px 15px;
  border-radius: 50%;
  cursor: pointer;
}

.angles li:active {
  transform: scale(0.95);
}

.angles .up {
  transform: rotate(90deg);
}

/* Buttons Container */

.buttons {
  gap: 30px;
}

.btn {
  padding: 10px 30px;
  font-size: 18px;
  background-color: transparent;
  border: 3px solid black;
  color: black;
  border-radius: 5px;
  font-weight: 600;
  cursor: pointer;
}

.btn:hover {
  background-color: black;
  color: #f5bb00;
}

.btn:active {
  transform: scale(0.95);
}

.resetBtn {
  background-color: #8ea604;
  color: black;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: none;
  box-shadow: 4px 4px black;
  cursor: pointer;
}

.resetBtn:active {
  position: relative;
  top: 4px;
  left: 4px;
  box-shadow: none;
}
JavaScript
const imgEl = document.querySelector("img");

const filtersEl = document.querySelectorAll("input");

const anglesEl = document.querySelectorAll("li");

const fileEl = document.querySelector(".file");
const chooseBtnEl = document.querySelector(".chooseBtn");
const saveBtnEl = document.querySelector(".saveBtn");
const resetBtnEl = document.querySelector(".resetBtn");

let saturation = "100", blur = "0", brightness = "100", contrast = "100";
let rotate = 0, flipH = 1, flipV = 1;

// when this function execute all changes will be set to initial values.
const loadEl = () =>{
    filtersEl[0].value = "100";
    filtersEl[1].value = "0";
    filtersEl[2].value = "100";
    filtersEl[3].value = "100";
}

// It generates result of the image as preview
const generateResult = () => {
    imgEl.style.filter = `saturate(${saturation}%) blur(${blur}px) brightness(${brightness}%) contrast(${contrast}%)`;
    imgEl.style.transform = `rotate(${rotate}deg) scale(${flipH}, ${flipV})`;
}

// This will change the image rotation or flip when we click on any of the rotation or flip. 
anglesEl.forEach(element => {
    element.addEventListener("click", () => {
        if(element.id === "vertical") {
            flipV = flipV === 1 ? -1 : 1;
        } else if(element.id === "horizontal") {
            flipH = flipH === 1 ? -1 : 1;
        } else if(element.id === "left") {
            rotate = rotate - 90;
        } else {
            rotate = rotate + 90;
        }
        // It calls the generateResult function for every click on the rotation or flip flop
        generateResult();
    });
});

// This will change the image filters when we give input on any of the filters. 
filtersEl.forEach(element => {
    element.addEventListener("input", () => {
        if(element.id === "saturation") {
            saturation = filtersEl[0].value;
        } else if(element.id === "blur") {
             blur = filtersEl[1].value;
        } else if(element.id === "brightness") {
            brightness = filtersEl[2].value;
        } else {
            contrast = filtersEl[3].value;
        }
        // It calls the generateResult function for every click on the rotation or flip flop
    generateResult();
    });
});

// It resets the all values to initial conditions
resetBtnEl.addEventListener("click", () => {
    saturation = "100", blur = "0", brightness = "100", contrast = "100";
    rotate = 0, flipH = 1, flipV = 1;
    generateResult();
    loadEl();
})

// This function adds image to the project when we choose a image.
fileEl.addEventListener("change", ()=>{
        let file = fileEl.files[0];
        console.log(fileEl)
        if(!file) return;
        imgEl.src = URL.createObjectURL(file);
        imgEl.addEventListener("load", () => {
            resetBtnEl.click();
        });
})

chooseBtnEl.addEventListener("click",()=>{
    fileEl.click();
})

// when we click on save button it Saves our resultant image as ResultImage.jpg
saveBtnEl.addEventListener("click",()=>{
        const canvas = document.createElement("canvas");
        const ctx = canvas.getContext("2d");
        canvas.width = imgEl.naturalWidth;
        canvas.height = imgEl.naturalHeight;
        
        ctx.filter = `saturate(${saturation}%) blur(${blur}px) brightness(${brightness}%) contrast(${contrast}%)`;
        ctx.translate(canvas.width / 2, canvas.height / 2);
        if(rotate !== 0) {
            ctx.rotate(rotate * Math.PI / 180);
        }
        ctx.scale(flipH, flipV);
        ctx.drawImage(imgEl, -canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height);
        
        const link = document.createElement("a");
        link.download = "ResultImage.jpg";
        link.href = canvas.toDataURL();
        link.click();
})

// It calls loadEl function at the beginning i.e when the website is opened
loadEl();
You have to wait 15 seconds.

Generating Download Link...

Post a Comment

Previous Post Next Post