Javascript 画布2D路径剪辑重叠pr

Javascript 画布2D路径剪辑重叠pr,javascript,canvas,html5-canvas,Javascript,Canvas,Html5 Canvas,我试图在画布中创建一个复合形状,遮罩其下的所有内容-我将设置这些路径的动画,以便它们最终相交-问题是,当它们相交时,当图形重叠时,它们正在进行反向遮罩。我只想要一个结实的面具 let region = new Path2D(); // first line //ctx.transform(1,0,0,1,xShift,yShift); region.moveTo(wdth*(.093+p1x) +

我试图在画布中创建一个复合形状,遮罩其下的所有内容-我将设置这些路径的动画,以便它们最终相交-问题是,当它们相交时,当图形重叠时,它们正在进行反向遮罩。我只想要一个结实的面具

let region = new Path2D();
            
            // first line
            //ctx.transform(1,0,0,1,xShift,yShift);
            region.moveTo(wdth*(.093+p1x) + p1x, ((ht*0)));
            region.lineTo(wdth*(.096+p2x)  + p2x, ((ht*0)));
            region.lineTo(wdth*(.302+p2x)   + p1x, ((ht*1)));
            region.lineTo(wdth*(.299+p1x), ((ht*1)));
    ctx.save();
            //ctx.fill(region);

            //
            ctx.beginPath();
            region.moveTo(wdth*.326, ((ht*1)));
            region.lineTo(wdth*.329, ((ht*1)));
            region.lineTo(wdth*.537, ((ht*0)));
            region.lineTo(wdth*.534, ((ht*0)));
    ctx.save();
            //ctx.fill(region);
            //
    ctx.beginPath();
            region.moveTo(wdth*.680, ((ht*0)));
            region.lineTo(wdth*.683, ((ht*0)));
            region.lineTo(wdth*.464, ((ht*1)));
            region.lineTo(wdth*.461, ((ht*1)));
    ctx.save();
            //ctx.fill(region);
            //
    ctx.beginPath();
            region.moveTo(wdth*.926, ((ht*1)));
            region.lineTo(wdth*.929, ((ht*1)));
            region.lineTo(wdth*.702, ((ht*0)));
            region.lineTo(wdth*.699, ((ht*0)));
            ctx.fill(region);
            //ctx.beginPath();
            //
            ctx.clip(region, "nonzero");
下面是一个示例(如您所见,有一条细线重叠,剪裁不正确-但另一条线剪裁正确):


您应该在一个单独的隐藏缓冲区画布中绘制它,只需填充所有形状-除非重用它,否则不需要Path2D构造函数,但即使如此,也不应该像这样绘制整个形状(由于缠绕算法,某些位不是填充的一部分,但这与此处的遮罩图像不完全相关-此处有更多信息和示例:)

然后使用该缓冲区画布使用
globalCompositeOperation
剪切另一个画布。下面我修改了您的代码片段并删除了构造函数,并直接在缓冲区画布上执行操作

document.addEventListener(“DOMContentLoaded”),函数(事件){
让canvas=document.getElementById('mainmask');
让gradcanvas=document.getElementById('gradmask');
让aWrapper=document.querySelector('.canvas wrap');
设ctx=canvas.getContext('2d');
让ctxGrad=gradcanvas.getContext('2d');
让我们赢={};
让markerShow=false;
//用于重新调整画布的大小
函数setCanvasScalingFactor(){
返回窗口.devicePixelRatio | | 1;
}
函数resizeViaCanvas(){
//获取devicePixelRatio
var pixelRatio=setCanvasScalingFactor();
//视口处于纵向模式,因此“可变宽度”应基于视口宽度
if(window.innerHeight1时,这将用于缩小画布元素的比例
aWrapper.style.width=宽度+px;
aWrapper.style.height=高度+px;
canvas.width=宽度*像素比率;
canvas.height=高度*像素比率;
gradcanvas.width=宽度*像素比率;
gradcanvas.height=高度*像素比率;
}
//遮罩渐变的两种颜色
//设color1=[201237223]
设color1=[5,5,5]
设color2=[22612499]
//各种rgb颜色
let mint=[201237223]
让红色=[239,65,35]
让fadered=[226124,99]
让紫色=[28,16,42]
让米色=[255,236,173]
let peach=[251,199,143]
设scaleAmt=1;
//其中,遮罩是基于tweening scaleAmt绘制的
函数drawMask(){
//每个正方形的长度
var w=数学圆(画布宽度);
var h=数学圆(画布高度);
圆木控制台(宽+高+高)
ctxGrad.clearRect(0,0,canvas.width,canvas.height);
ctxGrad.save();
//ctx.fillStyle=`rgba(239,65,35,${viaAlpha.alpha})`;
ctxGrad.fillStyle=`rgb(“+color1[0]+”、“+color1[1]+”、“+color1[2]+”)`
//
设wdth=w;
设ht=h;
设xShift=0;
设yShift=0;
设p1x=-.1;
设p2x=0.1;
var gradient=ctxGrad.createLinearGradient(0,0,w,0);
gradient.addColorStop(.4,“rgb(“+color1[0]+”,“+color1[1]+”,“+color1[2]+”);
gradient.addColorStop(1,“rgb(“+color2[0]+”,“+color2[1]+”,“+color2[2]+”));
ctxGrad.fillStyle=渐变;
ctxGrad.fillRect(0,0,w,h);
ctxGrad.save();
ctx.beginPath();
ctx.lineWidth=0;
ctx.fillStyle='蓝色';
//一线
//变换(1,0,0,1,x移位,y移位);
ctx.moveTo(wdth*(.093),((ht*0));
ctx.lineTo(wdth*(.096),((ht*0));
ctx.lineTo(wdth*(.302),((ht*1));
ctx.lineTo(wdth*(.299),((ht*1));
ctx.fill();
//ctx.save();
//
ctx.beginPath();
ctx.moveTo(wdth*(.326+p1x),((ht*1));
ctx.lineTo(wdth*(.329+p2x),((ht*1));
ctx.lineTo(wdth*(.537+p2x),((ht*0));
ctx.lineTo(wdth*(.534+p1x),((ht*0));
ctx.fill();
//
ctx.beginPath();
ctx.moveTo(wdth*.680,((ht*0));
ctx.lineTo(wdth*.683,((ht*0));
ctx.lineTo(wdth*.464,((ht*1));
ctx.lineTo(wdth*.461,((ht*1));
ctx.fill();
//
ctx.beginPath();
ctx.moveTo(wdth*.926,((ht*1));
ctx.lineTo(wdth*.929,((ht*1));
ctx.lineTo(wdth*.702,((ht*0));
ctx.lineTo(wdth*.699,((ht*0));
ctx.fill();