복잡하고 계층화 된 그림을 그리는 경우 globalCompositeOperation을 사용하여 두 번째 스크래치 캔버스에서 클리핑을 에뮬레이트 할 수 있습니다. 그런 다음 drawImage를 사용하여 스크래치 캔버스를 원래 캔버스로 다시 복사 할 수 있습니다. 이 방법의 성능을 보장 할 수는 없지만 원하는 결과를 얻으려면 내가 아는 유일한 방법입니다.
//set-up - probably only needs to be done once
var scratchCanvas = document.createElement('canvas');
scratchCanvas.width = 100;
scratchCanvas.height = 100;
var scratchCtx = scratchCanvas.getContext('2d');
//drawing code
scratchCtx.clearRect(0, 0, scratchCanvas.width, scratchCanvas.height);
scratchCtx.globalCompositeOperation = 'source-over'; //default
//Do whatever drawing you want. In your case, draw your image.
scratchCtx.drawImage(imageToCrop, ...);
//As long as we can represent our clipping region as a single path,
//we can perform our clipping by using a non-default composite operation.
//You can think of destination-in as "write alpha". It will not touch
//the color channel of the canvas, but will replace the alpha channel.
//(Actually, it will multiply the already drawn alpha with the alpha
//currently being drawn - meaning that things look good where two anti-
//aliased pixels overlap.)
//
//If you can't represent the clipping region as a single path, you can
//always draw your clip shape into yet another scratch canvas.
scratchCtx.fillStyle = '#fff'; //color doesn't matter, but we want full opacity
scratchCtx.globalCompositeOperation = 'destination-in';
scratchCtx.beginPath();
scratchCtx.arc(50, 50, 50, 0, 2 * Math.PI, true);
scratchCtx.closePath();
scratchCtx.fill();
//Now that we have a nice, cropped image, we can draw it in our
//actual canvas. We can even draw it over top existing pixels, and
//everything will look great!
ctx.drawImage(scratchCanvas, ...);
우리가 스크래치 캔버스에서이 작업을 수행하는 이유는 destination-in이 꽤 파괴적인 작업이라는 것입니다. 이미 배경에 멋진 그라디언트를 넣은 다음 주름 잡은 이미지를 그리기 위해 주 캔버스에 일부 작업을 이미 수행 한 경우 클리핑 원이 사용자가 이미 그린 모든 것을 잘라냅니다. 물론, 특정 상황이 더 간단하다면 (아마도 여러분이 그리려는 모든 것이 잘린 이미지입니다), 그러면 여러분은 스크래치 캔버스를 포기할 수 있습니다.
my demo page에서 다른 클리핑 모드로 재생할 수 있습니다. 맨 아래 행 (그라디언트 포함)은 너에게별로 유용하지 않지만 맨 위 행 (원과 사각형 포함)은 훨씬 더 적합합니다.
편집
으악, 내가 실수로 forked your JSFiddle 기술을 설명합니다.
이 문제도 발생했습니다. 내가 한 것은 반경이 1 ~ 2 배 큰 이미지와 동일한 위치에 원을 그리는 것입니다. 색상을 비슷하게 유지하고 "안티 앨리어싱 된"이미지 클립을 놓습니다. – Automatico