Canvas - 08

이강민·2022년 1월 5일
0

[혼공]Canvas

목록 보기
8/12
post-thumbnail

변형 (transformations)

상태(state)의 저장과 복원

  • save()
    • canvas의 모든 상태를 저장
  • restore()
    • 가장 최근에 저장된 canvas 상태를 복원
      캔버스의 상태는 스택에 쌓인다. save()메소드가 호출될 때 마다 현재 drawing 상태가 스택 위로 푸시된다.
    const ctx = document.getElementById('canvas').getContext('2d');
    
    function draw(){
        //검은색 사각형을 그림
        ctx.fillRect(0,0,150,150)
        //지금까지의 속성 저장 (기본값)
        ctx.save();

        //속성 변경, 파랑색
        ctx.fillStyle = '#09f';
        //파랑생 사각형을 그림
        ctx.fillRect(15,15,120,120)
        //현재까지 속성 저장(파랑색)
        ctx.save();

        //속성변경 흰색
        ctx.fillStyle = '#fff'
        //투명도 설정
        ctx.globalAlpha = 0.5;
        //흰색 투명한 사각형 그림
        ctx.fillRect(30,30,90,90)

        //마직막으로 저장했던 속성값 불러옴. - 파랑색
        ctx.restore();
        //파랑색 사각형을 그림
        ctx.fillRect(45,45,60,60);

        //첫번째로 저장했던 속성값 불러옴 - 검은색
        ctx.restore();
        //검은색 사각형을 불러옴
        ctx.fillRect(60,60,30,30);
    }
    if(document.getElementById('canvas').getContext){
        draw()
    }

이동(translating)

이 메소드는 그리드에서 캔버스를 원점에서 다른 점으로 옮기는데 사용된다.

  • translate(x,y)
    • 그리드에서 canvas와 그 원점을 이동한다. x는 이동시킬 수평거리를 가르키고, y는 그리드에서 수직으로 얼마나 멀리 떨어지는지 표시한다.

변형전에 canvas의 상태를 저장하는 것이 좋다. 대다수의 경우 원래 상태를 되돌리려고 역이동을 시키는 것보다 restore 메소드를 호출하는 것이 간편하다. 만약 루프 안에서 이동하는 거라면 canvas의 상태를 저장하고 복원하지 말아야 한다. canvas 모서리 밖에서 그려지는 바람에 drawing의 일부를 소실되게 된다.

    const ctx = document.getElementById('canvas').getContext('2d');
    
    function draw(){
       for (let i = 0; i < 3; i++) {
           for (let j = 0; j < 3; j++) {
               //초기상태를 저장함
               ctx.save();
               //스타일을 변수 i와 j에 맞추어 변화를 줌
               ctx.fillStyle = `rgb(${51*i}, ${255-51*i}, 255)`;
               //x축 y축 순으로 이동되도록 변수를 할당함.
               ctx.translate(j*50 + 10, i*50+10);
               //사각형을 그림 
               ctx.fillRect(0,0,25,25);
               //초기상태로 되돌림
               ctx.restore()
           }
       }
    }
    if(document.getElementById('canvas').getContext){
        draw()
    }

회전(rotating)

canvas를 현재의 원점 둘레로 회전하는데 사용한다.

  • rotate(angle)
    • canvas를 현재 원점을 기준으로 라디안의 angle숫자 만큼 시계방향으로 회전 시킨다.

회전의 중심은 언제나 canvas원점이다. 중심점을 바꾸려면 translate() 메소를 써서 이동해야한다.

참고
각도의 단위는 도(degree)가 아닌 라디안(radian)입니다. 변환하려면 radians = (Math.PI/180)*degrees.를 사용합니다.

    const ctx = document.getElementById('canvas').getContext('2d');
    const deg = function(deg){
        return (Math.PI/180)*deg
    }

    function draw(){
       //초기 상태를 저장함
      ctx.save();
      //속성 값 설정 - 파랑색
      ctx.fillStyle = '#0095dd';
      //파랑색 사각형을 그림
      ctx.fillRect(30,30,100,100);

      //25도 만큼 회전시킴
      ctx.rotate(deg(25));
      //속성 값 설정 - 회색
      ctx.fillStyle = '#4D4E53';
      //회색 사각형을 그림
      ctx.fillRect(30, 30, 100, 100);

      //초기값으로 설정
      ctx.restore();
      //속성 값 설정 - 파랑색
      ctx.fillStyle = '#0095DD';
      //파랑색 사각형을 그림
      ctx.fillRect(150, 30, 100, 100);

      //그림을 이동시킴, 원래상태로 되돌리지 않고 rotate를 적용하니 rotate는 캔버스를 0,0을 중심으로 회전시킨다는 것을 알 수 있다.
      ctx.translate(200, 80);
      //25도 회전시킴
      ctx.rotate(deg(25));
      //그림의 중심점을 다시 원래대로 이동
      ctx.translate(-200, -80);
      //속성값 설정. 회색
      ctx.fillStyle = '#4D4E53';
      //회색 사각형을 그림
      ctx.fillRect(150, 30, 100, 100);
    }
    if(document.getElementById('canvas').getContext){
        draw()
    }

확대·축소(scaling)

canvas 그리드에서 단위를 키우거나 줄이는 데 사용하고 이는 벡터 모양과 비트맵 요소를 축소하거나 확대해서 그리는 데 사용될 수 있다.

  • scale(x, y)
    • camvas단위를 수평으로 x만큼, 수직으로 y만큼 크기를 확대, 축소한다. 둘의 매개 변수는 실수이다. 1.0보다 작은 값이면 단위의 크기를 축소하고, 1.0보다 큰 값이면 단위의 크기를 확대한다.

음수를 이용해서 축을 대칭 시킬 수 있다(가령 translate(0,canvas.height); scale(1,-1);로 쓰는 것처럼 말이다. 좌측 하단 모서리에 있는 원점을 이용한, 잘 알려진 카르테시안 좌표계(Cartesian coordinate)인 것이다.

    const ctx = document.getElementById('canvas').getContext('2d');
    const deg = function(deg){
        return (Math.PI/180)*deg
    }

    function draw(){
       //초기 상태를 저장함
      ctx.save();
      //스케일을 다음과 같이 설정함
      ctx.scale(10,3);
      //사각형을 그림, 10이 10배, 10이 3배만큼으로 설정됨
      ctx.fillRect(1,10,10,10);

      //기본값으로 되돌림
      ctx.restore();
      //스케일을 설정함
      ctx.scale(1,-1);
      ctx.font = '48px serif';
      //스케일이 음수로 적용되어 음수로 적용된 부분은 대칭으로 보인다.
      ctx.fillText('MDN', 135, -120);
    }
    if(document.getElementById('canvas').getContext){
        draw()
    }

변형(transforms)

변형 메소드들은 변환 행렬로 변경할 사항을 즉시 적용할 수 있다.

  • transform(a, b, c, d, e, f)
    인수(arguments)에 표시된 행렬을 이용해 현재 변환 행렬을 곱한다. 변환 행렬은 다음과 같이 작성된다.
    [
    a c e
    b d f
    0 0 1
    ]

만일 인수 중에 Infinity가 있다면, 변환 행렬은 예외 처리하는 메소드 대신에 반드시 infinite로 표시됨
이 function의 매개 변수들은 다음과 같음

  • a (m11)
    • 수평으로 확대·축소하기
  • b (m12)
    • 수평으로 비스듬히 기울이기
  • c (m21)
    • 수직으로 비스듬히 기울이기
  • d (m22)
    • 수직으로 확대·축소하기
  • e (dx)
    • 수평으로 이동하기
  • f (dy)
    • 수직으로 이동하기
  • setTransform(a, b, c, d, e, f) (en-US)
    • 현재 변형 상태를 단위 행렬로 재설정하고 나서 동일한 인수로 transform() 메소드를 적용한다. 이는 기본적으로 현재의 변형을 무효로 한 후에 명시된 변형으로 바뀌는데, 한번에 모든 게 진행된다.
  • resetTransform() (en-US)
    • 현재 변형 상태를 단위 행렬로 재설정, 이는 ctx.setTransform(1, 0, 0, 1, 0, 0); 호출과 같음.
    const ctx = document.getElementById('canvas').getContext('2d');
    const deg = function(deg){
        return (Math.PI/180)*deg
    }

    function draw(){
     const sin = Math.sin(Math.PI / 6);
     const cos = Math.cos(Math.PI / 6);
     ctx.translate(100,100)
     let c = 0;
    
     for (let i = 0; i <= 12; i++) {
       c = Math.floor(255/12*i);
       ctx.fillStyle = `rgb(${c},${c},${c})`;
       ctx.fillRect(0,0,100,10);
       ctx.transform(cos, sin, -sin, cos, 0, 0);
     }
        ctx.setTransform(-1, 0, 0, 1, 100, 100);
        ctx.fillStyle = 'rgba(255, 128, 255, 0.5)';
        ctx.fillRect(0, 50, 100, 100);

    }
    if(document.getElementById('canvas').getContext){
        draw();
   
profile
배움은 끝없이

0개의 댓글