mcpField
P
pixijs-scene-graphics

pixijs-scene-graphics

github.com/pixijs开发3586.1k 次安装4 周前更新
代码仓库

关于 pixijs-scene-graphics

面向 PixiJS v8 开发者的 Graphics 技能,介绍在场景图中绘制矢量形状、路径并应用样式。还涵盖渐变、纹理、裁切、SVG 和共享绘图上下文。

主要功能

  1. 01绘制形状与复杂路径
  2. 02应用填充、描边、渐变和图案
  3. 03通过 cut() 创建镂空
  4. 04导入和导出 SVG
  5. 05共享 GraphicsContext

适用场景

  1. 01绘制界面图形和矢量元素
  2. 02制作带渐变或纹理的形状
  3. 03将 Graphics 用作遮罩

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pixijs/pixijs-skills --skill pixijs-scene-graphics

安装后在 Claude Code 中输入/pixijs-scene-graphics确认已加载。

详细介绍

Graphics 是 PixiJS v8 场景图中的矢量绘图叶节点。v8 API 采用先形状、后样式的模式:先使用 rect、circle、moveTo 等方法绘制形状或路径,再应用 fill 和/或 stroke。每个方法都会返回 this 以便链式调用,绘图指令则存储在可由多个实例共享的 GraphicsContext 中。

假设你熟悉 pixijs-scene-core-concepts。Graphics 是叶节点:不要在其中嵌套子节点。将多个 Graphics 对象放在 Container 中进行分组。

快速入门

const g = new Graphics();

g.rect(10, 10, 200, 100)
  .fill({ color: 0x3498db, alpha: 0.8 })
  .stroke({ width: 3, color: 0x2c3e50 });

g.circle(300, 60, 40).fill(0xe74c3c);

g.moveTo(50, 200)
  .lineTo(200, 200)
  .bezierCurveTo(250, 250, 100, 300, 50, 250)
  .closePath()
  .fill(0x6c5ce7);

app.stage.addChild(g);

相关技能: pixijs-scene-core-concepts(场景图基础)、pixijs-scene-container(将图形与其他对象分组)、pixijs-scene-core-concepts/references/masking.md(将 Graphics 用作模板遮罩)、pixijs-filters(特效)、pixijs-performance(批处理、cacheAsTexture)。

构造函数选项

所有 Container 选项(position、scale、tint、label、filters、zIndex 等)在这里同样有效——请参阅 skills/pixijs-scene-core-concepts/references/constructor-options.md。

由 GraphicsOptions 添加的叶节点专属选项:

选项类型默认值描述
contextGraphicsContextnew GraphicsContext()共享绘图上下文。传入上下文可在多个 Graphics 节点间复用其镶嵌几何数据,避免重复的 GPU 运算。如果省略,每个 Graphics 都会创建并持有一个新上下文。
roundPixelsbooleanfalse将最终屏幕上的 x/y 舍入到最接近的像素。这样能让像素艺术风格的线条更清晰,但会牺牲平滑的亚像素移动效果。

构造函数也接受 GraphicsContext 实例作为唯一参数(new Graphics(ctx)),这是 new Graphics({ context: ctx }) 的简写形式。

核心模式

先定义形状再填充的工作流
const g = new Graphics();

g.rect(10, 10, 200, 100)
  .fill({ color: 0x3498db, alpha: 0.8 })
  .stroke({ width: 3, color: 0x2c3e50 });

g.circle(150, 200, 40).fill(0xe74c3c);
g.roundRect(300, 10, 150, 80, 12).fill(0x2ecc71);
g.poly([0, 0, 60, 0, 30, 50], true).fill(0x9b59b6);
g.star(400, 200, 5, 40, 20, 0).fill(0xf39c12);
g.ellipse(100, 350, 60, 30).fill(0x1abc9c);

fill() 接受 FillInput:颜色数字或字符串、{ color, alpha, texture, matrix, textureSpace }、FillGradient、FillPattern 或 Texture。使用纹理填充时,textureSpace 控制坐标映射:

  • 'local'(默认):缩放纹理以适应每个形状的边界框(归一化的 0-1 坐标)。
  • 'global':纹理的位置和缩放相对于 Graphics 对象的坐标系,所有形状共享。
  • 图集子纹理:'global' 会遵循帧的原点和旋转,因此以帧的尺寸绘制的形状会与该帧的 Sprite 匹配。'local' 会映射整个源图像;传入一个将目标设为源图像中帧区域的 matrix,或者先对帧使用 renderer.generateTexture()。

FillInput 还支持嵌套的 fill 子字段:FillStyle 选项对象可以在其 fill 键下嵌入 FillGradient 或 FillPattern,从而将渐变或图案与外层对象的 color、alpha、texture 和 matrix 修饰项一并应用。

stroke() 接受颜色、FillGradient、FillPattern,或一个将所有 FillStyle 键(color、alpha、texture、matrix、fill、textureSpace)与描边属性组合在一起的 StrokeStyle 对象:

属性默认值说明
width1描边的像素宽度。
cap'butt'可选值为 'butt'、'round'、'square'。开放路径的端点样式。
join'miter'可选值为 'miter'、'round'、'bevel'。拐角样式。
miterLimit10限制斜接连接的延伸距离,超过后会改用斜角连接。
alignment0.51 = 形状内部,0.5 = 居中,0 = 形状外部。
pixelLinefalse将 1 像素线条对齐到像素网格,以获得清晰的输出。仅适用于 Graphics。

描边可以像填充一样使用渐变和图案,例如 fill: gradient 或 texture: tex:

const grad = new FillGradient({
  end: { x: 1, y: 0 },
  colorStops: [
    { offset: 0, color: 0xff0000 },
    { offset: 1, color: 0x0000ff },
  ],
});
g.rect(0, 0, 200, 100).stroke({
  width: 8,
  fill: grad,
  join: "round",
  cap: "round",
});

对同一形状调用 fill() 和 stroke() 时,可以先后调用;在 fill() 后立即调用 stroke() 会复用同一路径。

高级形状图元
g.regularPoly(100, 100, 50, 6, 0).fill(0x3498db);
g.roundPoly(250, 100, 50, 5, 10).fill(0xe74c3c);
g.chamferRect(350, 50, 100, 80, 15).fill(0x2ecc71);
g.filletRect(500, 50, 100, 80, 15).fill(0x9b59b6);
g.roundShape(
  [
    { x: 50, y: 250, radius: 20 },
    { x: 150, y: 250, radius: 5 },
    { x: 150, y: 350, radius: 10 },
    { x: 50, y: 350, radius: 15 },
  ],
  10,
).fill(0xf39c12);
使用 cut() 创建镂空
g.rect(0, 0, 200, 200).fill(0x00ff00).circle(100, 100, 50).cut();

cut() 会从之前绘制的填充或描边中减去当前活动路径。规则如下:

  • 镂空必须完全位于目标形状内部。由于渲染器会将镂空作为内部边界进行三角剖分,与边缘重叠或位于形状外部的镂空无法正确渲染。
  • cut() 会回溯最多最近两条指令。使用 fill() 后再对同一路径调用 stroke() 时,第一次 cut() 会先将镂空添加到描边;第二次 cut() 则会将镂空添加到下方的填充。
  • 调用 cut() 后,活动路径会重置,因此可以使用 moveTo、rect 等方法开始下一个形状。
  • cut() 也适用于描边——g.rect(...).stroke(...).circle(...).cut() 会在描边轮廓上切出一个孔。

调用 cut() 前,在活动路径中绘制多个形状,即可一次镂空多个位置。每个形状都会累加到同一个镂空路径中:

const g = new Graphics();

g.rect(350, 350, 150, 150).fill(0x00ff00);

// Draw three circles into the active path, then cut them all in one call
g.circle(375, 375, 25);
g.circle(425, 425, 25);
g.circle(475, 475, 25);
g.cut();

如果需要在彼此独立的填充形状上镂空,请为每个形状分别调用 fill() 和对应的 cut():

g.rect(0, 0, 100, 100).fill(0x3498db);
g.circle(50, 50, 20).cut(); // hole in the rect

g.rect(120, 0, 100, 100).fill(0xe74c3c);
g.circle(170, 50, 20).cut(); // hole in the second rect

对已有镂空的形状调用 cut() 时,会添加到现有镂空路径中,而不是替换它。可以用这种方式叠加多个镂空。

路径与复杂形状
g.moveTo(50, 50)
  .lineTo(200, 50)
  .bezierCurveTo(250, 100, 250, 150, 200, 200)
  .quadraticCurveTo(100, 250, 50, 200)
  .closePath()
  .fill({ color: 0x6c5ce7, alpha: 0.7 })
  .stroke({ width: 2, color: 0xdfe6e9 });

路径方法:moveTo、lineTo、bezierCurveTo、quadraticCurveTo、arc、arcTo、arcToSvg、closePath。调用 beginPath() 可丢弃当前路径并开始新路径。

// arc(cx, cy, radius, startAngle, endAngle, counterclockwise?)
g.moveTo(80, 50)
  .arc(50, 50, 30, 0, Math.PI)
  .stroke({ width: 4, color: 0x2c3e50 });

// arcTo(x1, y1, x2, y2, radius) — rounded corner between two line segments
g.moveTo(150, 20)
  .arcTo(200, 20, 200, 80, 20)
  .lineTo(200, 80)
  .stroke({ width: 2 });

// arcToSvg(rx, ry, xAxisRotation, largeArcFlag, sweepFlag, x, y) — matches the SVG `A` command
g.moveTo(250, 50).arcToSvg(40, 20, 0, 1, 0, 330, 50).stroke({ width: 2 });
渐变和图案
// Linear gradient
const linear = new FillGradient({
  end: { x: 1, y: 0 },
  colorStops: [
    { offset: 0, color: 0xff0000 },
    { offset: 1, color: 0x0000ff },
  ],
});
g.rect(0, 0, 200, 100).fill(linear);

// Radial gradient. Coordinates are normalized 0-1 in the default "local" space:
// inner circle at the center, outer circle reaching the edges.
const radial = new FillGradient({
  type: "radial",
  center: { x: 0.5, y: 0.5 },
  innerRadius: 0,
  outerCenter: { x: 0.5, y: 0.5 },
  outerRadius: 0.5,
  colorStops: [
    { offset: 0, color: 0xffffff },
    { offset: 1, color: 0x000000 },
  ],
});
g.circle(100, 100, 100).fill(radial);

// Pixel coordinates need textureSpace: "global"; the gradient then spans shapes.
const shared = new FillGradient({
  type: "radial",
  center: { x: 100, y: 100 },
  outerRadius: 100,
  textureSpace: "global",
  colorStops: [
    { offset: 0, color: 0xffffff },
    { offset: 1, color: 0x000000 },
  ],
});
g.rect(0, 0, 200, 200).fill(shared);

const brick = await Assets.load("brick.png");

// Options-object form (preferred)
const pattern = new FillPattern({
  texture: brick,
  repetition: "repeat", // 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'
  textureSpace: "global", // 'global' (default) | 'local'
});

// Legacy positional form is still supported
const pattern2 = new FillPattern(brick, "repeat");

g.rect(0, 120, 200, 100).fill(pattern);

FillGradient 的默认 type 为 'linear',起点为 {0,0},终点为 {0,1}(垂直)。径向渐变可将 type 设为 'radial',并设置 center/innerRadius 和 outerCenter/outerRadius;rotation(弧度,默认值为 0)和 scale(默认值为 1)可使渐变呈椭圆形,且仅适用于 Graphics。textureSpace 默认为 'local'(归一化的 0-1 形状坐标);使用 'global' 可在多个形状间共享像素坐标。

FillPattern 接受一个选项对象({ texture, repetition?, textureSpace? })或旧版的位置参数形式(new FillPattern(texture, repetition?))。repetition 用于选择平铺模式。textureSpace 控制图块如何映射到形状:

  • 'global'(默认):图块在 Graphics 坐标系中连续重复,因此相邻形状共享同一平铺网格。最适合背景和无缝纹理。
  • 'local':单个图块适配每个形状的边界。与 setTransform 配合,可将形状细分为图块网格。

请注意,FillPattern 的 textureSpace 默认值为 'global',与上文所示纹理填充的 'local' 默认值不同。

setTransform(matrix) 会将给定矩阵直接复制到图案变换中,以缩放、旋转或偏移平铺;不带参数调用 setTransform() 可将其重置为单位变换。

请在 FillPattern 本身上设置 textureSpace 和变换。将图案传入样式对象时(fill({ fill: pattern, textureSpace: "local" })),图案自身的值会覆盖样式的 textureSpace 和 matrix。

直接绘制纹理
const tex = await Assets.load("icon.png");

// Draw the whole texture at (x, y) with optional tint
g.texture(tex, 0xffffff, 20, 20);

// Draw a subregion (dx, dy, dw, dh)
g.texture(tex, 0xff0000, 100, 20, 64, 64);

Graphics.texture(texture, tint?, dx?, dy?, dw?, dh?) 是一种快捷方式,无需通过 fill() 即可绘制单个带纹理的矩形。适用于不需要完整精灵生命周期的图标。

GraphicsContext 共享
const ctx = new GraphicsContext().rect(0, 0, 50, 50).fill(0xff0000);

const g1 = new Graphics(ctx);
const g2 = new Graphics(ctx);
g2.x = 100;

共享上下文可避免重复生成 GPU 几何数据;耗时的镶嵌处理只会运行一次。也可以在构造后指定上下文:g.context = existingContext。

SVG 导入和导出

使用 svg() 将 SVG 标记解析到当前上下文中:

g.svg(`<svg viewBox="0 0 100 100">
    <circle cx="50" cy="50" r="40" fill="red"/>
</svg>`);

svg() 可解析 <path>(包括 fill-rule="evenodd" 镂空)、<rect>、<circle>、<ellipse>、<line>、<polygon>、<polyline> 和 <g> 分组。样式可通过属性或内联 style 中的 fill、stroke、stroke-width、fill-opacity、stroke-opacity 和 opacity 指定。<defs> 中的 <linearGradient> 和 <radialGradient> 定义会转换为 FillGradient,并通过 url(#id) 应用;gradientUnits 会映射到 textureSpace,且支持百分比坐标。不支持:transform 属性、<style> 块、stroke-linecap/stroke-linejoin/stroke-dasharray、gradientTransform、spreadMethod、stop-opacity、<text>、<image>、<use>、<clipPath>、<mask>、<pattern>。遇到不支持的元素时会记录警告并跳过。由于 Pixi 的三角剖分经过性能优化,复杂的镂空几何图形可能渲染不准确。

使用 graphicsContextToSvg 将 Graphics 或 GraphicsContext 序列化为独立的 SVG 文档字符串:

import { Graphics, graphicsContextToSvg } from "pixi.js";

const g = new Graphics()
  .rect(0, 0, 100, 50)
  .fill({ color: 0xff0000 })
  .circle(150, 25, 25)
  .stroke({ color: 0x0000ff, width: 4 });

const svgString = graphicsContextToSvg(g, 2);

graphicsContextToSvg(source, precision = 2) 是一个纯函数,会读取上下文的指令,并返回包含自动计算的 viewBox 的完整 <svg> 字符串。传入 Graphics 或 GraphicsContext;precision 用于控制输出坐标的小数位数。它会导出所有形状填充图元(regularPoly/filletRect 等高级图形会回退为形状路径)、所有路径方法、描边属性(width、cap、join、miterLimit)、fill-opacity/stroke-opacity,以及通过 <defs> 块导出的 FillGradient(线性和径向)。镂空会合并为一个带有 fill-rule="evenodd" 的 <path>。FillPattern 和纹理填充没有对应的 SVG 表示:图案会回退为填充的纯色 color,而 texture() 指令会被完全跳过。导出的标记可直接通过 g.svg(...) 重新导入,无需清理,因此你可以导出、保存图形,并在之后将其重新导入另一个 Graphics。

重用 GraphicsPath
const arrow = new GraphicsPath()
  .moveTo(0, 0)
  .lineTo(40, 0)
  .lineTo(40, -10)
  .lineTo(60, 10)
  .lineTo(40, 30)
  .lineTo(40, 20)
  .lineTo(0, 20)
  .closePath();

g.path(arrow).fill(0x3498db);
g.translateTransform(80, 0).path(arrow).fill(0xe74c3c);

Graphics.path(graphicsPath)(以及 GraphicsContext.path())会将预先构建的 GraphicsPath 追加到当前路径中。构建一次,绘制多次。

绘制时变换

Graphics 有自己的绘制时变换堆栈,与应用于渲染输出的 Container 变换分开。绘制变换方法已重命名,以避免与 Container.rotation、Container.scale、Container.position 冲突:

绘制变换Container 变换
g.rotateTransform(angle)g.rotation
g.scaleTransform(x, y?)g.scale.set(x, y)
g.translateTransform(x, y?)g.position.set(x, y)
g.setTransform(matrix) 或 setTransform(a,b,c,d,tx,ty)g.setFromMatrix(matrix)
g.transform(matrix) 或 transform(a,b,c,d,tx,ty)不适用
g.getTransform() / g.resetTransform()不适用
const g = new Graphics();

g.translateTransform(100, 100)
  .rotateTransform(Math.PI / 4)
  .rect(-25, -25, 50, 50)
  .fill(0x3498db);

// The square is rotated 45 degrees as it is added to the geometry.
// Setting g.rotation later rotates the entire Graphics on screen.

绘制变换会影响之后添加到上下文中的每个形状和路径命令。使用 save()/restore() 对其进行作用域控制。

状态保存与恢复
g.save();
g.translateTransform(100, 100);
g.rotateTransform(Math.PI / 4);
g.rect(0, 0, 50, 50).fill(0xff0000);
g.restore();

save() 会将绘制变换、填充样式和描边样式压入堆栈;restore() 会将它们弹出。Graphics 直接提供 save/restore 方法,对应底层 GraphicsContext 的调用。

通过 setFillStyle / setStrokeStyle 设置默认样式
g.setFillStyle({ color: 0x3498db, alpha: 0.8 }).setStrokeStyle({
  width: 2,
  color: 0x2c3e50,
});

g.rect(0, 0, 100, 100).fill().stroke();
g.circle(150, 50, 40).fill().stroke();

setFillStyle() 和 setStrokeStyle() 用于配置后续未传入参数的 fill() / stroke() 调用所使用的默认样式。你可以随时通过 fillStyle 和 strokeStyle getter/setter 读取或替换当前样式。启动时修改 GraphicsContext.defaultFillStyle 和 GraphicsContext.defaultStrokeStyle,即可覆盖整个库的默认值。

命中测试
const g = new Graphics().star(100, 100, 5, 60, 30).fill(0xf39c12);
g.eventMode = "static";
g.on("pointermove", (e) => {
  if (g.containsPoint(g.toLocal(e.global))) {
    /* over the star, not just its bbox */
  }
});

Graphics.containsPoint(pointInLocalSpace) 会对上下文中的每个填充和描边形状执行考虑拓扑结构的测试,包括孔洞。请先通过 toLocal() 转换全局指针坐标。描边形状的命中测试针对实际绘制的描边进行:命中范围取决于描边的 width 和 alignment(1 表示向内,0.5 表示居中,0 表示向外),且与多边形的绕序无关。

克隆、清除和边界
const g = new Graphics().rect(0, 0, 100, 100).fill(0xff0000);

const shallow = g.clone(); // shares the same GraphicsContext
const deep = g.clone(true); // creates an independent context

console.log(g.bounds.width); // 100 - geometry bounds before transforms

g.clear(); // wipes active path, instructions, and transform; fill/stroke styles persist
  • clone() 会返回一个新的 Graphics,并与源对象共享上下文(开销较低,复用几何数据)。如果上下文发生变化,这两个对象都会随之更新。
  • clone(true) 也会克隆上下文,因此新 Graphics 可以独立编辑。
  • bounds 返回 Container 变换前的几何边界,可用于布局决策。
  • clear() 会重置上下文,以便重复使用同一个 Graphics。关于何时清除、何时保留稳定几何数据,请参阅下文的常见错误。
GraphicsContext 工具
成员行为
ctx.path(graphicsPath)将预先构建的 GraphicsPath 应用到当前活动路径。可在多个上下文或帧中复用同一个路径。
ctx.beginPath()丢弃当前活动路径并开始新路径,不影响已提交的指令。
ctx.setFillStyle(style) / ctx.fillStyle设置或读取后续形状使用的默认填充样式,无需调用 fill()。
ctx.setStrokeStyle(style) / ctx.strokeStyle设置或读取后续形状使用的默认描边样式,无需调用 stroke()。
ctx.bounds缓存所有填充、描边和纹理指令的几何边界。
ctx.clear()清除指令、活动路径和绘图变换。
ctx.clone()深拷贝指令、活动路径、变换、样式和堆栈。
ctx.containsPoint(point)对所有填充和描边形状执行考虑拓扑结构的命中测试(包括孔洞)。
ctx.batchMode可设为 'auto'、'batch' 或 'no-batch',以强制启用或禁用此上下文中形状的批处理。
ctx.customShader指定一个 Shader,以覆盖默认图形着色器。
GraphicsContext.defaultFillStyle调用 fill() 时未传入参数且未设置填充样式时使用的静态回退值。
GraphicsContext.defaultStrokeStyle调用 stroke() 时未传入参数且未设置描边样式时使用的静态回退值。

GraphicsContext 是一个 EventEmitter,会触发 update、destroy 和 unload 事件。当工具或对象池需要响应上下文生命周期变化时,可通过 ctx.on('update' | 'destroy' | 'unload', cb) 订阅这些事件。

常见错误

[CRITICAL] 使用 v7 的 beginFill/drawRect/endFill

错误:

const g = new Graphics().beginFill(0xff0000).drawRect(0, 0, 100, 100).endFill();

正确:

const g = new Graphics().rect(0, 0, 100, 100).fill(0xff0000);

v8 将“设置样式、绘制、结束”替换为“绘制形状,然后应用样式”。beginFill/endFill 不存在。

[CRITICAL] 使用旧的形状方法名称

错误:

g.drawCircle(50, 50, 25);

正确:

g.circle(50, 50, 25);

v8 重命名了所有 draw* 方法:drawRect → rect、drawCircle → circle、drawEllipse → ellipse、drawPolygon → poly、drawRoundedRect → roundRect、drawStar → star。

[CRITICAL] 使用 lineStyle 而不是 stroke

错误:

g.lineStyle(2, 0xffffff);
g.drawRect(0, 0, 100, 100);

正确:

g.rect(0, 0, 100, 100).stroke({ width: 2, color: 0xffffff });

lineStyle 已被移除。绘制形状后使用 stroke()。描边选项对象接受 width、color、alpha、cap、join、alignment、miterLimit 和 pixelLine。

[HIGH] 使用 beginHole/endHole 创建孔洞

错误:

g.beginFill(0x00ff00)
  .drawRect(0, 0, 100, 100)
  .beginHole()
  .drawCircle(50, 50, 20)
  .endHole()
  .endFill();

正确:

g.rect(0, 0, 100, 100).fill(0x00ff00).circle(50, 50, 20).cut();

beginHole/endHole 已被 cut() 替代。绘制外部形状并填充,然后绘制孔洞形状并调用 cut()。

[HIGH] 使用 GraphicsGeometry 而不是 GraphicsContext

错误:

const geom = g.geometry;
const clone = new Graphics(geom);

正确:

const ctx = new GraphicsContext().rect(0, 0, 100, 100).fill(0xff0000);
const g1 = new Graphics(ctx);
const g2 = new Graphics(ctx);

在 v8 中,GraphicsGeometry 已被 GraphicsContext 替代。不存在 .geometry 属性。

[HIGH] 意外销毁共享的 GraphicsContext
const ctx = new GraphicsContext().rect(0, 0, 50, 50).fill(0xff0000);
const g1 = new Graphics(ctx);
const g2 = new Graphics(ctx);

g1.destroy({ context: true }); // g2 is left holding a destroyed context

销毁共享的 GraphicsContext 不会销毁其他使用它的 Graphics,但它们仍会保留对已销毁上下文的引用,导致无法继续正确更新或渲染。通过构造函数传入上下文时,不带参数调用 destroy() 会保留上下文,并将实例与上下文分离;也可以使用 destroy({ context: false }) 明确指定。只有在所有共享实例都不再使用该上下文时,才销毁它。自行拥有的上下文(未通过构造函数传入)仍会在不带参数调用 destroy() 时被销毁。

[HIGH] 每帧清除并重新绘制 Graphics

Graphics 旨在保持稳定,而非动态。每帧调用 clear() 并重新绘制都会重新构建 GPU 几何体。对于动态视觉效果:

  • 使用预渲染纹理并通过变换进行更改的 Sprite。
  • 对复杂的静态图形使用 cacheAsTexture(true)。
  • 对于实时形状变化,可考虑使用自定义几何体更新的 Mesh。

这与 HTML Canvas 2D 正好相反,在 HTML Canvas 2D 中,每帧重绘很常见。PixiJS 会将形状细分为 GPU 三角形,因此初次绘制开销较大,但后续渲染速度很快。应将 Graphics 视为 SVG 元素,而不是 Canvas 绘图调用。

[MEDIUM] 不要在 Graphics 中嵌套子项

Graphics 将 allowChildren 设为 false。添加子项会记录弃用警告,并会在未来版本中成为严重错误。将多个图形与其他叶节点一起包在普通的 Container 中:

const group = new Container();
group.addChild(graphics, sprite);

API 参考

评论

支持 Markdown