강의/노마드 코더 강의

노마드 코더 - 바닐라 JS로 그림 앱 만들기- 그림판 만들기

홍시_코딩기록 2023. 5. 26. 20:30

대충 모양 나오는 그림판

//html

data-color 값을 줘서 js에서 불러올 수 있게함.

'color'는 사용자 임의대로 지정할 수 있음. data-potato, data-abc..

<div class="wrap">        
    <canvas></canvas>
    <div class="color_box">
        <input type="range" id="line_width" min="1" max="10" value="5" step="0.5">
        <input type="color" id="color">
        <div class="color_pick">
            <div class="color_option" style="background-color:#eb4d4b;" data-color="#eb4d4b"></div>
            <div class="color_option" style="background-color:#ff7979;" data-color="#ff7979"></div>
            <div class="color_option" style="background-color:#f0932b;" data-color="#f0932b"></div>
            <div class="color_option" style="background-color:#95afc0;" data-color="#95afc0"></div>
            <div class="color_option" style="background-color:#f9ca24;" data-color="#f9ca24"></div>
            <div class="color_option" style="background-color:#badc58;" data-color="#badc58"></div>
            <div class="color_option" style="background-color:#ffbe76;" data-color="#ffbe76"></div>
            <div class="color_option" style="background-color:#7ed6df;" data-color="#7ed6df"></div>
            <div class="color_option" style="background-color:#686de0;" data-color="#686de0"></div>
        </div>
        <button id="mode_btn">Fill</button>
        <button id="destroy_btn">Destroy</button>
        <button id="eraser_btn">Erase</button>
    </div>
</div>
 

//js

코드가 너무 길어서 정리하고 싶은데 일단 나중으로 미뤄본다.

const colorOptions = Array.from(

document.getElementsByClassName("color_option")

);

forEach를 써야하는데 배열로 바꿔주어야해서 array.from을 씀.

 

const modeBtn = document.getElementById("mode_btn");
const destroyBtn = document.getElementById("destroy_btn");
const eraserBtn = document.getElementById("eraser_btn");
const colorOptions = Array.from(
    document.getElementsByClassName("color_option")
);
const color = document.getElementById("color");
const lineWidth = document.getElementById("line_width");
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext('2d');

const canvasWidth = 800;
const canvasHight = 800;
canvas.width = canvasWidth;
canvas.height = canvasHight;

ctx.lineWidth = lineWidth.value;
let isPainting = false;
let isFilling = false;

//브러쉬 그리기
function onMove(e) {
    if (isPainting) {
        ctx.lineTo(e.offsetX, e.offsetY);
        ctx.stroke();
        return;
    }
    ctx.beginPath();
    ctx.moveTo(e.offsetX, e.offsetY);
};
function startPainting() {
    isPainting = true;
};
function cancelPainting() {
    isPainting = false;
};
//브러쉬 크기 바꾸기
function onLineChange(e) {
    ctx.lineWidth = e.target.value;
}
//브러쉬 컬러 바꾸기
function onColorChange(e) {
    ctx.strokeStyle = ctx.fillStyle = e.target.value;
}
//컬러pick
function onColorClick(e){
    const colorValue = e.target.dataset.color;
    ctx.strokeStyle = ctx.fillStyle = color.value = colorValue;
}
//fill, draw 버튼 토글
function onModeClick() {
    if(isFilling){
        isFilling = false;
        modeBtn.innerText = "Fill"
    } else {
        isFilling = true;
        modeBtn.innerText = "Draw"
    }
}
//캔버스 꽉 채우기
function onCanvasClick() {
    if(isFilling){
        ctx.fillRect(0, 0, canvasWidth, canvasHight);
    }
}
function onDestroyClick() {
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, canvasWidth, canvasHight);
}
function onEraserClick() {
    ctx.strokeStyle = "white";
    isFilling = false;
    modeBtn.innerText = "Fill"
}

canvas.addEventListener("mousemove", onMove);
canvas.addEventListener("mousedown", startPainting);
document.addEventListener("mouseup", cancelPainting);
// canvas.addEventListener("mouseleave", cancelPainting);
canvas.addEventListener("click", onCanvasClick);

lineWidth.addEventListener("change", onLineChange);
color.addEventListener("change",onColorChange);

colorOptions.forEach(color => color.addEventListener("click", onColorClick));

modeBtn.addEventListener("click", onModeClick);
destroyBtn.addEventListener("click", onDestroyClick);
eraserBtn.addEventListener("click", onEraserClick);