如何使用Canvas填充饼图、环形图切片的指定比例区域
问题原因
你之前的代码没得到预期效果,核心是context.arc()的参数使用错误:该方法的参数顺序为(圆心x, 圆心y, 半径, 起始弧度, 结束弧度, 是否逆时针绘制),你把起始弧度参数填成了50,导致裁剪区域完全不符合预期,自然得不到正确的切片填充效果。
实现方案
直接通过分段绘制扇形的方式实现比例填充,不需要用裁剪+填充矩形的组合,逻辑更简单、可控性更高:
- 先绘制完整切片的底色
- 按填充比例计算填充区域的结束弧度,在相同区域内绘制对应比例的填充层
- 要实现环形图效果,只需要额外绘制一个和背景同色的内侧小圆,或者直接用两个半径不同的扇形做裁剪即可
完整可运行示例
<canvas id="Arc" width="200" height="200"></canvas>
var canvas = document.getElementById('Arc'); var context = canvas.getContext('2d'); var centerX = canvas.width / 2; var centerY = canvas.height / 2; // 可配置参数 var radius = 50; // 饼图半径 var sliceStartAngle = 0; // 切片起始角度(弧度) var sliceTotalAngle = Math.PI / 2; // 切片总角度 这里示例是90度的扇形 var fillPercent = 0.6; // 要填充的比例 60% var fillEndAngle = sliceStartAngle + sliceTotalAngle * fillPercent; // 填充区域结束角度 function drawPieSlice() { // 第一步:绘制完整切片底色 context.beginPath(); context.moveTo(centerX, centerY); context.arc(centerX, centerY, radius, sliceStartAngle, sliceStartAngle + sliceTotalAngle); context.closePath(); context.fillStyle = '#e0e0e0'; context.fill(); context.strokeStyle = '#000'; context.lineWidth = 2; context.stroke(); // 第二步:绘制对应比例的填充区域 context.beginPath(); context.moveTo(centerX, centerY); context.arc(centerX, centerY, radius, sliceStartAngle, fillEndAngle); context.closePath(); context.fillStyle = '#090A09'; context.fill(); } // 如果要画环形图,调用这个方法 function drawDonutSlice() { var innerRadius = 25; // 环形内侧半径 // 底色环形切片 context.beginPath(); context.arc(centerX, centerY, radius, sliceStartAngle, sliceStartAngle + sliceTotalAngle); context.arc(centerX, centerY, innerRadius, sliceStartAngle + sliceTotalAngle, sliceStartAngle, true); context.closePath(); context.fillStyle = '#e0e0e0'; context.fill(); context.strokeStyle = '#000'; context.lineWidth = 2; context.stroke(); // 填充比例的环形切片 context.beginPath(); context.arc(centerX, centerY, radius, sliceStartAngle, fillEndAngle); context.arc(centerX, centerY, innerRadius, fillEndAngle, sliceStartAngle, true); context.closePath(); context.fillStyle = '#090A09'; context.fill(); } // 按需调用即可,这里示例调用饼图绘制 drawPieSlice(); // 要环形图就注释上面一行,解开下面一行 // drawDonutSlice();
参数调整说明
你可以按需修改以下参数适配你的需求:
radius:饼图/环形图的外侧半径innerRadius:环形图的内侧半径,调整这个值可以改变环形的粗细sliceStartAngle、sliceTotalAngle:调整单个切片的位置和大小,绘制完整饼图的时候依次累加总角度即可fillPercent:调整单个切片的填充比例,取值范围0-1
内容的提问来源于stack exchange,提问作者Théo
相关产品推荐
相关产品推荐

