画布 - 是否可以仅填充画布上的特定元素?

时间:2017-08-01 18:03:27

标签: javascript canvas

我的中心有一个主圈。在这之外的圆圈总是只是触及主圆圈。外圈可以相互重叠。

外圈可以有任何线宽,对于线宽小于中心圆的外圈,我试图"吃进去"主要圈子。

如果没有重叠的圆圈,我可以设置外圆圈填充,这将在主圆圈吃掉。但是,外圈可以重叠,填充它们可能会破坏其他外圈。

这里有一张图片可以更好地解释: enter image description here

以下是显示上述示例的摘录:



var canvas = document.getElementById("my-canvas"),
    ctx    = canvas.getContext("2d");
    
canvas.width  = $(window).width();
canvas.height = $(window).height();

drawCircle(174, 174, 100, 20);
drawCircle(300, 300, 75, 15);
drawCircle(400, 400, 66, 5);
drawCircle(325, 423, 50, 7);

function drawCircle(circleCenterX, circleCenterY, circleRadius, lineWidth) {
    ctx.beginPath();

    ctx.lineWidth = lineWidth;
    //canvasContext.fillStyle = "#22313f";
    ctx.arc(circleCenterX, circleCenterY, circleRadius, getRadiansFromPercentage(0), getRadiansFromPercentage(1)); // centerX, centerY, radius, startRadians, endRadians

    ctx.stroke();
}

function getRadiansFromPercentage(percentage) {
  var radians = (percentage * 360) * (Math.PI / 180); // turn percentage to degrees, then to radians

  return radians - 0.5 * Math.PI; // - 0.5 * Math.PI so "0.00" starts at the top of the circle
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="my-canvas"></canvas>
&#13;
&#13;
&#13;

最终目标是让我的项目看起来像这样:

enter image description here

1 个答案:

答案 0 :(得分:1)

要执行此操作,首先要正常绘制中心圆,然后使用ctx.globalCompositeOperation = "destination-out"绘制所有填充的外圆,这将从中心圆中删除像素。渲染完所有外圈后,设置ctx.globalCompositeOperation = "source-over"并将外圈渲染为正常。

带随机圆圈的示例代码。我认为这就是你所追求的目标。

&#13;
&#13;
canvas.width = 512;
canvas.height = 512;
const ctx = canvas.getContext("2d");

const circle = {
   x : 256,
   y : 256,
   r : 150,
   w : 10,
}

const circles = [];
function randCircle(){
  const ang = Math.random() * Math.PI * 2;
  const r = Math.random() * 100 + 50;
  const w = Math.random() * 18 + 2;
  const dist = circle.r - circle.w/2 + (r - w/2 );
  circles.push({
    x : circle.x + Math.cos(ang) * dist,
    y : circle.y + Math.sin(ang) * dist,
    r,
    w,
  })
}
function doit(){
  ctx.clearRect(0,0,512,512);
  circles.length = 0;
  /// some random circles
  for(let i = 0; i < 8; i ++){
    randCircle();
  }


  function renderAll(){
     ctx.lineWidth = circle.w;
     ctx.beginPath();
     ctx.arc(circle.x, circle.y, circle.r, 0 , Math.PI * 2);
     ctx.stroke();
     ctx.globalCompositeOperation = "destination-out";
     ctx.beginPath();
     for(var i = 0; i < circles.length; i ++){
       var c = circles[i];
       ctx.moveTo(c.x + c.r,c.y);
       ctx.arc(c.x,c.y,c.r,0,Math.PI * 2);
     }
     ctx.fill();
     ctx.globalCompositeOperation = "source-over";
     for(var i = 0; i < circles.length; i ++){
       ctx.beginPath();
       var c = circles[i];
       ctx.lineWidth = c.w;
       ctx.arc(c.x,c.y,c.r,0,Math.PI * 2);
       ctx.stroke();
     }

  }

  renderAll();
}

canvas.onclick = doit;
doit();
&#13;
canvas {
 border : 2px solid black;
}
&#13;
Click canvas to randomise.<br>
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;