[JS] HTML, CSS, JS로 그림판 만들기

dyomi·2023년 9월 22일
0
post-thumbnail

canvas 요소 생성

<canvas id="myCanvas" width="500" height="500"></canvas>

변수 준비

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d'); //context로 그래픽 작업 수행 예정

//그리기 작업 진행 여부
var isDrawing = false;

//그리기 시작점 좌표
var lastX = 0;
var lastY = 0;

이벤트 리스너

//마우스
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);

//터치 (패드나 핸드폰일 경우)
canvas.addEventListener('touchstart', startDrawing);
canvas.addEventListener('touchmove', draw);
canvas.addEventListener('touchend', stopDrawing);

함수 준비

function startDrawing(event) {
    isDrawing = true; // 그리기 작업 시작

	//현재 이벤트에서 얻은 마우스 위치 좌표 저장
    [lastX, lastY] = [event.offsetX, event.offsetY];
  }

function draw(event) {
  if (!isDrawing) return;
  context.beginPath(); // 새로운 경로를 시작
  context.moveTo(lastX, lastY); //그리기 시작 위치로 이동
  context.lineTo(event.offsetX, event.offsetY); //현재 마우스 좌표까지 그리기
  context.stroke(); //실제 선 그리기
  [lastX, lastY] = [event.offsetX, event.offsetY]; //현재 마우스 좌표 저장
}

function stopDrawing() {
  isDrawing = false;
}

전체 코드

    <!DOCTYPE html>
    <html>
    <head>
      <title>마우스로 그림 그리기</title>
      <style>
        canvas {
          border: 1px solid #000;
        }
      </style>
    </head>
    <body>
      <canvas id="myCanvas" width="500" height="500"></canvas>
    
      <script>
        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');
        var isDrawing = false;
        var lastX = 0;
        var lastY = 0;
    
        canvas.addEventListener('mousedown', startDrawing);
        canvas.addEventListener('mousemove', draw);
        canvas.addEventListener('mouseup', stopDrawing);
        canvas.addEventListener('mouseout', stopDrawing);
    
        function startDrawing(event) {
          isDrawing = true;
          [lastX, lastY] = [event.offsetX, event.offsetY];
        }
    
        function draw(event) {
          if (!isDrawing) return;
          context.beginPath();
          context.moveTo(lastX, lastY);
          context.lineTo(event.offsetX, event.offsetY);
          context.stroke();
          [lastX, lastY] = [event.offsetX, event.offsetY];
        }
    
        function stopDrawing() {
          isDrawing = false;
        }
      </script>
    </body>
    </html>

⭐ 참고사항

모바일 기기에서는 디바이스 화면 영역과 실제 픽셀 크기 간의 차이로 인해 터치 이벤트의 좌표가 달라질 수 있다.

이 경우, 뷰포트 크기와 캔버스의 실제 픽셀 크기를 고려해서 좌표를 변환해주어야 한다.

아래는 뷰포트 크기와 캔버스 실제 픽셀 크기 비율을 계산해서 사용한 코드이다.

let painting = false;
let lastX = 0;
let lastY = 0;

function startTouching() {
    painting=true;

    var touch = event.touches[0]; // 첫 번째 터치 이벤트만 사용

    // 뷰포트 크기와 캔버스의 실제 픽셀 크기 비율 계산
    var scale = canvas.width / canvas.offsetWidth;

    // 터치한 좌표를 캔버스 좌표로 변환
    var rect = canvas.getBoundingClientRect();
    lastX = (touch.clientX - rect.left) * scale;
    lastY = (touch.clientY - rect.top) * scale;
}

function stopTouching(event) {
    painting=false;
}

function onTouchMove(event) {
    if (!painting) return;

    var touch = event.touches[0]; // 첫 번째 터치 이벤트만 사용

    // 뷰포트 크기와 캔버스의 실제 픽셀 크기 비율 계산
    var scale = canvas.width / canvas.offsetWidth;

    // 터치한 좌표를 캔버스 좌표로 변환
    var rect = canvas.getBoundingClientRect();
    var x = (touch.clientX - rect.left) * scale;
    var y = (touch.clientY - rect.top) * scale;

    ctx.beginPath();
    ctx.moveTo(lastX, lastY);
    ctx.lineTo(x, y);
    ctx.stroke();

    lastX = x;
    lastY = y;
}
profile
기록하는 습관

0개의 댓글