DOM/Canvas

1-7. 도형 합성 - Canvas API | MDN

AGAL 2021. 3. 23. 16:26
반응형

 

이전의 모든 예제에서 도형은 항상 다른 것 위에 그려졌습니다. 대부분의 상황에 적합하지만 도형이 합성되는 순서를 제한합니다. globalCompositeOperation 속성을 설정하여 이러한 동작을 변경할 수 있습니다. 또한 clip 속성을 사용하면 원하지 않는 모양 부분을 숨길 수 있습니다.

 

 

globalCompositeOperation

기존 도형 뒤에 새로운 도형을 그릴 수 있을 뿐만 아니라, 특정 영역을 가리고 캔버스의 특정 부분을 지우는 데 사용할 수 있습니다. (clearRect() 메소드처럼 직사각형에 국한되지 않음)

 

  • globalCompositeOperation = type
    새로운 도형을 그릴 때, 도형 합성 방법을 설정합니다. type은 다음 26종류의 합성 방법 중에서 선택할 수 있습니다.

 

아래의 도형 합성 예제를 참조하세요

 

 

 

잘라내기 경로(Clipping path)

잘라내기 경로는 다른 캔버스 도형과 비슷하지만, 다른 도형에서 원하지 않는 부분을 가리는 가면과 같은 역할을 합니다. 오른쪽에 있는 그림을 보면 어떤 역할을 하는지 알 수 있을 것입니다. 붉은 별 모양이 잘라내기 경로입니다. 이 경로 밖에 있는 모든 것은 캔버스에 그려지지 않을 것입니다.

 

잘라내기 경로와 위에서 살펴본  globalCompositeOperation 속성을 비교해 보면,   source-in과 source-atop에서 비슷한 효과가 보입니다. 이들과 잘라내기 경로와의 가장 중요한 차이점은, 잘라내기 경로 자체는 캔버스에 전혀 그려지지 않는다는 것입니다. 잘라내기 경로는 제한된 영역 안에서 여러 가지 도형을 그리는 데에 적합합니다.

 

캔버스에 도형 그리기에서는 stroke()과 fill() 메소드만을 설명했었는데, clip()이라는 세 번째 메소드도 있습니다.

 

  • clip()
    현재 그려지는 경로를 현재 잘라내기 경로로 만듭니다.

 

경로를 닫기 위해 closePath() 대신 clip()을 사용하고, 경로를 채우거나 윤곽선을 만드는 대신 잘라내기 경로로 만들 수 있습니다.

 

<canvas> 요소의 초기 설정값으로써, 캔버스는 캔버스와 똑같은 크기의 잘라내기 경로를 가집니다. 크기가 똑같기 때문에 잘라내기 효과는 나타나지 않습니다.

 

clip 예제

다음 예제에서는 특정 영역의 별들만 보이도록 동그란 모양의 잘라내기 경로를 사용할 것입니다.

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  ctx.fillRect(0,0,150,150);
  ctx.translate(75,75);

  // 동그란 모양의 잘라내기 경로를 생성한다
  ctx.beginPath();
  ctx.arc(0,0,60,0,Math.PI*2,true);
  ctx.clip();

  // 배경을 그린다
  var lingrad = ctx.createLinearGradient(0,-75,0,75);
  lingrad.addColorStop(0, '#232256');
  lingrad.addColorStop(1, '#143778');

  ctx.fillStyle = lingrad;
  ctx.fillRect(-75,-75,150,150);

  // 별을 그린다
  for (var j=1;j<50;j++){
    ctx.save();
    ctx.fillStyle = '#fff';
    ctx.translate(75-Math.floor(Math.random()*150),
                  75-Math.floor(Math.random()*150));
    drawStar(ctx,Math.floor(Math.random()*4)+2);
    ctx.restore();
  }

}

function drawStar(ctx,r){
  ctx.save();
  ctx.beginPath()
  ctx.moveTo(r,0);
  for (var i=0;i<9;i++){
    ctx.rotate(Math.PI/5);
    if(i%2 == 0) {
      ctx.lineTo((r/0.525731)*0.200811,0);
    } else {
      ctx.lineTo(r,0);
    }
  }
  ctx.closePath();
  ctx.fill();
  ctx.restore();
}

코드의 위쪽 몇 줄에서는 배경으로 캔버스 크기와 같은 검은색 네모를 그리고, 가운데로 원점을 옮깁니다. 그런 다음 호를 그리고 clip()을 사용하여 동그란 모양의 잘라내기 경로를 생성합니다. 캔버스 상태를 저장할 때 잘라내기 경로도 같이 저장됩니다. 이전의 잘라내기 경로를 보존하려면, 새로운 잘라내기 경로를 만들기 전에 캔버스 상태를 저장하면 됩니다.

 

잘라내기 경로를 만든 후에 그려지는 모든 것들은, 그 경로의 안쪽에서만 보입니다. 이는 그 다음에 그려지는 선형 그라디언트에서 확실히 볼 수 있습니다. 이렇게 하고 나서, drawStar() 함수를 사용하여 위치와 크기가 모두 다른 50개의 별을 그립니다. 이 별들은 잘라내기 경로 안쪽에만 나타납니다.

반응형