728x90

canvas 를 이용해 낙서장 만들기 스크립트 및 html 태그 예시

 

html5 에 있는 canvas 태그를 이용하면 낙서장, 서명란 등을 간단하게 구현 할 수 있다. 스크립트를 적용하면 마우스나 터치팬에서도 잘 작동 한다. 처음 작업 했을때는 width:100px, height:100px 처럼 사이즈가 정의된 경우만 적용이 되어서 반응형을 못맞췄었는데 스크립트로 화면의 가로 세로 사이즈를 체크해서 가로 세로 값을 계산해서 canvas.width 에 적용해 주면 화면이 유동적이어도 적용이 잘 된다. 단 임의로 화면 사이즈를 줄였을때도 적응이 되게 하려면 리사이징 시에도 가로세로 값을 체크 하는 함수를 한번 더 호출해주어야 한다. 아래 예시는 부분은 작업 되어 있지 않다. 

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas Drawing and Erasing</title>
    <style>
        canvas {
            border: 1px solid black;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <button id="toggleEraser">Toggle Eraser</button>
    <canvas id="drawCanvas"></canvas>
    <script src="script.js"></script>
</body>
</html>

 

const canvas = document.getElementById('drawCanvas');
const context = canvas.getContext('2d');
let isDrawing = false;
let isErasing = false;

function resizeCanvas() {
    canvas.width = canvas.offsetWidth;
    canvas.height = canvas.offsetHeight;
}

function getPosition(e) {
    if (e.touches) {
        return {
            x: e.touches[0].clientX - canvas.offsetLeft,
            y: e.touches[0].clientY - canvas.offsetTop
        };
    } else {
        return {
            x: e.clientX - canvas.offsetLeft,
            y: e.clientY - canvas.offsetTop
        };
    }
}

function startDrawing(e) {
    e.preventDefault();
    isDrawing = true;
    draw(e);
}

function stopDrawing() {
    isDrawing = false;
    context.beginPath();  // 경로 초기화
}

function draw(e) {
    if (!isDrawing) return;

    const pos = getPosition(e);

    context.lineWidth = 10;
    context.lineCap = 'round';

    if (isErasing) {
        context.globalCompositeOperation = 'destination-out';
        context.strokeStyle = 'rgba(0,0,0,1)';
    } else {
        context.globalCompositeOperation = 'source-over';
        context.strokeStyle = '#000';
    }

    context.lineTo(pos.x, pos.y);
    context.stroke();
    context.beginPath();  // 새로운 경로 시작
    context.moveTo(pos.x, pos.y);
}

function toggleEraser() {
    isErasing = !isErasing;
    const button = document.getElementById('toggleEraser');
    button.textContent = isErasing ? 'Switch to Draw' : 'Switch to Erase';
}

function clickDrawReset() {
    context.clearRect(0, 0, canvas.width, canvas.height);
}

canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
canvas.addEventListener('touchstart', startDrawing);
canvas.addEventListener('touchmove', function (e) {
    e.preventDefault();
    draw(e);
});
canvas.addEventListener('touchend', stopDrawing);

document.getElementById('toggleEraser').addEventListener('click', toggleEraser);
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
728x90

+ Recent posts