Web API - Canvas 기본 사용법 - 웹 페이지에서 캔버스로 원하는 위치에 직선 그리기

반응형

 

Overview

이번 포스팅에서는...

  1. 캔버스의 기본을 이해하고
  2. 캔버스 2D 컨텍스트 설정 방법을 알게되고
  3. 캔버스 위에 마우스로 클릭하여 원하는 위치에 직선을 생성하는

것을 다룹니다.


캔버스 (Canvas)

  • HTML5에서 추가된 요소 중 하나
  • 스크립트(보통은 자바스크립트)를 사용하여 그림을 그리는 데에 사용
    • 예) 그래프 그리기, 사진 합성, 애니메이션 등 다양한 그래픽 만들기
  • 캔버스에 드로잉(Drawing) 영역을 생성하고 하나 이상의 렌더링 컨텍스트를 노출하여 출력할 컨텐츠를 생성
    • 그래프 만들기, 도형 그리기 등 : 2D 렌더링 컨텍스트
    • WebGL, OpenGL ES 기반 : 3D 렌더링 컨텍스트
  • 즉, 자바스크립트를 사용하여 캔버스의 렌더링 컨텍스트에 접근하여 콘텐츠를 생성하는 기능을 가짐

캔버스 요소 (Canvas Element)

  • 'canvas'는 두 가지의 속성을 가지고 있음
    • width : 캔버스의 가로 크기 지정
    • height : 캔버스의 세로 크기 지정
    • 캔버스의 너비와 높이를 지정하지 않으면 기본값 너비는 300px, 높이는 150px
<canvas id="myCanvas" width="600px" height="300px" style="border: 1px dotted red;"></canvas>

렌더링 콘텍스트 설정

  • getContext() : 렌더링 컨텍스트 타입을 지정하는 메서드
  • 2D 그래픽일 경우, 파라미터를 "2d"로 지정
    • 이 포스팅에서는 간단한 직선을 그리는 것을 다루기 때문에 2D 그래픽을 사용합니다.
<script>
window.onload = function() {
    // 캔버스 객체 생성 및 렌더링 컨텍스트 설정
    canvas = document.getElementById("myCanvas");
    context = canvas.getContext("2d");
}
</script>

예제1 - 두 개의 직사각형을 캔버스에 출력

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <script type="application/javascript">
    // 캔버스에 두 개의 직사각형 그리는 함수
    function draw() {
        // 캔버스 객체 생성
        var canvas = document.getElementById("canvas");
        // 캔버스 렌더링 컨텍스트 2D 그래픽 설정
        var ctx = canvas.getContext("2d");

        // 첫 번째 직사각형 생성
        ctx.fillStyle = "rgb(200,0,0)"; // 투명도 0%의 빨간색
        ctx.fillRect (10, 10, 50, 50); // 좌표(x,y) (10,10) : 크기(width,height) (50,50)

        // 두 번째 직사각형 생성
        ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; // 투명도 50%의 파란색
        ctx.fillRect (30, 30, 50, 50); // 좌표(x,y) (30,30) : 크기(width,height) (50,50)
    }
    </script>
</head>
<!-- 문서 로딩 완료 시 draw 함수 호출 -->
<body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
</body>
</html>

 

  • 실행 화면


예제2 - 원하는 위치에 직선 그리기

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script>
        // 캔버스 인스턴스
        let canvas;

        // 캔버스를 2D 컨텍스트로 설정
        let context;

        // 직선을 구분짓기 위한 카운터 변수
        let clickCount = 0;

        // 직선을 그리기 위한 X, Y축 좌표와 저장
        let x, y;
        let points = [];

        window.onload = function() {
            // 캔버스 객체 생성 및 설정
            canvas = document.getElementById("myCanvas");
            context = canvas.getContext("2d");

            // 캔버스 클릭 이벤트 리스너 정의
            canvas.addEventListener("click", drawCanvas);
        }

        // 캔버스 클릭 이벤트 리스너
        function drawCanvas(event) {
            // 클릭된 위치의 x, y 좌표 확인
            const rect = canvas.getBoundingClientRect();
            x = event.clientX - rect.left;
            y = event.clientY - rect.top;
            
            // 클릭한 위치의 좌표 저장
            points.push({ x, y });
            
            // 클릭수가 짝수일 경우 직선 그리기
            if (clickCount % 2 == 1) {
                drawLine(points[clickCount-1], points[clickCount]);
            }

            // 클릭 시 클릭 카운터 변수 1씩 증가 (짝수 클릭 확인을 위함)
            clickCount++;
        }

        // 캔버스의 직선 그리기
        function drawLine(point1, point2) {
            // 패스 그리기 초기화
            context.beginPath();
            // 시작점 설정
            context.moveTo(point1.x, point1.y);
            // 끝점 설정
            context.lineTo(point2.x, point2.y);
            // 시작점과 끝점의 경로를 따라 선 그리기
            context.stroke();
        }
    </script>
</head>
<body>
    <canvas id="myCanvas" width="600px" height="300px" style="border: 1px dotted red;"></canvas>
</body>
</html>

 

  • 실행 화면
    • 홀수 클릭 : 직선의 시작점
    • 짝수 클릭 : 직선의 끝점
    • 매 짝수 클릭마다 직선이 그려지는 캔버스


+ 벡터로 직선 그리기

  • Body 부분에 벡터를 표현할 svg 요소 생성
  • 캔버스에 그린 직선을 svg 요소에 표현
  • 캔버스 요소와 svg 요소를 겹쳐야 원하는 위치에 직선이 그려지므로 position 설정
<body>
    <div>
        <svg id="mySvg" width="600px" height="300px" style="position:absolute;">
            <line x1="10" x2="50" y1="110" y2="150" stroke="orange" stroke-width="5"/>
        </svg>
        
        <canvas id="myCanvas" width="600px" height="300px" style="position:relative; border:1px dotted red;"></canvas>
    </div>
</body>

 

  • drawLine 함수 수정
  • 나머지 소스 코드는 위의 코드와 같음
// 캔버스의 직선 그리기
function drawLine(point1, point2) {
	// 캔버스에 그린 직선을 벡터 직선으로 생성
    const svg = document.getElementById("mySvg");
    const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
    line.setAttribute("x1", point1.x);
    line.setAttribute("x2", point2.x);
    line.setAttribute("y1", point1.y);
    line.setAttribute("y2", point2.y);
    line.setAttribute("stroke", "black");
    line.setAttribute("stroke-width", "5")
    svg.appendChild(line);
}

 


참고

반응형