HTML画布剪辑路径是包含还是独占?

时间:2017-07-05 04:35:09

标签: html canvas clipping image-clipping

我一直在为我们的CQC家庭自动化平台开发基于打字稿的触摸屏客户端,并遇到了奇怪的事情。有很多地方可以在图像上分层各种图形元素。在更新屏幕的某个区域时,我设置了一个剪辑区域并进行更新。

但是我总是围绕着一切都围绕一条线,这是图像背后的底层颜色填充的颜色。我当然责备自己。但是,最后,我做了一个小测试计划,而不是自杀。

似乎表明drawImage()不包含剪辑路径边界,而颜色填充则包含剪辑路径边界。因此,对于我正在更新的区域的图像部分进行blitting并不会完全填满目标区域,在该区域周围留下一条线。

在那个简单的程序演示了这个问题之后,我回过头来进行图像更新,我把剪辑区域一个一个地夸大了,但是把它留给其他所有东西,现在一切正常。我在Chrome和Edge中对此进行了测试,以确保它不是一些错误,并且它们的行为完全相同。

奇怪的是,我从未在文档中看到任何关于剪辑路径是排他性还是包含边界的声明,但肯定不应该是一种原始方式和另一种原始方式,正确?

function drawRect(ctx, x, y, w, h) {
    ctx.moveTo(x, y);
    ctx.lineTo(x + w, y);
    ctx.lineTo(x + w, y + h);
    ctx.lineTo(x, y + h);
    ctx.lineTo(x, y);
}

function init()
{
    var canvas = document.getElementById("output");
    canvas.style.width = 480;
    canvas.style.height = 480;
    canvas.width = 480;
    canvas.height = 480;

    var drawCtx = canvas.getContext("2d");
    drawCtx.translate(0.5, 0.5);

    var img = new Image();
    img.src = "test.jpg";
    img.onload = function() {

        // DRaw the image
        drawCtx.drawImage(img, 0, 0);

        // SEt a clip path
        drawCtx.beginPath();
        drawRect(drawCtx, 10, 10, 200, 200);
        drawCtx.clip();

        // Fill the whole area, which fills the clip area
        drawCtx.fillStyle = "black";
        drawCtx.fillRect(0, 0, 480, 480);

        // Draw the image again, which should fill the area
        drawCtx.drawImage(img, 0, 0);

        // But it ends up with a black line around it
    }
}

window.addEventListener("load", init, false);

1 个答案:

答案 0 :(得分:1)

我认为他们的行为相同。

剪辑区域不包含边框,但它们可以使用抗锯齿。

Chrome没有使用这种技术,并且在裁剪时给出锯齿状线条。 (可能他们最近改变了。)

细黑边框是合成操作的副作用。 剪辑区域跨越像素。所以fillRect会在任何地方绘制黑色,但边框将是50%黑色和50%透明,与第一个图像绘制合成。

第二个绘制图像被捕获,在具有50%不透明度的边界处模拟半像素。此时您在剪辑边框处有:

图片100% 黑色填充50% 图像50%

这样会出现一个小的黑色边框。



function drawRect(ctx, x, y, w, h) {
    ctx.moveTo(x, y);
    ctx.lineTo(x, y + h);
    ctx.lineTo(x + w, y + h);
    ctx.lineTo(x + w, y);
    ctx.closePath();
}

function init()
{
    var canvas = document.getElementById("output");
    canvas.style.width = 480;
    canvas.style.height = 480;
    canvas.width = 480;
    canvas.height = 480;

    var drawCtx = canvas.getContext("2d");
    drawCtx.translate(0.5, 0.5);

    var img = new Image();
    img.src = "http://fabricjs.com/assets/printio.png";
    img.onload = function() {

        // DRaw the image
        drawCtx.drawImage(img, 0, 0);

        // SEt a clip path
        drawCtx.beginPath();
        drawRect(drawCtx, 10, 10, 200, 200);
        drawCtx.clip();

        // Fill the whole area, which fills the clip area
        drawCtx.fillStyle = "black";
        drawCtx.fillRect(0, 0, 480, 480);

        // Draw the image again, which should fill the area
        drawCtx.drawImage(img, 0, 0);

        // But it ends up with a black line around it
    }
}

init();

<canvas id="output" />
&#13;
&#13;
&#13;

相关问题