Web/html & css & xml

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

luvris2 2023. 7. 10. 16:03
반응형

 

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);
}

 


참고

반응형