LHJ

I'm a FE developer.

5. 애플 웹사이트 따라하기 - study 공유 1

23 Aug 2020 » js_interaction

canvas

  • 왜 canvas 태그를 사용해야될까?
    요새는 다양한 인터렉션이 구현되어있는 웹페이지가 인기가 많다.
    대표적으로 애플 사이트가 있다.

    위 에어팟프로 사이트를 보면 이미지, 비디오 화질이 엄청 고화질이다.
    고화질임에도 부구하고 스크롤에 따른 애니메이션 효과가 자연스럽다.
    비록 위 애플 사이트도 IE에선 인터렉션이 들어가있지 않은 정적 페이지로 움직이지만, 마이크로소프트에서 내년부터 완전히 IE를 버린다고 했으니 큰 상관 없다.

    다시 본론으로 돌아가면, 화질이 높은데도 불구하고 인터렉션이 자연스럽다.
    이른 canvas 태그를 활용하여 처리할 수 있다는 것이다.

  • canvas란?
    canvas 태그란 쉽게 말해 그림을 그릴 수 있는 태그라 생각하면 된다.
    canvas 태그 안에서 자바스크립트로 그림을 그리는 형식이다.
    canvas 태그는 IE9까지 지원한다.

    canvas 태그는 API 자체가 저수준이다. (이를 추상화가 잘 안됐다라고도 말한다.)
    API가 저수준이라는 말은 쉽게 말해 개발자가 사용하기 어렵다 또는 귀찮다라고 이해하면 된다.

    예를들어 제이쿼리 라이브러리를 생각하면 된다.
    제이쿼리라는 라이브러리를 사용 안하고 자바스크립트로만 스크립트를 작성한다면?
    모던 브라우저는 호환성이 좋아 그나마 괜찮지만 과거 브라우저까지 다 맞춰야된다면 엄청 고생할 것이다.
    하지만 제이쿼리는 이를 쉽게해준다.

    마찬가지로 canvas 태그에 그림을 쉽게 그리게 해주는 라이브러리도 많다.
    하지만 이번 interaction 관련 자바스크립트 스터디는 하드하게 모든걸 ‘직접’ 작성하면서 원리를 이해해보려는 스터디이기에 라이브러리는 사용하지 않도록 하겠다.

  • canvas 그림그리는 원리 1) 도화지
    그림을 그리기 전엔 도화지가 필요하다.
    도화지가 없다면 그림을 그릴 수 없다.
    이 도화지를 처음에 설정해주어야 한다.

      <canvas id="canvas" width="150" height="150"></canvas>
      <script >
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext('2d');
      </script>
    

    위와 같이 설정하면 내가 그림그릴 도화지를 설정한 것이다.
    canvas 태그를 html에 선언해주고, 자바스크립트로 해당 canvas 태그르 선택한 후에 이 canvas 태그는 2d로 랜더링할거야, 라고 선언해주면 된다.

    canvas는 이미지와 똑같은 비트맵 형식이라고 한다.
    때문에 레티나 모니터 대응하는 것처럼 똑같이 canvas 태그도 2배수, 3배수로 적용하는 것이 가능하다고 한다.
    (canvas 태그 안에서 SVG 처럼 만들어주는 Path2D 객체도 있다. 이는 나중에 살펴보도록 하겠다.) canvas 태그의 width, height 값을 크게 주고 실제로 적용되는 width, height 값을 반으로 주면 레티나 대응 이미지처럼 적용이 된다고 한다.
    이것이 화질 좋은 이미지와 비디오를 처리하는 방법 중 하나이다.

  • canvas 그림그리는 원리 2) 손과 펜
    ‘손’이랑 ‘펜’을 생각하면 된다.
    ‘손’으로 ‘펜’을 쥐어 어떤 그림을 그린다고 생각한다면,

    1. 손으로 펜을 든다.
    2. 펜을 들어 처음 시작점에 펜을 댄다.
    3. 그리고 선을 긋는다.
    4. 다시 손으로 펜을 든다.
    5. 다시 시작할 위치에 펜을 댄다.
    6. 그리고 선을 긋는다.
    7. 다시 손으로 펜을 든다. …

    위 동작의 연속일 것이다.

    canvas 태그에 그림그리는 원리도 마찬가지이다.
    시작점으로 펜을 옮긴다. moveTo 메서드.. ctx.moveTo()
    선을 긋는다. lineTo 메서드.. ctx.lineTo()

    등등..

    이런 메서드들은

    해당 mdn 문서를 읽어보면 자세히 알 수 있을 것이다.
    메서드들이 여러개 있긴 하지만 모든 원리는 위와 같다.

  • canvas 그림그리는 원리 3) 도화지 움직임
    펜을 들어서 옮기고 선을 긋는 동작만 있으면 충분할까?
    아니다. 그림을 그리는 도화지를 상황에 맞게 옮겨야 된다.
    그림그릴 때 도화지는 아예 고정시킨채 그릴 때도 있지만 경우에 따라선 도화지를 이동시키면서 그리고 회전시키면서 그림을 그리는 것이 더 편할 때가 있다.

    즉, 도화지를 이동시키거나, 회전시키거나, 확대 축소하는 메서드들이 canvas API에도 있다.

  1. 코드다운 면모 : save, restor
    canvas 태그는 코드답게 일반 도화지에선 가질 수 없는 기능을 갖고 있다.
    옛날 비디오 게임을 생각해보면 된다.
    비디오 게임엔 저장기능이 있었고 원할 때 저장된 시점을 불러올 수 있었다.
    canvas에도 이런 저장기능이 있다.
    저장이란 말 그대로 그 상태를 ‘저장’하는 것이다.

canvas의 현상황, 상태를 저장하는 메서드는 save이다.
현재 내가 검은색 펜으로 테두리를 그렸다고 치자. - 이를 save 메서드로 저장한다.
그리고 그 다음엔 파랑색 펜으로 다른 도형을 그렸다. - 이를 또 save 메서드로 저장한다.

그렇다면 이 상태를 저장한 저장소엔 다음과 같이 저장되어있다.

두번째, save() - 파랑색
첫번째, save() - 검은색 펜

그리고 restore 메서드를 활용하면 마지막 save 시점부터 꺼내올 수 있다.
위의 두개를 저장한 상태에서 이번엔 빨간색 펜으로 그림을 그리고 있다.
그러다 restore 메서드를 사용하면, 내 펜은 파랑색 펜으로 바뀌어있고 저장소엔

첫번째, save() - 검은색 펜

만 남아있다.
다시 restore 메서드를 사용하면 내 펜은 파랑색 펜에서 검은색 펜으로 바뀐다.

위의 예로는 saverestore이 왜 필요한지 안 와닿을거다.
하지만 저장해야되는 상태가 엄청 많다면, 위 기능은 유용할 것이다.