You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Canvas中复用自定义SVG pattern实现图形填充

Canvas 自定义 Pattern 实现方案

Canvas 的createPattern()方法并非仅支持传入图片作为填充源,它支持传入任意CanvasImageSource类型,包括<img>元素、离屏 Canvas、<svg>元素、视频元素等,完全可以复现和 SVG 中完全一致的自定义 pattern 填充效果,两种常用实现路径如下:

方案1:直接复用现有 SVG 代码(零逻辑重写)

不需要重写 pattern 的绘制逻辑,直接把已有的 SVG 片段封装为合法的 SVG 文件,加载后作为 pattern 源即可:

  • 补全 SVG 根节点声明,将已写好的 defs 和 pattern 放入节点内,注意给 SVG 根节点加上标准命名空间
  • 将 SVG 字符串转为 Blob URL,通过 Image 对象加载
  • 加载完成后传入createPattern(),设置重复模式为repeat就能得到和 SVG 完全一致的填充效果

对应实现代码:

// 直接复用已有的SVG pattern代码
const svgString = `
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
  <defs>
    <pattern id="hash4_4" width="8" height="8" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
      <rect width="4" height="8" transform="translate(0,0)" fill="lightgray"></rect>
    </pattern>
  </defs>
  <rect width="100%" height="100%" fill="url(#hash4_4)"></rect>
</svg>
`;
// 转换为可被Image加载的URL
const blob = new Blob([svgString], {type: 'image/svg+xml'});
const url = URL.createObjectURL(blob);

const img = new Image();
img.onload = () => {
  const canvas = document.getElementById('target-canvas');
  const ctx = canvas.getContext('2d');
  // 生成填充pattern
  const fillPattern = ctx.createPattern(img, 'repeat');
  ctx.fillStyle = fillPattern;
  // 正常绘制图形即可得到同款填充效果
  ctx.fillRect(0, 0, 300, 300);
  // 加载完成后释放URL对象避免内存泄漏
  URL.revokeObjectURL(url);
};
img.src = url;

方案2:离屏 Canvas 绘制图案单元(性能更优)

如果不想依赖 SVG 解析,也可以直接在离屏 Canvas 上手动绘制 pattern 的最小重复单元,再把离屏 Canvas 作为createPattern的输入,这种方式渲染开销更低,适合动画、高频重绘的场景:

// 创建和pattern单元尺寸一致的离屏canvas
const patternCanvas = document.createElement('canvas');
patternCanvas.width = 8;
patternCanvas.height = 8;
const pctx = patternCanvas.getContext('2d');

// 绘制和原SVG效果一致的45度斜纹单元
pctx.fillStyle = 'lightgray';
pctx.translate(4, 0);
pctx.rotate(Math.PI / 4);
pctx.fillRect(-4, -4, 4, 16);

// 主canvas直接引用离屏canvas生成填充
const canvas = document.getElementById('target-canvas');
const ctx = canvas.getContext('2d');
const fillPattern = ctx.createPattern(patternCanvas, 'repeat');
ctx.fillStyle = fillPattern;
ctx.fillRect(0, 0, 300, 300);

注意:如果需要调整 pattern 的缩放、偏移、旋转效果,不需要修改 pattern 源本身,直接在主 Canvas 绘图时通过ctx.setTransform()调整坐标系即可,逻辑和 SVG 中patternTransform属性一致。

内容的提问来源于stack exchange,提问作者Kamil P.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:03:50