본문 바로가기

Canvas 기본 파악하기

지난 편에서 벡터 이미지인 SVG를 살펴보았는데, 이때 캔버스 등장으로 웹에 실제 코딩으로 이미지를 구현할 때는 canvas 태그가 더 선호된다고 언급한 바 있다. 이에 이번 장에서는 웹 페이지에 그래픽을 그리는 데 사용하는 canvas 태그를 간략하게 기본만 살펴본다.

 

웹에 Canvas 활용하기

CONTENTS

     

    Canvas 태그란?

    HTML 태그의 하나인 canvas는 그래픽을 그리는 컨테이너에 해당한다. 즉, 껍데기 태그로 실제 그래픽 작업은 자바스크립트를 사용해야 한다. 앞에서 살펴본 svg가 실제로 이미지를 그릴 수 있지만, 자바스크립트로 조작할 수 없는 단점이 존재한다고 밝힌 바 있다. 바로 이 부분 때문에 코드로 이미지를 구현할 때는 canvas 태그가 더 선호된다. 부가적으로 svg는 이미 svg로 만들어진 이미지를 그대로 웹에 넣을 때, 다른 이미지 파일보다 선호된다.

     

    즉, 다른 그래픽 프로그램을 활용해서 이미지를 만들 때 svg 이미지로 제작한 걸 더 선호한다. 하지만 코드로 직접 이미지를 표현할 때는 canvas 태그를 더 선호한다.

     

    캔버스 사용법

    기본적으로 canvas 태그는 id속성을 지정하고 width와 height 속성으로 캔버스 크기를 설계한다. 이후 style 속성을 사용하여 색상이나 보더 등을 추가할 수 있다. 하지만 id 속성을 이용해서 자바스크립트로 이미지 조작을 수행하는 게, 캔버스의 정석 사용법이다.

     

     

    Your browser does not support the HTML canvas tag.

    <canvas id="myCanvas" width="200" height="100" style="border:3px solid #154645; background:#808080;">
    </canvas>

     

    위의 예시처럼 canvas에 스타일을 사용해 보더와 색상을 넣을 수도 있다. 하지만 이건 div 태그를 사용하는 것과 별반 다를 바가 없다. 즉, canvas 태그에 준 id 속성을 사용해 그래픽 이미지를 만드는 데 캔버스 태그가 지닌 의미가 있다.

     

     

     

    <canvas id="vas" width="200" height="100"">
    </canvas>
    <script>
    var canvas = document.getElementById("vas");
    var ctx = canvas.getContext("2d");
    ctx.fillStyle = "#FF0000";
    ctx.fillRect(0, 0, 150, 75);
    </script>

     

    위 코드는 기본적인 캔버스 사용법을 담고 있다. canvas 태그로 캔버스 크기만을 설정하고, 나머지 작업은 id 속성을 활용한다.

    자바스크립트로 id 속성값을 찾아서 변수에 담은 후에, 이 변수에 HTML 내장객체인 getContext()를 사용함을 알린다. 이후 내장객체가 지니고 있는 그리기 속성들을 활용해서 그래픽 이미지 작업을 수행한다.  

     

    캔버스 기본 요약

    HTML5에서 추가한 canvas 태그는 자체적으로 그리기 기능은 없다. 그래픽을 위한 컨테이너 역할만 할 뿐, 실제로 그래픽 작업은 자바스크립트를 사용해야 한다. 이러한 canvas 태그는 내장객체로 getContext()를 지니는데, 이 getContext() 내장객체는 그리기에 필요한 메서드와 속성을 제공한다.

     

    내장객체 getContext()가 지닌 메서드와 속성들 종류만 나열하면 다음과 같다.

     

     

    캔버스 내장객체가 지닌 메서드 및 속성들

     

    위는 W3Schools에서 발췌한 내용이다. 이렇게  다양한 메서드와 속성을 지니고 있어, 캔버스를 활용해서 할 수 있는 대표적인 사레들은 텍스트, 그래픽, 애니메이션, 인터랙티브, 게임 등이 있다. 이렇다보니 다양한 작업에서 캔버스는 그 자체가 또 하나의 API로 대접을 받으며, Canvas 튜토리얼이라는 챕터 단위 학습이 필요할 만큼 알아야 할 분량이 많다. 

     

    MDN 캔버스 튜토리얼 바로가기

     

    캔버스 시계

     

    아래는 캔버스로 제작한 시계이다. 캔버스로 무엇을 할 수 있는지, 그 다양한 사례들 중에 가장 간단한 예에 불과하다.

     

    <canvas id="can" width="400" height="400"
    style="background-color:#333">  </canvas>
    
    <script>
    var can = document.getElementById("can");
    var ctx = can.getContext("2d"); var radius = can.height / 2;
    ctx.translate(radius, radius); radius = radius * 0.90
    setInterval(drawClock, 1000);
    
    function drawClock() { drawFace(ctx, radius);
      drawNumbers(ctx, radius); drawTime(ctx, radius);
    }
    
    function drawFace(ctx, radius) { var grad;
      ctx.beginPath(); ctx.arc(0, 0, radius, 0, 2*Math.PI);
      ctx.fillStyle = 'white';  ctx.fill();
      grad = ctx.createRadialGradient(0,0,radius*0.95, 0,0,radius*1.05);
      grad.addColorStop(0, '#333');  grad.addColorStop(0.5, 'white');
      grad.addColorStop(1, '#333'); ctx.strokeStyle = grad;
      ctx.lineWidth = radius*0.1;  ctx.stroke();
      ctx.beginPath();  ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI);
      ctx.fillStyle = '#333';  ctx.fill();
    }
    
    function drawNumbers(ctx, radius) {
      var ang;  var num;
      ctx.font = radius*0.15 + "px arial";
      ctx.textBaseline="middle"; ctx.textAlign="center";
      for(num = 1; num < 13; num++){
        ang = num * Math.PI / 6;
        ctx.rotate(ang); ctx.translate(0, -radius*0.85);
        ctx.rotate(-ang); ctx.fillText(num.toString(), 0, 0);
        ctx.rotate(ang); ctx.translate(0, radius*0.85);
        ctx.rotate(-ang);
      }
    }
    
    function drawTime(ctx, radius){
        var now = new Date();  var hour = now.getHours();
        var minute = now.getMinutes(); var second = now.getSeconds();
        //hour
        hour=hour%12;  hour=(hour*Math.PI/6)+
        (minute*Math.PI/(6*60))+
        (second*Math.PI/(360*60));
        drawHand(ctx, hour, radius*0.5, radius*0.07);
        //minute
        minute=(minute*Math.PI/30)+(second*Math.PI/(30*60));
        drawHand(ctx, minute, radius*0.8, radius*0.07);
        // second
        second=(second*Math.PI/30);
        drawHand(ctx, second, radius*0.9, radius*0.02);
    }
    
    function drawHand(ctx, pos, length, width) {
        ctx.beginPath();   ctx.lineWidth = width;
        ctx.lineCap = "round";   ctx.moveTo(0,0);
        ctx.rotate(pos);   ctx.lineTo(0, -length);
        ctx.stroke();  ctx.rotate(-pos);
    }
    </script>
    * 위 코드는 w3schools에서 확인할 수 있습니다.