简体   繁体   中英

how to fill certain percentage area of circle in color in html canvas?

我的html页面中有9个圆圈。每个圆圈都必须用一定的百分比填充某些颜色。我使用html5画布元素绘制了圆圈。但我只能用颜色填充整个圆圈而不是某些优点area.How我可以实现吗?

"Fuel tank", filling of circle

Use composite mode:

  • Use the radius x2 for height (or width)
  • Draw and fill the complete circle
  • Use composite mode destination-out
  • Draw a filled rectangle on top representing the % of the height

The main code would be:

  var o = radius * 2,                 // diameter => width and height of rect
      h = o - (o * percent / 100);    // height based on percentage

  ctx.beginPath();
  ctx.arc(x, y, radius, 0, 6.28);
  ctx.fill();

  ctx.globalCompositeOperation = "destination-out";
  ctx.fillRect(x - radius, y - radius, o, h);       // this will remove a part of the top

Demo

 var ctx = document.querySelector("canvas").getContext("2d"), pst = 0, dlt = 2; ctx.fillStyle = "#28f"; function drawCircle(ctx, x, y, radius, percent) { var o = radius * 2, h = o - (o * percent / 100); ctx.globalCompositeOperation = "source-over"; // make sure we have default mode ctx.beginPath(); // fill an arc ctx.arc(x, y, radius, 0, 6.28); ctx.fill(); ctx.globalCompositeOperation = "destination-out"; // mode to use for next op. ctx.fillRect(x - radius, y - radius, o, h); // "clear" part of arc ctx.globalCompositeOperation = "source-over"; // be polite, set default mode back } (function loop() { ctx.clearRect(0,0,300,150); drawCircle(ctx, 70, 70, 60, pst); pst += dlt; if (pst <= 0 || pst >= 100) dlt = -dlt; requestAnimationFrame(loop); })(); 
 <canvas></canvas> 

Pie type

  • Move to center of circle
  • Add arc, this will create a line from center to start of arc
  • Close path, this will create a line from end of arc back to center, and fill

(tip: closePath() is really not necessary with fill() as fill() will close the path implicit, but it's needed if you want to do a stroke() instead).

The essential part being:

ctx.beginPath();
ctx.moveTo(x, y);
ctx.arc(x, y, radius, 0, 2 * Math.PI * percent / 100);
//ctx.closePath();  // for stroke, not needed for fill
ctx.fill();

Demo

 var ctx = document.querySelector("canvas").getContext("2d"), pst = 0, dlt = 2; ctx.fillStyle = "#28f"; function drawPie(ctx, x, y, radius, percent) { ctx.beginPath(); ctx.moveTo(x, y); ctx.arc(x, y, radius, 0, 2 * Math.PI * percent /100); ctx.fill(); } (function loop() { ctx.clearRect(0,0,300,150); drawPie(ctx, 70, 70, 60, pst); pst += dlt; if (pst <= 0 || pst >= 100) dlt = -dlt; requestAnimationFrame(loop); })(); 
 <canvas></canvas> 

Outlined circle:

Almost same as with pie type, but with these changes:

  • Move to outer edge of arc at angle 0 (or the angle you want to start from)
  • Add arc to path
  • Stroke (remember to set lineWidth , see demo below)

Essential part:

ctx.beginPath();
ctx.moveTo(x + radius, y);  // cos(0) for x = 1, so just use radius, sin(0) = 0
ctx.arc(x, y, radius, 0, 2 * Math.PI * percent /100);
ctx.stroke();

You can adjust gap point using rotation transform or calculating the actual point using trigonometry.

Demo

 var ctx = document.querySelector("canvas").getContext("2d"), pst = 0, dlt = 2; ctx.strokeStyle = "#28f"; ctx.lineWidth = 8; function drawWedge(ctx, x, y, radius, percent) { ctx.beginPath(); ctx.moveTo(x + radius, y); ctx.arc(x, y, radius, 0, 2 * Math.PI * percent /100); ctx.stroke(); } (function loop() { ctx.clearRect(0,0,300,150); drawWedge(ctx, 70, 70, 60, pst); pst += dlt; if (pst <= 0 || pst >= 100) dlt = -dlt; requestAnimationFrame(loop); })(); 
 <canvas></canvas> 

Using different starting point

You can change the starting point for the arc using rotation transform or calculating the point manually using trigonometry.

To calculate these manually you can do (angles in radians):

x = radius * Math.cos(angleInRad);  // end point for x
y = radius * Math.sin(angleInRad);  // end point for y

Just add the total angle to the start angle to get end point.

360° in radians = 2 x PI, so if you want to use angles in degrees, convert them using:

angleInRad = angleInDeg * Math.PI / 180;

Demo, rotated using transfrom and counter-clock-wise mode

 var ctx = document.querySelector("canvas").getContext("2d"), pst = 0, dlt = 2; ctx.strokeStyle = "#28f"; ctx.lineWidth = 8; function drawWedge(ctx, x, y, radius, percent) { ctx.translate(x, y); // translate to rotating pivot ctx.rotate(Math.PI * 0.5); // rotate, here 90° deg ctx.translate(-x, -y); // translate back ctx.beginPath(); ctx.moveTo(x + radius, y); ctx.arc(x, y, radius, 0, 2 * Math.PI * percent /100); ctx.stroke(); ctx.setTransform(1,0,0,1,0,0); // reset transform } (function loop() { ctx.clearRect(0,0,300,150); drawWedge(ctx, 70, 70, 60, pst); pst += dlt; if (pst <= 0 || pst >= 100) dlt = -dlt; requestAnimationFrame(loop); })(); 
 <canvas></canvas> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM