Canvas'Clip'反向动作? [英] Canvas 'Clip' reverse action?

查看:333
本文介绍了Canvas'Clip'反向动作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有:

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

//背景
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();
context.closePath();

context.globalCompositeOperation ='destination-out';

//'P'hole
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.fillStyle ='#ffffff';
context.fill();
context.closePath();

这是可行的,除了你可以看到'hole'不是一个剪辑,背景不固定,你根本不能设置孔的'fill'颜色以匹配背景。



因此,我需要剪切孔。然而,当我这样做的时候,P的唯一部分显示是由剪辑孔绑定的部分。我需要相反。我需要'P'显示,但剪辑的部分与'洞',所以任何背景都会显示。



这是我的,但不是相当的:

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

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

//'P'孔夹
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();
context.closePath();

//'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();
context.closePath();感谢您的帮助!


$ b $ p < >解决方案

我知道你以前问过这个问题,但我有一个答案。



你的第一个例子是半正确的。使用destination-out将工作,但为了不打扰你想画的画布,我们创建一个新的画布并绘制它。



然后一旦我们我们用我们的切割绘制我们的形状,然后将整个画布绘制到原件上。由于新的画布没有背景,它将保持透明度。

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

//新画布 - 我们将在这里绘制字母P
newCanvas = document.createElement('canvas'),
newContext = newCanvas.getContext('2d');

//确保你的新画布有足够的空间
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);

//绘制时
只引用canvas元素drawImage(newCanvas,0,0);
}


Assuming I have:

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();
context.closePath();

context.globalCompositeOperation = 'destination-out';

// 'P' hole
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.fillStyle = '#ffffff';
context.fill();
context.closePath();

This works, except as you can see the 'hole' isn't a clip, so if the background isn't solid, you simply can't set the 'fill' color of the hole to match the background.

Therefore I need to clip the hole instead. When I do that however, the only part of the 'P' that shows is the part bound by the clip 'hole'. I need the reverse. I need the 'P' to show, but clip the part with the 'hole' so any background will show through.

Here is as far as I got, but not quite there:

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

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

// '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();
context.closePath();

// '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();
context.closePath();

Thank you for your help!

解决方案

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);
}

这篇关于Canvas'Clip'反向动作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆