Xây dựng trình chỉnh sửa hình ảnh trong HTML CSS & JavaScript

Thứ năm - 28/07/2022 22:03
Xin chào các bạn, hôm nay trong blog này, các bạn sẽ học cách tạo một dự án mới có tên là Build An Basic Image Editor trong HTML CSS & JavaScript. Trước đây, tôi đã chia sẻ một blog về cách xây dựng trò chơi đoán từ trong JavaScript.
Trong dự án này (Trình chỉnh sửa hình ảnh bằng JavaScript), như bạn đã thấy trong hình ảnh xem trước, người dùng có thể áp dụng các bộ lọc khác nhau cho hình ảnh của họ như thang độ xám, đảo ngược, độ bão hòa và điều chỉnh độ sáng của hình ảnh. Ngoài ra, người dùng cũng có thể xoay hoặc lật hình ảnh và lưu hình ảnh đã chỉnh sửa của họ.
Dự án này được thực hiện với JavaScript vani. Nếu bạn hào hứng muốn xem bản trình diễn của trình chỉnh sửa hình ảnh này hoặc muốn biết trình chỉnh sửa này trông như thế nào. Bạn có thể xem video YouTube đã cho hoặc nhấp vào đây để xem bản demo trực tiếp của trình chỉnh sửa hình ảnh cơ bản này.

Trình chỉnh sửa hình ảnh cơ bản trong JavaScript

Để xây dựng Trình chỉnh sửa hình ảnh bằng HTML CSS & JavaScript, bạn cần tạo 3 file: HTML, CSS & JavaScript. Khi bạn tạo các tệp này, chỉ cần dán các mã đã cho vào file của bạn. Nếu bạn không biết cách tạo các tệp này, nơi dán mã hoặc không muốn làm những việc này, bạn chỉ cần tải xuống tệp mã nguồn của Trình chỉnh sửa hình ảnh này bằng cách nhấp vào nút tải xuống đã cho ở cuối trang này.
Đầu tiên, tạo một file HTML với tên index.html và dán các mã đã cho vào tệp HTML của bạn. Hãy nhớ rằng, bạn phải tạo một tệp có đuôi .html.
<!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/boxicons@2.1.2/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>
Thứ hai, tạo một file CSS với tên style.css và dán các mã đã cho vào file CSS của bạn. Hãy nhớ rằng, bạn phải tạo một file có đuôi .css.
/* 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;
  }
}
Cuối cùng, tạo một file JavaScript với tên script.js và dán các mã đã cho vào file JavaScript của bạn. Hãy nhớ rằng, bạn phải tạo file có đuôi .js.
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");

let brightness = "100", saturation = "100", inversion = "0", grayscale = "0";
let rotate = 0, flipHorizontal = 1, flipVertical = 1;

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");
    });
}

const applyFilter = () => {
    previewImg.style.transform = `rotate(${rotate}deg) scale(${flipHorizontal}, ${flipVertical})`;
    previewImg.style.filter = `brightness(${brightness}%) saturate(${saturation}%) invert(${inversion}%) grayscale(${grayscale}%)`;
}

filterOptions.forEach(option => {
    option.addEventListener("click", () => {
        document.querySelector(".active").classList.remove("active");
        option.classList.add("active");
        filterName.innerText = option.innerText;

        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}%`;
        }
    });
});

const updateFilter = () => {
    filterValue.innerText = `${filterSlider.value}%`;
    const selectedFilter = document.querySelector(".filter .active");

    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();
}

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();
    });
});

const resetFilter = () => {
    brightness = "100"; saturation = "100"; inversion = "0"; grayscale = "0";
    rotate = 0; flipHorizontal = 1; flipVertical = 1;
    filterOptions[0].click();
    applyFilter();
}

const saveImage = () => {
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    canvas.width = previewImg.naturalWidth;
    canvas.height = previewImg.naturalHeight;
    ctx.filter = `brightness(${brightness}%) saturate(${saturation}%) invert(${inversion}%) grayscale(${grayscale}%)`;
    ctx.translate(canvas.width / 2, canvas.height / 2);
    if(rotate !== 0) {
        ctx.rotate(rotate * Math.PI / 180);
    }
    ctx.scale(flipHorizontal, flipVertical);
    ctx.drawImage(previewImg, -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();
}

filterSlider.addEventListener("input", updateFilter);
resetFilterBtn.addEventListener("click", resetFilter);
saveImgBtn.addEventListener("click", saveImage);
fileInput.addEventListener("change", loadImage);
chooseImgBtn.addEventListener("click", () => fileInput.click());
Đó là tất cả, bây giờ bạn đã xây dựng thành công Trình chỉnh sửa hình ảnh cơ bản trong HTML CSS & JavaScript. Nếu mã của bạn không hoạt động hoặc bạn gặp phải bất kỳ sự cố nào, vui lòng tải xuống tệp mã nguồn từ nút tải xuống đã cho. Nó miễn phí và một tệp zip sẽ được tải xuống có chứa thư mục dự án với các tệp mã nguồn.

Mã giải nén: 3yxWswZ431eoDbhrSAanfXLNnjGEMKv1J853FOFJn30

Tác giả: admin, codingnepalweb

Nguồn tin: www.codingnepalweb.com

Tổng số điểm của bài viết là: 0 trong 0 đánh giá

Click để đánh giá bài viết

  Ý kiến bạn đọc

Những tin mới hơn

Những tin cũ hơn

Bạn đã không sử dụng Site, Bấm vào đây để duy trì trạng thái đăng nhập. Thời gian chờ: 60 giây