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() 就是用当前设置的填充样式(颜色/渐变/图案)把路径围起来的区域涂满,并且会自动帮你把路径闭合。