HTML5 Canvas 的随机剪裁

Random cutouts with HTML5 Canvas

我想做的就是通过 HTML Canvas 元素获得随机切口(不同形状)。

在页面上我有一个 DIV,在它上面我有 canvas 元素。到目前为止,我已经能够为元素着色并剪下第一块(不是随机的),然后 wipe/clean 再次 canvas ,但是当我多次尝试做完全相同的事情时,它行不通:/

这是半成品的例子:http://plnkr.co/edit/a5UAutd2jNgHMTtPMsp4

    var cutThatOut = function(coords) {

      ctx.fillStyle = "rgba(0,0,0,1)";
      ctx.globalCompositeOperation = "destination-out";

      coords.forEach(function(coord, i){
        if (i==0) {
          ctx.moveTo(coord.x, coord.y);
        } else {
          ctx.lineTo(coord.x, coord.y);
        }
      });
      ctx.fill();
    }

感谢您的time/help

几个修复:

  • 使用 ctx.beginPath 开始您的新路径命令集。否则,您以前的绘图命令集将与最新的一组一起重复。

  • 确保在 cutThatOut 结束时重置合成。否则你的下一个 fillRect(0,0,c.width,c.height) 将 "erase" 整个 canvas 因为它仍在使用 'destination-out'.

  • 如果你想在每次调用 cutThatOut 时做一个全新的剪切,然后在 cutThatOut

  • 的开始用黑色重新填充 canvas

请注意:您的随机坐标通常会导致多边形的边相交,并且通常会延伸到 canvas 的边界之外。

这是示例代码和演示:

var c = document.getElementById("canvas");
var ctx = c.getContext('2d');

var cutThatOut = function(coords) {

  ctx.fillStyle = "black";
  ctx.fillRect(0,0,c.width, c.height);

  ctx.fillStyle = "rgba(0,0,0,1)";
  ctx.globalCompositeOperation = "destination-out";

  ctx.beginPath();
  coords.forEach(function(coord, i){
    if (i==0) {
      ctx.moveTo(coord.x, coord.y);
    } else {
      ctx.lineTo(coord.x, coord.y);
    }
  });
  ctx.fill();

  ctx.globalCompositeOperation = "source-over";

}

var wipeIt = function() {
  ctx.clearRect(0,0,c.width,c.height);
}

var getRand = function(min, max) {return Math.round(Math.random() * (max - min) + min);}

cutThatOut([
  {x:c.width/2, y:0},
  {x:c.width,y:c.height/2},
  {x:c.width/2,y:c.height},
  {x:0, y:c.height/2}
]);

$("#btn").on("click", function(){
  wipeIt();
  cutThatOut([
    {x:getRand(1,200), y:getRand(1,200)},
    {x:getRand(1,200), y:getRand(1,200)},
    {x:getRand(1,200), y:getRand(1,200)},
    {x:getRand(1,200), y:getRand(1,200)}
  ]);
});
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
.adiv {
  width: 200px;
  height: 200px;
  background-color: yellow;
  position: relative;
}
#canvas {
  width: 200px;
  height: 200px;
  position:absolute;
}        
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="adiv">
  <canvas id="canvas"></canvas>
</div>
<p>
  <button id="btn">NEXT!</button>
</p>