이전 페이지들에서 나온 모든 예제에서, 새로 그리는 도형은 언제나 이미 그려진 도형의 위에 그려졌습니다. 대부분의 상황에서는 이렇게 하는 것이 적절하지만, 도형을 합성하기 위한 순서를 제한하게 되는데, globalCompositeOperation
속성을 설정함으로써 이러한 상태를 바꿀 수 있습니다.
globalCompositeOperation
기존 도형 뒤에 새로운 도형을 그릴 수 있을 뿐만 아니라, 도형의 일정 영역을 가려 보이지 않게 하거나 캔버스의 특정 부분을 지우는 (clearRect()
메소드는 사각형의 영역만을 지우지만, 이같은 제한도 없다.) 등의 효과를 얻을 수도 있습니다.
-
globalCompositeOperation = type
- 새로운 도형을 그릴 때, 도형 합성 방법의 유형을 설정합니다. type에는 12개의 방법이 있습니다.
알아둘 것: 아래에 나온 모든 예제에서, 파란색 네모는 먼저 그려졌으며, "기존 도형"이라고 부르겠습니다. 붉은색 원은 나중에 그려졌으며, "새 도형"이라고 부르겠습니다.
source-over (초기 설정값) |
destination-over |
||
source-in |
destination-in |
||
source-out |
destination-out |
||
source-atop |
destination-atop |
||
lighter |
darker 기존 도형과 새 도형이 겹치는 부분의 색이 바뀝니다. 바뀌는 색은 두 도형의 색상값을 빼서 결정됩니다. 캔버스 사양에서 제외되었고, 더 이상 지원되지 않습니다. |
||
xor |
copy |
합성 방법 예제에서 코드를 살펴보고, 예제의 출력 결과도 확인해 보세요.
잘라내기 경로(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(); }
<canvas id="canvas" width="150" height="150"></canvas>
draw();
코드 위쪽의 몇줄에서, 캔버스 크기와 같은 검은색 네모를 그리고, 가운데로 원점을 옮긴다. 그리고, 호 그리기와 clip()
을 사용하여 동그란 모양의 잘라내기 경로를 생성한다. 캔버스 상태를 저장할 때 잘라내기 경로도 같이 저장된다. 만약 이전의 잘라내기 경로를 보존하고 싶었다면, 새로운 잘라내기 경로를 만들기 전에 캔버스 상태를 저장했으면 됐을 것이다.
잘라내기 경로를 만든 후에 그려지는 모든 것들은, 그 경로의 안쪽에서만 보인다. 이후 그려지는 선형 그레이디언트에서 분명히 확인해 볼 수 있다. 이렇게 하고 나서 drawStar()
함수를 사용하여, 위치와 크기가 모두 다른 50개의 별이 그려진다. 이 별들은 잘라내기 경로 안쪽에만 나타난다.
Screenshot | Live sample |
---|---|