【问题标题】:How to clip canvas with CSS clip-path?如何使用 CSS 剪辑路径剪辑画布?
【发布时间】:2013-07-09 18:58:47
【问题描述】:

我知道我可以通过使用getContext('2d') 创建路径并设置globalCompositeOperation 来剪辑画布。

我注意到,有时我可以在其他浏览器(我使用的是 Chrome)上使用 -webkit-clip-path 或 clip-path 剪辑画布,但有时我无法:

使用此 HTML:

<canvas width="300" height="60"></canvas>

和 CSS:

canvas { -webkit-clip-path: polygon(50% 33%, 75% 10%, 80% 80%, 60% 75%, 40% 60%, 20% 10%, 40% 20%, 50% 33%);
}

产生这个:

这似乎是正确的。

但是,我注意到,如果我改变画布的高度,它就无法剪辑:

<canvas width="300" height="250"></canvas>

产生:

我的假设 是,它在浮点上裁剪(百分比在像素之间而不是像素上裁剪)有问题,但是从百分比更改为像素坐标不会裁剪。

*这里分别是他们的jsfiddle页面的链接:

有谁知道为什么一个有效而另一个无效?

是否有一种稳定 的方式来使用 CSS 剪辑画布元素,或者我是否需要使用画布上下文方法?

我问的原因是我想尽可能少用js。我有一串坐标,可以很容易地放入 css;而要使用 ctx.beginPath()...ctx.moveTo()...ctx.lineTo()...ctx.lineTo()... 方法,我需要对这些点执行 for 循环。

另外,我很好奇为什么第一个示例有效,如果有人可以解释的话。谢谢! :)

【问题讨论】:

    标签: javascript css html canvas webkit


    【解决方案1】:

    剪辑路径相对较新,可能容易出错(在 Aurora 中对我不起作用)。

    为了获得稳定的结果,我建议只使用画布的clip() 方法(您不需要为此合成)。

    您可以通过这种方式提供分数(此处为百分比):

    var path = [50, 33, 75, 10, 80, 80, 60, 75, 40, 60, 20, 10, 40, 20, 50, 33];
    

    几乎就像在 CSS 中定义一样简单。然后有一个函数来解析它:

    function addClip(context, path) {
    
        var w = context.canvas.width,
            h = context.canvas.height;
    
        context.beginPath();
        context.moveTo(path[0] * w / 100, path[1] * h / 100);
        for(var i = 2; i < path.length; i+=2) {
            context.lineTo(path[i] * w / 100, path[i+1] * h / 100);
        }
        context.closePath();
        context.clip();
    }
    

    结果:

    DEMO HERE

    (剪辑是在绘制操作发生之前设置的)。

    只需将您的绘图操作放在一个函数中,您也可以在调整窗口大小时调用该函数(如上面的演示所示)。

    更新

    至于抗锯齿:实际上对图像应用了抗锯齿,但由于红色,很难检测到它,具体取决于屏幕类型,也许浏览器。放大版:

    【讨论】:

    • 谢谢肯。这是一个很好的工作示例。我实际上打算避免使用clip() 方法,以便我可以获得具有抗锯齿的多边形(更平滑的边缘,就像 CSS 会给出的那样):jsfiddle.net/bozdoz/TB9rX 知道为什么我的第一个示例有效但其他示例没有?
    • @bozdoz 我只能推测,但这似乎是一个错误。如果在应用剪辑后调整元素大小,则剪辑似乎丢失了。您可以通过使用 JS 重新应用 css-class 来进行测试:document.getElementById('canvas').className = 'canvas';(当然您需要更改 CSS 以便规则为 class)。
    • @bozdoz 关于抗锯齿:试试这条线:context.translate(0.5, 0.5); 更新小提琴:jsfiddle.net/AbdiasSoftware/CmaUy/2(答案中的图像确实有抗锯齿,但红色可能很难根据屏幕类型查看)。
    • 我认为它因浏览器而异:stackoverflow.com/questions/9536257/…
    【解决方案2】:

    我从未使用过-webkit-clip-path:,但作为一种解决方法,我会尝试将剪辑路径应用于包含画布而不是画布本身的元素。

     <div class='canvas-wrapper'><canvas></canvas></div>
    
     .canvas-wrapper {
        display: table;   /* shrinkwrap around canvas */
        -webkit-clip-path: ...;
     }
    

    【讨论】:

      猜你喜欢
      • 2016-09-18
      • 2023-03-11
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 2015-02-22
      • 2015-10-24
      相关资源
      最近更新 更多