Canvas 'Clip' reverse action?

旧城冷巷雨未停 提交于 2019-12-05 06:12:30

I understand you asked this a while ago but I have an answer for you.

Your first example was half-correct. Using destination-out will work, however in order not to disturb the canvas you want to draw on, we create a new canvas and draw it in that.

Then once we've drawn our shape on there with our cutaways, we then draw the entire canvas onto the original. Since the new canvas has no background it will keep transparency.

var canvas = document.getElementById('test'),
    context = canvas.getContext('2d'),

    // New canvas - we will draw the letter P on here
    newCanvas = document.createElement('canvas'),
    newContext = newCanvas.getContext('2d');

// Make sure you have enough room on your new canvas
newCanvas.width = canvas.width;
newCanvas.height = canvas.height;

with(newContext) {
    // 'P'
    beginPath();
    moveTo(90,89);
    lineTo(161,89);
    quadraticCurveTo(200,89,200,127);
    quadraticCurveTo(200,166,148,166);
    lineTo(115,166);
    lineTo(108,210);
    lineTo(69,210);
    lineTo(90,89);
    fillStyle = "#eee";
    fill();
    closePath();

    globalCompositeOperation = 'destination-out';

    // 'P' hole
    beginPath();
    moveTo(124,117);
    lineTo(146,117);
    quadraticCurveTo(160,117,160,127);
    quadraticCurveTo(160,145,146,145);
    lineTo(120,145);
    lineTo(124,117);
    fillStyle = '#000';
    fill();
    closePath();
}

with(context) {
    // Background
    fillStyle = '#000';
    fillRect(0,0,300,300);

    // Simply reference the canvas element when drawing
    drawImage(newCanvas, 0, 0);
}

I know this is very old but... you are not using clip correctly in your second try. Everything that comes after clip will be drawn only on the clipped area.

so you could either:

  • Clip the hole and redraw the background

var context = document.getElementById('test').getContext('2d');

// Background
context.fillStyle = '#000';
context.fillRect(0,0,300,300);


// 'P'
context.beginPath();
context.moveTo(90,89);
context.lineTo(161,89);
context.quadraticCurveTo(200,89,200,127);
context.quadraticCurveTo(200,166,148,166);
context.lineTo(115,166);
context.lineTo(108,210);
context.lineTo(69,210);
context.lineTo(90,89);
context.fillStyle = "#eee";
context.fill();


// 'P' hole clip
context.beginPath();
context.moveTo(124,117);
context.lineTo(146,117);
context.quadraticCurveTo(160,117,160,127);
context.quadraticCurveTo(160,145,146,145);
context.lineTo(120,145);
context.lineTo(124,117);
context.clip();

// Redraw Background in the clipped area
context.fillStyle = '#000';
context.fillRect(0,0,300,300);
<canvas id="test" width="300" height="300">
  • clip the outside part of the hole and draw the P

var context = document.getElementById('test').getContext('2d');

// Background
context.fillStyle = '#000';
context.fillRect(0,0,300,300);

// inverse 'P' hole clip
context.beginPath();
context.rect(0, 0, 300, 300);
context.lineTo(124,117);
context.lineTo(120,145);
context.lineTo(146,145);
context.quadraticCurveTo(160,145,160,127);
context.quadraticCurveTo(160,117,146,117);
context.lineTo(124,117);
context.clip();

// 'P'
context.beginPath();
context.moveTo(90,89);
context.lineTo(161,89);
context.quadraticCurveTo(200,89,200,127);
context.quadraticCurveTo(200,166,148,166);
context.lineTo(115,166);
context.lineTo(108,210);
context.lineTo(69,210);
context.lineTo(90,89);
context.fillStyle = "#eee";
context.fill();
<canvas id="test" width="300" height="300">

Also, you don't need to use closePath here.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!