앞서의 예제는

Canvas에서 두가지 방법으로 구현해 보았다.

여기에서는 Canvas 대신에

SVG (Scalable Vector Graphics)를 이용하여 구현한다.

SVG 장점이나 문법은 알고 있다는 전제로 정리한다.


SVG로 구현하기 전에

삼각함수로 구현한 코드

다음 코드와 같이 변경 작업을 진행해야 한다.

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var center = canvas.height / 2;
//ctx.translate(radius, radius);
var radius = center * 0.90
drawClock();

function drawClock() {
  drawFace(ctx, radius);
  drawNumbers(ctx, radius);
  drawTime(ctx, radius);
}

function drawFace(ctx, radius) {
  var grad;
  ctx.beginPath();
  ctx.arc(center, center, radius, 0, 2*Math.PI);
  ctx.fillStyle = 'white';
  ctx.fill();
  grad = ctx.createRadialGradient(center,center,radius*0.95, center,center,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(center, center, radius*0.1, 0, 2*Math.PI);
  ctx.fillStyle = '#333';
  ctx.fill();
}

function drawNumbers(ctx, radius) {
    ctx.font = radius*0.15 + "px arial";
    ctx.textBaseline="middle";
    ctx.textAlign="center";
 
    var pos = radius*0.85;
    for (var num = 1; num < 13; num++) {
        var x = pos * Math.cos(Math.PI* ((30 * num)-90)/ 180);
        var y = pos * Math.sin(Math.PI* ((30 * num)-90)/ 180);

        ctx.fillText(num.toString(), x+center, y+center);
    }
}

function drawTime(ctx, radius){
    var now = new Date();
    var hour = now.getHours();
    var minute = now.getMinutes();
    var second = now.getSeconds();
    var pos = radius*0.5;
   
    //hour
    x = pos* Math.cos(Math.PI* ((hour*30)- 90 + 30/60*minute + 30/60/60*second) / 180);
    y = pos* Math.sin(Math.PI* ((hour*30)- 90 + 30/60*minute + 30/60/60*second) / 180);
    drawHand(ctx, x, y, radius*0.07);
   
    //minute
    pos = radius*0.8;
    x = pos * Math.cos(Math.PI* ((minute * 6)- 90 + 6/60*second)/ 180);
    y = pos * Math.sin(Math.PI* ((minute * 6)- 90 + 6/60*second)/ 180);
    drawHand(ctx, x, y, radius*0.07);
   
    // second
    pos = radius*0.9;
    x = pos * Math.cos(Math.PI* ((second * 6)- 90)/ 180);
    y = pos * Math.sin(Math.PI* ((second * 6)- 90)/ 180);
    drawHand(ctx, x, y, radius*0.02);
}

function drawHand(ctx, x, y, width) {
    ctx.beginPath();
    ctx.lineWidth = width;
    ctx.lineCap = "round";
    ctx.moveTo(center,center);
    ctx.lineTo(x+center, y+center);
    ctx.stroke();
}

clock1.html

삼각함수로 구현한 코드와 차이는

translate(radius, radius)로 기준점을 화면(canvas) 중앙으로 하지 않고

원래 기준점(화면의 좌측 상단)을 유지하는 것이다.

이전 코드에서는 화면 중앙을 기준으로 했기 때문에

대부분의 좌표가 0 이었다.

좌측 상단이 0 이 되면,

도형을 그릴 위치를 지정해야 한다.


예로, 시계 외곽선을 그리기 위해

arc를 호출한다.

화면 중앙을 기준으로 할 경우

0,0 에서 반지름 만큼 그리도록 호출하면 된다 (arc(0,0,radious)).

좌측 상단을 기준으로 하면

화면 중앙에서 반지름 만큼 그리도록 호출하면 된다 (arc(center,center,radious)).

따라서 위 코드에서 보는 것 처럼 center 변수를 추가하였다.


이렇게 작성하는 것이 

책이나 인터넷 자료에서 가장 흔하게 보는 일반적인 코드 작성법이고

SVG를 좀더 쉽게 사용할 수 있어서 코드를 수정하였다.



+ Recent posts