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

使用PixiJS渲染带镂空路径的定位SVG图标失败

解决PixiJS Graphics.svg()渲染SVG镂空失效的问题

问题描述

使用PixiJS渲染定位SVG图标时,中间镂空区域无法显示,SVG代码如下:

<svg width="28" height="40" viewBox="0 0 28 40" xmlns="http://www.w3.org/2000/svg">
  <path fill-rule="evenodd" d="M14 0C6.26 0 0 6.26 0 14C0 24.5 14 40 14 40C14 40 28 24.5 28 14C28 6.26 21.74 0 14 0ZM14 19C11.24 19 9 16.76 9 14C9 11.24 11.24 9 14 9C16.76 9 19 11.24 19 14C19 16.76 16.76 19 14 19Z" />
</svg>

该图标在Figma中显示正常,但通过Graphics.svg()方法渲染时镂空消失。尝试设置fill-rule="evenodd"和nonzero均无效,当前绘制代码:

o.graphic = new Graphics()
this.#artboard.addChild(o.graphic)
o.graphic.svg(pinSVG)
o.graphic.stroke({ color: 'black', width: 2 })
o.graphic.fill('red')

若将SVG加载为Texture,镂空显示正常,但无法修改描边等属性。

问题原因

  1. Graphics.svg()方法默认不会自动继承SVG路径的fill-rule配置,尤其是evenodd这种依赖路径环绕方向的填充规则。
  2. 后续调用的fill()方法会覆盖路径原本的填充设置,强制使用默认填充逻辑,导致镂空失效。

解决方案

方案1:在svg()方法中明确指定填充规则

调用svg()时传入配置项指定填充规则,避免后续fill()方法覆盖设置:

o.graphic = new Graphics()
this.#artboard.addChild(o.graphic)
// 解析SVG时指定填充规则
o.graphic.svg(pinSVG, {
  fillRule: 'evenodd'
})
// 通过style属性设置填充和描边,而非直接调用fill()/stroke()
o.graphic.style.fill = 'red'
o.graphic.style.stroke = 'black'
o.graphic.style.lineWidth = 2

方案2:手动构建路径并设置填充规则

拆分SVG的内外路径,手动绘制并设置fillRule,利用路径环绕方向实现镂空:

o.graphic = new Graphics()
this.#artboard.addChild(o.graphic)

// 绘制外层路径
o.graphic.moveTo(14, 0)
o.graphic.bezierCurveTo(6.26, 0, 0, 6.26, 0, 14)
o.graphic.bezierCurveTo(0, 24.5, 14, 40, 14, 40)
o.graphic.bezierCurveTo(14, 40, 28, 24.5, 28, 14)
o.graphic.bezierCurveTo(28, 6.26, 21.74, 0, 14, 0)
o.graphic.closePath()

// 绘制内层镂空路径(反向环绕)
o.graphic.moveTo(14, 19)
o.graphic.bezierCurveTo(11.24, 19, 9, 16.76, 9, 14)
o.graphic.bezierCurveTo(9, 11.24, 11.24, 9, 14, 9)
o.graphic.bezierCurveTo(16.76, 9, 19, 11.24, 19, 14)
o.graphic.bezierCurveTo(19, 16.76, 16.76, 19, 14, 19)
o.graphic.closePath()

// 设置填充规则并应用样式
o.graphic.fillRule = 'evenodd'
o.graphic.fill('red')
o.graphic.stroke({ color: 'black', width: 2 })

方案3:使用SVGLoader解析路径后构建Graphics

通过PIXI.SVGLoader加载SVG,获取原始路径数据后构建Graphics,确保正确保留fill-rule:

import { SVGLoader } from 'pixi.js';

const loader = new SVGLoader();
// 替换为你的SVG文件路径或直接传入SVG字符串
loader.load('pin.svg', (svgData) => {
  o.graphic = new Graphics();
  this.#artboard.addChild(o.graphic);

  // 遍历解析后的路径,添加到Graphics并应用填充规则
  svgData.paths.forEach(path => {
    o.graphic.drawShape(path.shape);
    o.graphic.fillRule = path.fillRule;
  });

  // 设置样式
  o.graphic.style.fill = 'red';
  o.graphic.style.stroke = 'black';
  o.graphic.style.lineWidth = 2;
});

内容的提问来源于stack exchange,提问作者Nikolay Dyankov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 09:25:12