๐ Painting-App-Toy-Project ๐
Vanilla JS ๋ก ์ ์ํ ๋ฐ์ํ ๊ทธ๋ฆผํ ์น์ ๋๋ค.
์ถ์ฒ: ๋ ธ๋ง๋์ฝ๋ ๊ฐ์ ํ์ฉ
javascript ๋ง์ ์ด์ฉํ์ฌ ์ ์ํ ๊ทธ๋ฆผํ์ ๊ตฌํํด ๋ณด์์ต๋๋ค.
๊ตฌํํ javascript code
const colors = document.getElementsByClassName(`jsColor`);
const canvas = document.getElementById(`jsCanvas`);
const range = document.getElementById(`jsRange`);
const clear = document.getElementById(`jsClear`);
const fill = document.getElementById(`jsFill`);
const saveBtn = document.getElementById(`jsSave`);
const canvasSizeForm = document.querySelector(`.defineCanvasSize`);
const inputWidth = canvasSizeForm.querySelector(`#jsWidth`);
const inputHeight = canvasSizeForm.querySelector(`#jsHeight`);
const sizeBtn = document.getElementById(`jsCanvasSizeBtn`);
const INITIAL_COLOR = `#1a1a1a`;
const context = canvas.getContext(`2d`);
let painting = false;
let filling = false;
context.strokeStyle = INITIAL_COLOR;
context.fillStyle = INITIAL_COLOR;
context.lineWidth = 2.5;
let widthValue = 0;
let heightValue = 0;
canvas.style.width = widthValue;
canvas.style.height = heightValue;
๋ณ์ ์ ์ธ๊ณผ ๊ธฐ๋ณธ ๊ฐ๋ค ์ ์.
๊ธฐ๋ณธ ์บ๋ฒ์ค์ ์ฌ์ด์ฆ๋ฅผ 0์ผ๋ก ์ค์ ํ์ฌ ์ฌ์ฉ์๊ฐ ๊ฐ์ ์
๋ ฅํ๊ธฐ ์ ์๋ ์บ๋ฒ์ค๊ฐ ๋ณด์ด์ง ์๋๋ก ํ์์ต๋๋ค.
function canvasSetting() {
canvas.style.width = "";
canvas.style.height = "";
widthValue = inputWidth.value;
heightValue = inputHeight.value;
context.fillStyle = `white`;
context.fillRect(0, 0, widthValue, heightValue);
canvas.style.width = widthValue;
canvas.style.height = heightValue;
canvas.width = widthValue;
canvas.height = heightValue;
}
์บ๋ฒ์ค ์ธํ
๊ณผ ๊ธฐ๋ณธ ๊ฐ๋ค์ ์ด๊ธฐํํ๋ ํจ์.
function stopPainting() {
painting = false;
}
function startPainting() {
painting = true;
}
function onMouseLeave() {
stopPainting();
}
function onMouseMove(event) {
const x = event.offsetX;
const y = event.offsetY;
if (!painting) {
context.beginPath();
context.moveTo(x, y);
} else {
context.lineTo(x, y);
context.stroke();
}
}
๋ง์ฐ์ค๊ฐ ์บ๋ฒ์ค ์์์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผฐ์ ๋, ์ํฉ์ ๋ฐ๋ผ ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๊ฑฐ๋ ๊ทธ๋ฆผ ๊ทธ๋ฆฌ๋ ๊ฒ์ ๋ฉ์ถ๊ฒ ํ๋ ํจ์๋ค ์
๋๋ค.
๋ง์ฐ์ค๊ฐ ์์ง์ผ ๋ ํฌ์ธํฐ์ ์์น๋ฅผ offsetX , offsetY ๋ก ๊ฐ์ ธ์ path(๋ณด์ด์ง ์๋) ๋ฅผ ์์ฑํฉ๋๋ค
ํด๋ฆญ์ด ๋ฐ์ํ ์์ ์ paiting ์ true ๋ก ๋ณ๊ฒฝํ์ฌ ๋ผ์ธ์ ๊ทธ๋ฆฌ๋๋ก ๊ตฌํํ์์ต๋๋ค.
function handleColorClick() {
const color = event.target.style.backgroundColor;
context.strokeStyle = color;
context.fillStyle = color;
}
ํ๋ ํธ์ ํด๋นํ๋ ์์ ํด๋ฆญํ์ ๋, ํ์ธํธ(fillStyle)์ ๋ธ๋ฌ์ฌ(strokeStyle)์ ์์์ ๋ณ๊ฒฝํ๋ ํจ์์
๋๋ค.
๋ฒํผ์ด ํด๋ฆญ๋์ ๋, ํด๋ฆญ๋ ๋ฒํผ์ ๋ฐฐ๊ฒฝ์์ ์์ ๋ณ์์ ๋ฃ์ด ์ฌ์ฉํฉ๋๋ค.
function handleRangeChange() {
const colorRange = event.target.value;
context.lineWidth = colorRange;
}
input์ value๋ก ๋ธ๋ฌ์ฌ์ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ๋ ํจ์์
๋๋ค.
function handleClickFillMode() {
if (filling === true) {
filling = false;
fill.innerText = `Paint`;
} else {
filling = true;
fill.innerText = `Brush`;
}
}
Paint ๋ฒํผ ํด๋ฆญ ์ ๋ธ๋ฌ์ฌ์์ ํ์ธํธํต์ผ๋ก ์ ํํ๋ ํจ์์
๋๋ค.
function handleCanvasClick() {
if (filling) {
context.fillRect(0, 0, widthValue, heightValue);
}
}
ํ์ธํธํต์ผ๋ก ์ค์ ๋์์ ๋ ๋ฐฐ๊ฒฝ์ ํด๋ฆญํ๋ฉด, ์์ด ์น ํด์ง๋๋ก ํ๋ ํจ์ ์
๋๋ค.
fillRect์ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๋ฐฐ๊ฒฝ ์ฌ์ด์ฆ ๊ฐ์ ์ ์ฉํ์ฌ ์์์ด ์
ํ์ง๋๋ค.
function saveClick() {
const image = canvas.toDataURL();
const link = document.createElement(`a`);
link.href = image;
link.download = `Paint JS by JIREH's Canvas`;
link.click();
}
function blockRightClick() {
event.preventDefault();
alert(`์ ์ฅ์ ์ํ์๋ฉด SAVE ๋ฒํผ์ ๋๋ฌ์ฃผ์ธ์`);
}
์ ์ฅ์ ํ๋ Save ๋ฒํผ์ saveClick ํจ์์, ๋ง์ฐ์ค ์ค๋ฅธ์ชฝ์ผ๋ก ์ ์ฅํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํ blockRightClick ํจ์ ์
๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก png ํ์ผ๋ก ์ ์ฅ์ด ๊ฐ๋ฅํ๊ณ , Paint JS by JIREH's Canvas ๋ผ๋ ํ์ผ๋ช
์ผ๋ก ์ ์ฅ๋ฉ๋๋ค.
*JIREH : ์์ฑ์ ๋ณธ์ธ์ ์ํฐ์คํธ, ๋์์ด๋ ์์ ํ๋๋ช
function cleanCanvas() {
canvasSetting();
const modifiedRangeValue = document.getElementById(`jsRange`);
context.lineWidth = modifiedRangeValue.value;
}
Clean ๋ฒํผ ํด๋ฆญ์ ๊ธฐ์กด ์ฌ์ฉ์ ์ธํ
๊ฐ์ผ๋ก ์ฌ์ค์ ํ๊ณ ๋ธ๋ฌ์ฌ ํฌ๊ธฐ๋ฅผ ์ด๊ธฐํ ์ํต๋๋ค.
if (colors) {
Array.from(colors).forEach((eachColor) =>
eachColor.addEventListener(`click`, handleColorClick)
);
}
if (canvas) {
canvas.addEventListener(`mousemove`, onMouseMove);
canvas.addEventListener(`mousedown`, startPainting);
canvas.addEventListener(`mouseup`, stopPainting);
canvas.addEventListener(`click`, handleCanvasClick);
canvas.addEventListener(`contextmenu`, blockRightClick);
}
if (range) {
range.addEventListener(`input`, handleRangeChange);
}
if (fill) {
fill.addEventListener(`click`, handleClickFillMode);
}
if (saveBtn) {
saveBtn.addEventListener("click", saveClick);
}
if (clear) {
clear.addEventListener(`click`, cleanCanvas);
}
sizeBtn.addEventListener("click", canvasSetting);
๋ฒํผ ํด๋ฆญ ์ ๋ฐ์ํ๋ ์ด๋ฒคํธ๋ค์ ์ ์์
๋๋ค.