Почти Paint: как создать приложение для рисования в браузере на JavaScript Фронтенд-разработчик под ником Shuvo опубликовал туториал по созданию браузерного приложения для рисования с помощью JavaScript и элемента HMTL5 «canvas». Готовый проект подойдет для портфолио, а если функционала будет недостаточно, его можно расширить, добавив в прилагающийся исходный код все необходимое. Давайте приступим.
Фронтенд-разработчик под ником Shuvo опубликовал туториал по созданию браузерного приложения для рисования с помощью JavaScript и элемента HMTL5 canvas
. Готовый проект подойдет для портфолио, а если функционала будет недостаточно, его можно расширить, добавив в прилагающийся исходный код все необходимое. Давайте приступим.
Готовый проект будет обладать следующим функционалом:
Вот что должно политься:
index.html
c элементом canvas
<!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"> <link rel="stylesheet" href="style.css"> <title>JavaScript Drawing APP</title> </head> <body> <canvas id="canvas"></canvas> <script src="main.js"></script> </body> </html>
style.css
с основными настройками*{ margin: 0; padding: 0; }
main.js
, в котором определим размер холста приложения в соответствии с размером экранаconst canvas = document.getElementById("canvas") canvas.height = window.innerHeight canvas.width = window.innerWidth // ctx is the context of our canvas // we use ctx to draw on the canvas const ctx = canvas.getContext("2d") // lets create a rectangle for testing purposes ctx.fillStyle = "red" ctx.fillRect(100, 100, 100, 100)
При открытии файла в браузере, должен появиться красный прямоугольник:
mousemove
const canvas = document.getElementById("canvas") canvas.height = window.innerHeight canvas.width = window.innerWidth const ctx = canvas.getContext("2d") window.addEventListener("mousemove", (e) => { console.log("Mouse X: " + e.clientX) console.log("Mouse Y: " + e.clientY) })
const canvas = document.getElementById("canvas") canvas.height = window.innerHeight canvas.width = window.innerWidth const ctx = canvas.getContext("2d") // previous mouse positions // They will be null initially let prevX = null let prevY = null // How thick the lines should be ctx.lineWidth = 5 window.addEventListener("mousemove", (e) => { // initially previous mouse positions are null // so we can't draw a line if(prevX == null || prevY == null){ // Set the previous mouse positions to the current mouse positions prevX = e.clientX prevY = e.clientY return } // Current mouse position let currentX = e.clientX let currentY = e.clientY // Drawing a line from the previous mouse position to the current mouse position ctx.beginPath() ctx.moveTo(prevX, prevY) ctx.lineTo(currentX, currentY) ctx.stroke() // Update previous mouse position prevX = currentX prevY = currentY })
Теперь при перемещении линии будет рисовать линия. Но это бесконтрольный процесс. Поэтому, чтобы рисовать только тогда, когда нужно, необходимо объявить переменную let draw = false
. Теперь линия будет появляться только в том случае, если draw = true
, то есть при нажатии пользователем правой кнопки мыши, и draw = false
, когда он ее отпускает.
const canvas = document.getElementById("canvas") canvas.height = window.innerHeight canvas.width = window.innerWidth const ctx = canvas.getContext("2d") let prevX = null let prevY = null ctx.lineWidth = 5 let draw = false // Set draw to true when mouse is pressed window.addEventListener("mousedown", (e) => draw = true) // Set draw to false when mouse is released window.addEventListener("mouseup", (e) => draw = false) window.addEventListener("mousemove", (e) => { // if draw is false then we won't draw if(prevX == null || prevY == null || !draw){ prevX = e.clientX prevY = e.clientY return } let currentX = e.clientX let currentY = e.clientY ctx.beginPath() ctx.moveTo(prevX, prevY) ctx.lineTo(currentX, currentY) ctx.stroke() prevX = currentX prevY = currentY })
<!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"> <link rel="stylesheet" href="style.css"> <title>Document</title> </head> <body> <canvas id="canvas"></canvas> <div class="nav"> <!-- We will be accessing the data-clr in JavaScript --> <div class="clr" data-clr="#000"></div> <div class="clr" data-clr="#EF626C"></div> <div class="clr" data-clr="#fdec03"></div> <div class="clr" data-clr="#24d102"></div> <div class="clr" data-clr="#fff"></div> <button class="clear">clear</button> <button class="save">save</button> </div> <script src="main.js"></script> </body> </html>
*{ margin: 0; padding: 0; } .nav{ width: 310px; height: 50px; position: fixed; top: 0; left: 50%; transform: translateX(-50%); display: flex; align-items: center; justify-content: space-around; opacity: .3; transition: opacity .5s; } .nav:hover{ opacity: 1; } .clr{ height: 30px; width: 30px; background-color: blue; border-radius: 50%; border: 3px solid rgb(214, 214, 214); transition: transform .5s; } .clr:hover{ transform: scale(1.2); } .clr:nth-child(1){ background-color: #000; } .clr:nth-child(2){ background-color: #EF626C; } .clr:nth-child(3){ background-color: #fdec03; } .clr:nth-child(4){ background-color: #24d102; } .clr:nth-child(5){ background-color: #fff; } button{ border: none; outline: none; padding: .6em 1em; border-radius: 3px; background-color: #03bb56; color: #fff; } .save{ background-color: #0f65d4; }
При переходе на страницу приложения в браузере должно отобразиться следующее:
Теперь при щелчке на div
с классом clr
добавляем установку цвета линии в свойство data-clr
этого div
const canvas = document.getElementById("canvas") canvas.height = window.innerHeight canvas.width = window.innerWidth const ctx = canvas.getContext("2d") let prevX = null let prevY = null ctx.lineWidth = 5 let draw = false // Selecting all the div that has a class of clr let clrs = document.querySelectorAll(".clr") // Converting NodeList to Array clrs = Array.from(clrs) clrs.forEach(clr => { clr.addEventListener("click", () => { ctx.strokeStyle = clr.dataset.clr }) }) window.addEventListener("mousedown", (e) => draw = true) window.addEventListener("mouseup", (e) => draw = false) window.addEventListener("mousemove", (e) => { if(prevX == null || prevY == null || !draw){ prevX = e.clientX prevY = e.clientY return } let currentX = e.clientX let currentY = e.clientY ctx.beginPath() ctx.moveTo(prevX, prevY) ctx.lineTo(currentX, currentY) ctx.stroke() prevX = currentX prevY = currentY })
const canvas = document.getElementById("canvas") canvas.height = window.innerHeight canvas.width = window.innerWidth const ctx = canvas.getContext("2d") let prevX = null let prevY = null ctx.lineWidth = 5 let draw = false let clrs = document.querySelectorAll(".clr") clrs = Array.from(clrs) clrs.forEach(clr => { clr.addEventListener("click", () => { ctx.strokeStyle = clr.dataset.clr }) }) let clearBtn = document.querySelector(".clear") clearBtn.addEventListener("click", () => { // Clearning the entire canvas ctx.clearRect(0, 0, canvas.width, canvas.height) }) window.addEventListener("mousedown", (e) => draw = true) window.addEventListener("mouseup", (e) => draw = false) window.addEventListener("mousemove", (e) => { if(prevX == null || prevY == null || !draw){ prevX = e.clientX prevY = e.clientY return } let currentX = e.clientX let currentY = e.clientY ctx.beginPath() ctx.moveTo(prevX, prevY) ctx.lineTo(currentX, currentY) ctx.stroke() prevX = currentX prevY = currentY })
const canvas = document.getElementById("canvas") canvas.height = window.innerHeight canvas.width = window.innerWidth const ctx = canvas.getContext("2d") let prevX = null let prevY = null ctx.lineWidth = 5 let draw = false let clrs = document.querySelectorAll(".clr") clrs = Array.from(clrs) clrs.forEach(clr => { clr.addEventListener("click", () => { ctx.strokeStyle = clr.dataset.clr }) }) let clearBtn = document.querySelector(".clear") clearBtn.addEventListener("click", () => { ctx.clearRect(0, 0, canvas.width, canvas.height) }) // Saving drawing as image let saveBtn = document.querySelector(".save") saveBtn.addEventListener("click", () => { let data = canvas.toDataURL("imag/png") let a = document.createElement("a") a.href = data // what ever name you specify here // the image will be saved as that name a.download = "sketch.png" a.click() }) window.addEventListener("mousedown", (e) => draw = true) window.addEventListener("mouseup", (e) => draw = false) window.addEventListener("mousemove", (e) => { if(prevX == null || prevY == null || !draw){ prevX = e.clientX prevY = e.clientY return } let currentX = e.clientX let currentY = e.clientY ctx.beginPath() ctx.moveTo(prevX, prevY) ctx.lineTo(currentX, currentY) ctx.stroke() prevX = currentX prevY = currentY })
Вот и все!
Ранее мы писали о том, как Shuvo разработал «Игру в кальмара» на JavaScript.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…