图形
🌐 Graphics
Graphics 是一个强大且灵活的工具,用于渲染矩形、圆形、星形和自定义多边形等形状。它还可用于通过组合多个基本图形创建复杂形状,并支持渐变、纹理和蒙版等高级功能。
import { Graphics } from 'pixi.js';
const graphics = new Graphics().rect(50, 50, 100, 100).fill(0xff0000);
可用形状
🌐 Available Shapes
PixiJS v8 支持多种形状基元:
🌐 PixiJS v8 supports a variety of shape primitives:
Basic Primitives
- Line
- Rectangle
- Rounded Rectangle
- Circle
- Ellipse
- Arc
- Bezier / Quadratic Curves
const graphics = new Graphics()
.rect(50, 50, 100, 100)
.fill(0xff0000)
.circle(200, 200, 50)
.stroke(0x00ff00)
.lineStyle(5)
.moveTo(300, 300)
.lineTo(400, 400);
SVG 支持
🌐 SVG Support
你还可以加载 SVG 路径数据,但由于 Pixi 性能优化的三角测量系统,复杂的孔洞几何体渲染可能不准确。
🌐 You can also load SVG path data, although complex hole geometries may render inaccurately due to Pixi's performance-optimized triangulation system.
let shape = new Graphics().svg(`
<svg>
<path d="M 100 350 q 150 -300 300 0" stroke="blue" />
</svg>
`);
图形上下文
🌐 GraphicsContext
GraphicsContext 类是 PixiJS 新图形模型的核心。它保存了所有的绘图命令和样式,允许多个 Graphics 实例重用相同的形状数据:
🌐 The GraphicsContext class is the core of PixiJS's new graphics model. It holds all the drawing commands and styles, allowing the same shape data to be reused by multiple Graphics instances:
const context = new GraphicsContext().circle(100, 100, 50).fill('red');
const shapeA = new Graphics(context);
const shapeB = new Graphics(context); // Shares the same geometry
此模式在渲染重复或动画形状(例如基于帧的 SVG 交换)时特别有效:
🌐 This pattern is particularly effective when rendering repeated or animated shapes, such as frame-based SVG swaps:
let frames = [
new GraphicsContext().circle(100, 100, 50).fill('red'),
new GraphicsContext().rect(0, 0, 100, 100).fill('red'),
];
let graphic = new Graphics(frames[0]);
function update() {
graphic.context = frames[1]; // Very cheap operation
}
如果在创建 Graphics 对象时没有显式传递 GraphicsContext,那么在内部,它将拥有自己的上下文,可以通过 myGraphics.context 访问。
销毁 GraphicsContext
🌐 Destroying a GraphicsContext
当你销毁一个 GraphicsContext 时,所有共享它的 Graphics 实例也会被销毁。这一点至关重要,因为如果不小心,可能会导致意想不到的行为。
🌐 When you destroy a GraphicsContext, all Graphics instances that share it will also be destroyed. This is a crucial point to remember, as it can lead to unexpected behavior if you're not careful.
const context = new GraphicsContext().circle(100, 100, 50).fill('red');
const shapeA = new Graphics(context);
const shapeB = new Graphics(context); // Shares the same geometry
shapeA.destroy({ context: true }); // Destroys both shapeA and shapeB
创建孔洞
🌐 Creating Holes
使用 .cut() 从前一个形状中移除一个形状:
🌐 Use .cut() to remove a shape from the previous one:
const g = new Graphics().rect(0, 0, 100, 100).fill(0x00ff00).circle(50, 50, 20).cut(); // Creates a hole in the green rectangle
确保孔洞完全包含在形状内,以避免三角测量错误。
🌐 Ensure the hole is fully enclosed within the shape to avoid triangulation errors.
图形是关于构建,而不是绘画
🌐 Graphics Is About Building, Not Drawing
尽管像 .rect() 或 .circle() 这样的函数命名,Graphics 并不会立即绘制任何内容。相反,每个方法都会在 GraphicsContext 中构建一个几何原语列表。只有当对象被绘制到屏幕上或在其他上下文中使用,例如作为遮罩时,这些原语才会被渲染。
🌐 Despite the terminology of functions like .rect() or .circle(), Graphics does not immediately draw anything. Instead, each method builds up a list of geometry primitives stored inside a GraphicsContext. These are then rendered when the object is drawn to the screen or used in another context, such as a mask.
const graphic = new Graphics().rect(0, 0, 200, 100).fill(0xff0000);
app.stage.addChild(graphic); // The rendering happens here
你可以把 Graphics 想象成一个蓝图构建器:它定义了要绘制什么,但不定义何时绘制。这就是为什么 Graphics 对象可以被重用、克隆、遮罩和变换,而不会产生额外计算,直到它们实际上被渲染为止。
🌐 You can think of Graphics as a blueprint builder: it defines what to draw, but not when to draw it. This is why Graphics objects can be reused, cloned, masked, and transformed without incurring extra computation until they're actually rendered.
性能最佳实践
🌐 Performance Best Practices
- 不要每帧清除并重建图形。如果你的内容是动态的,最好替换预先构建的
GraphicsContext对象,而不是重新创建它们。 - 完成后使用
Graphics.destroy()来清理。共享上下文不会自动销毁。 - 使用多个简单的
Graphics对象 而不是一个复杂的对象,以保持 GPU 批处理。 - 避免透明重叠,除非你了解混合模式;重叠的半透明图元将按照每个图元相互作用,而不是按后期合成。
注意事项和陷阱
🌐 Caveats and Gotchas
- 内存泄漏:在不再需要时调用
.destroy()。 - SVG 和孔:并非所有 SVG 孔路径都能正确进行三角剖分。
- 改变几何:请谨慎使用
.clear()。更建议交换上下文。 - 透明度和混合模式:这些应用于每个图元。如果你想要合并效果,请使用
RenderTexture。
API 参考
🌐 API Reference