Canvas API

 

Canvas API - Web API | MDN

Canvas API는 JavaScript와 HTML <canvas> 엘리먼트를 통해 그래픽을 그리기위한 수단을 제공합니다. 무엇보다도 애니메이션, 게임 그래픽, 데이터 시각화, 사진 조작 및 실시간 비디오 처리를 위해 사용

developer.mozilla.org

JavaScript와 HTML <canvas> element가 제공하는 graphic 그리기 API이다. 간단하게 도형을 그리는 것부터 Animation, game graphic, data 시각화, 사진 조작 및 실시간 vidio 처리를 위해 사용된다.

 

 

HTML, Canvas element

<canvas id="canvas"></canvas>
<button type="button" class="drawing-btn" id="drawing_btn">그리기</button>
<button type="button" class="clear-btn" id="clear_btn">지우기</button>

먼저 <canvas> element를 만든다. DOM으로 제어하기 때문에 id를 단다.

 

JavaScript

<script>

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = innerWidth;
    canvas.height = innerHeight;

    const drawingBtn = document.getElementById('drawing_btn');
    const clearBtn = document.getElementById('clear_btn');
    let painting = false;

    drawingBtn.addEventListener("click", (ev) => {
        startPainting();
    });

    function startPainting() {
        painting = true;
    }

    function stopPainting(event) {
        painting = false;
    }

    ctx.strokeStyle = "rgba(255, 242, 0)";
    ctx.lineWidth = 3;

    function onMouseMove(event) {
        const x = event.offsetX;
        const y = event.offsetY;
        if (!painting) {
            ctx.beginPath();
            ctx.moveTo(x, y);
        } else {
            ctx.lineTo(x, y);
            ctx.stroke();
        }
    }
    
    drawingBtn.addEventListener("click", (ev) => {
        if(canvas.style.display === "block"){
            canvas.style.display = "none";
            clearBtn.style.display = "none";
        }else{
            canvas.style.display = "block";
            clearBtn.style.display = "block";
            painting = false;

            if (canvas) {
                canvas.addEventListener("mousemove", onMouseMove);
                canvas.addEventListener("mousedown", startPainting);
                canvas.addEventListener("mouseup", stopPainting);
                canvas.addEventListener("mouseleave", stopPainting);
            }
        }

        clearBtn.addEventListener("click", () => {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        });
    });


</script>

 

'그리기' button을 클릭하면 canvas와 지우기 button이 display none에서 block으로 바뀌며, canvas 영역을 클릭하면 그림을 그릴 수 있는 형태의 logic으로 전체 script이다.

 

변수 선언

canvas 생성에 관련한 변수 선언이다. 그리기는 CanvasRenderingContext2D interface를 사용해 수행된다.

const canvas = document.getElementById('canvas'); // canvas
const ctx = canvas.getContext('2d'); // 그리기의 대상
canvas.width = innerWidth; // canvas의 width
canvas.height = innerHeight; // canvas의 height

const drawingBtn = document.getElementById('drawing_btn'); // 그리기 button
const clearBtn = document.getElementById('clear_btn'); // 지우기 button
let painting = false; // 그리기 여부 상태

ctx.strokeStyle = "rgba(255, 242, 0)"; // 채우기 선의 색
ctx.lineWidth = 3; // 선의 굵기

 

HTMLCanvasElement.getContext() method는 element의 context(rendering될 그리기의 대상)를 얻는다. 쉽게 말해 작업을 할 수 있게 하는 여러 속성과 method가 든 객체이다.

 

canvas의 크기는 px 단위로 가능하며, inner는 유동적인 크기에 맞출 수 있다. canvas tag 안에 width, height로 설정할 수ㄷ도 있고 canvas.width = 50vw; 식 DOM으로 설정할 수도 있다. (width 단위 vw, height 단위 vh)

 

ctx.strokeStyle: 도형 색 채우기의 색이자 선 그리기에서는 선의 색상이다. "yellow", "rgba(0, 0, 0)" 형태로 작성 가능.

ctx.lineWidth: 선의 굵기 설정이다.

 

주요 기능

function startPainting() {
    painting = true;
} // 그리기 시작

function stopPainting(event) {
    painting = false;
} // 그리기 멈춤

function onMouseMove(event) {
    const x = event.offsetX;
    const y = event.offsetY;
    if (!painting) {
        ctx.beginPath();
        ctx.moveTo(x, y);
    } else {
        ctx.lineTo(x, y);
        ctx.stroke();
    }
} // 그리는 상태(마우스 움직일 때)

 

onMouseMove: mouse의 움직임대로 선이 그려지기 위해 mouse의 현재 위치 즉 화면에서의 좌표 값을 받아야 한다.

 

함수 실행

drawingBtn.addEventListener("click", (ev) => {
    if(canvas.style.display === "block"){
        canvas.style.display = "none";
        clearBtn.style.display = "none";
    }else{
        canvas.style.display = "block";
        clearBtn.style.display = "block";
        painting = false;

        if (canvas) {
            canvas.addEventListener("mousemove", onMouseMove);
            canvas.addEventListener("mousedown", startPainting);
            canvas.addEventListener("mouseup", stopPainting);
            canvas.addEventListener("mouseleave", stopPainting);
        }
    }

    clearBtn.addEventListener("click", () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    });

drawingBtn을 클릭했을 때만 canvas가 드러나서 그리기가 시작되도록 했다. mouse 상태에 따른 진행 내용을 if문으로 넣었으며, 삭제 또한 지원해 주는 ctx.clearRect(x, y, width, height) method로 구현한다. 위 code는 canvas 내의 모든 내용을 지우는 함수이다.

 

canvas 겹치기

<canvas id="canvas" style="display: none; position: absolute; z-index: 9999;"></canvas>
<div class="swiper mySwiper" style="position: relative"

나의 경우는 그리기 canvas가 다른 div 화면의 위에 덮이는 형태를 원해서 position absolute와 relative를 주었다. 만일 canvas에서 아래 화면이 click되길 원하면 z-index: 9999; 를 주면 된다는데 왜인지 안 먹히는 것 같다.

복사했습니다!