fill() 简介
fill() 是 Canvas 2D 上下文中用于填充当前路径内部区域的方法。它会用当前的 fillStyle 颜色或渐变来填充路径围成的区域。
语法
ctx.fill();
// 或带可选参数
ctx.fill(fillRule);
ctx.fill(path, fillRule);
| 参数 | 说明 |
|---|---|
fillRule(可选) |
填充规则:'nonzero'(默认,非零环绕规则)或 'evenodd'(奇偶规则) |
path(可选) |
指定要填充的 Path2D 对象 |
基本用法
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 填充一个矩形路径
ctx.beginPath();
ctx.rect(50, 50, 200, 150);
ctx.fillStyle = '#3498db'; // 设置填充颜色
ctx.fill(); // 填充为蓝色
// 填充一个圆形路径
ctx.beginPath();
ctx.arc(300, 200, 60, 0, Math.PI * 2);
ctx.fillStyle = '#e74c3c';
ctx.fill();
fill() 的特性
1. 自动闭合路径:
ctx.beginPath();
ctx.moveTo(100, 50);
ctx.lineTo(175, 165);
ctx.lineTo(25, 165);
// 没有调用 closePath()
ctx.fill(); // 自动从最后一个点画线回到起点,然后填充
2. 填充规则(fillRule):
// 绘制两个重叠的正方形
ctx.beginPath();
ctx.rect(50, 50, 150, 150); // 外正方形
ctx.rect(100, 100, 90, 90); // 内正方形(逆时针方向)
// 非零环绕规则(默认):内外方向相反时挖空
ctx.fillStyle = 'red';
ctx.fill('nonzero'); // 中间被挖空
// 奇偶环绕规则:根据交叉次数判断
ctx.fill('evenodd'); // 中间也被挖空,但效果可能不同
填充样式
fill() 可以使用多种填充样式:
// 纯色填充
ctx.fillStyle = 'red';
ctx.fill();
// 渐变填充
const gradient = ctx.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, 'red');
gradient.addColorStop(1, 'blue');
ctx.fillStyle = gradient;
ctx.fill();
// 图案填充
const img = new Image();
img.onload = function() {
const pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
ctx.fill();
};
img.src = 'pattern.png';
与 stroke() 配合使用
// 既有填充又有描边的图形
ctx.beginPath();
ctx.arc(150, 115, 70, 0, Math.PI * 2);
ctx.fillStyle = '#f1c40f'; // 黄色填充
ctx.fill();
ctx.strokeStyle = '#e67e22'; // 橙色描边
ctx.lineWidth = 4;
ctx.stroke();
典型应用
1. 绘制柱状图:
const data = [45, 78, 32, 91, 56, 68];
const barWidth = 50;
const gap = 20;
data.forEach((value, index) => {
const x = 30 + index * (barWidth + gap);
const y = 280 - value;
ctx.beginPath();
ctx.rect(x, y, barWidth, value);
ctx.fillStyle = `hsl(${index * 35}, 70%, 50%)`;
ctx.fill();
});
2. 绘制饼图:
const data = [30, 20, 25, 25]; // 百分比
const colors = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12'];
let startAngle = 0;
data.forEach((value, index) => {
const sliceAngle = (value / 100) * Math.PI * 2;
ctx.beginPath();
ctx.moveTo(200, 150);
ctx.arc(200, 150, 100, startAngle, startAngle + sliceAngle);
ctx.closePath();
ctx.fillStyle = colors[index];
ctx.fill();
startAngle += sliceAngle;
});
注意事项
| 情况 | 说明 |
|---|---|
| 路径为空 | 不产生任何效果 |
| 路径未闭合 | fill() 会自动闭合后再填充 |
多次调用 fill() |
会在同一路径上重复填充(叠加效果) |
| 性能 | 大量小图形的填充可能影响性能 |
与 stroke() 的区别
| 方法 | 作用 | 依赖属性 | 自动闭合 |
|---|---|---|---|
fill() |
填充内部区域 | fillStyle |
✅ 是 |
stroke() |
描画轮廓线条 | strokeStyle, lineWidth |
❌ 否 |
一句话总结
fill() 就是用当前设置的填充样式(颜色/渐变/图案)把路径围起来的区域涂满,并且会自动帮你把路径闭合。
