삼각함수로 구현한 예제를 (SVG I)

앞서 정리한 코드로 (SVG II)

다시 작성하면 다음과 같다.

clock4.html

먼저 CSS 클래스를 3개 작성하였다.

시계 구조(face), 시간(number), 시계 바늘(hands)에 대한

고정된 디자인 값을 가지고 있다 [라인 2 ~ 15].


drawFace에서 두 개의 원(circle)을

createElement로 간단하게 생성하였다.

하나는 시계의 외곽선 [라인 34],

나머지는 시계의 중심을 그리는 원이다 [라인 35].

외곽선은 CSS 클래스를 이용하였고(face)

중심 원은 검은색(#000)으로 채웠다.


시간 표시는 (drawNumbers)

글자를 출력하던 것을 (fillText)

Text 태그를 생성하여 구현한다 [라인 44].

Text 태그에 글자를 넣기 위해

createTextNode를 이용하는 불편함이 있다 [라인 46].


마지막으로

시계 바늘은 선을 그리던 것을 (lineTo)

라인(line) 태그를 생성하였다 [라인 76].


정리하면

Canvas에서는 필요한 도형을 함수를 이용하여 그렸고

SVG에서는 필요한 도형을 태그로 생성했다.

그리고, CSS로 디자인 부분을 분리하였다.


이상의 내용을 타이머를 이용하여

시계처럼 실행하면 문제가 생길 수 있다.

Canvas에서는

타이머가 1초마다 drawClock 함수를 호출하여

시계 구조, 시간, 시계 바늘을

모두 다시 그리기 때문에 중복 되어 실행해도 문제가 없다.


SVG에서는 모두 태그로 생성하게 되는데

1초마다 모든 것을 새로 생성하면

무한대로 계속 생성하기 때문에 여러가지 문제가 생기게 된다.

따라서, 시계 구조, 시간, 시계 바늘을 한 번 생성한 후,

매 초마다 시계 바늘의 위치만 바꾸는 방식으로 구현해야 한다.

var clock = document.getElementById('clock');
var center = parseInt(clock.style.height) / 2;
var radius = center * 0.90;

drawFace(radius);
drawNumbers(radius);

var hourHand = drawHand(0, 0, radius*0.07);
var minuteHand = drawHand(0, 0, radius*0.07);
var secondHand = drawHand(0, 0, radius*0.02);

drawClock();

function drawClock() {
    drawTime(radius);
    setTimeout(drawClock, 1000);
}

~~생략 ~~

function drawTime(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);
    setAttributes(hourHand, {"x1": center, "y1": center, "x2": x+center, "y2": y+center});

    //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);
    setAttributes(minuteHand, {"x1": center, "y1": center, "x2": x+center, "y2": y+center});
   
    // 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);
    setAttributes(secondHand, {"x1": center, "y1": center, "x2": x+center, "y2": y+center});
}

~~생략 ~~

function setAttributes(ele, attributes) {
    for (var item in attributes) ele.setAttribute(item, attributes[item]);
}

clock5.html

drawClock 함수에서 생성하던 것을

모두 함수의 밖(앞)으로 빼서 한번만 실행되도록 하고

타이머가 drawClock를 매초마다 실행하게 작성한다.


새로 작성한 setAttributes는

Json의 값(도형들의 속성)을 주어진 개수만큼 반복해서

도형에 속성들을 부여하는 역할을 하는 함수이다.


이 함수를 (setAttributes)

시계 바늘을 생성하던 drawHand 함수 대신 사용했다.

즉, 생성하는 것이(drawHand) 아닌

속성을 바꾸는 것으로 작성한 것(setAttributes)이다.

속성을 바꾸기 위해

시계 바늘을 시, 분, 초로 구별하여 알아야 하기 때문에

생성 후 변수(hourHand, minuteHand, secondHand)로 받아서 사용한다.


 


+ Recent posts