容器
Container 类提供了一个简单的显示对象,它做的事情就像其名称暗示的那样 - 收集一组子对象到一起。但除了对对象分组外,容器还有一些你应该了解的用途。
常用属性
在 PixiJS 中布局和动画内容时,你会使用到的最常见属性由 Container 类提供
属性 | 说明 |
---|---|
position | X 和 Y 位置以像素为单位给出,并相对于其父对象更改对象的位置,还可以直接作为 object.x / object.y 使用 |
rotation | 旋转以弧度指定,并顺时针旋转一个对象 (0.0 - 2 * Math.PI) |
angle | 角度是 rotation 的别名,以度而不是弧度指定 (0.0 - 360.0) |
pivot | 对象绕其旋转的点,以像素为单位 - 还设置子对象的原点 |
alpha | 从 0.0(完全透明)到 1.0(完全不透明)的不透明度,由子对象继承 |
scale | 比例以百分比指定,其中 1.0 表示 100% 或实际大小,并且可以独立地针对 x 和 y 轴设置 |
skew | Skew 以类似于 CSS skew() 函数的方式转换 x 和 y 中的对象,并以弧度指定 |
visible | 对象是否可见,以布尔值表示 - 阻止更新和渲染对象和子对象 |
renderable | 对象是否应被渲染 - 当值为 false 时,对象仍将被更新,但不会被渲染,不会影响子对象 |
容器作为组
几乎每种类型的显示对象都派生自容器!这意味着在许多情况下,您可以使用要渲染的对象创建父子层次结构。
不过,最好不要这样做。独立的容器对象非常适合渲染,而拥有正确的容器对象层次结构(每个容器包含一个或多个可渲染对象)则提供了渲染顺序的灵活性。它还能让您的代码适应未来,因为当您需要向树的某个分支添加一个其他对象时,动画逻辑无需更改 - 只需将该新对象放到正确的容器中,逻辑便会移动容器,而您的代码无需更改。
因此,这是容器的主要用途 - 作为层次结构中可渲染对象的组。
查看容器示例代码。
遮罩
容器对象的另一种常见用途是作为蒙版内容的宿主。“遮罩”是一种技术,其中场景图的一部分仅在给定区域内可见。
想想弹出窗口。它的框架由一个或多个 Sprite 构成,然后有一个可滚动的内容区域,用于隐藏框架外部的内容。一个容器和一个遮罩可以让这可滚动区域易于实现。添加容器,将其 mask
属性设置为具有矩形的图形对象,并将文本、图像等添加为该受遮罩的容器的子项,以便将其显示为内容。超出矩形遮罩的任何内容都将不会绘制。将容器的内容移动到所需的滚动位置。
// Create the application helper and add its render target to the page
let app = new Application({ width: 640, height: 360 });
document.body.appendChild(app.view);
// Create window frame
let frame = new Graphics({
x:320 - 104,
y:180 - 104
})
.rect(0, 0, 208, 208)
.fill(0x666666)
.stroke({ color: 0xffffff, width: 4, alignment: 0 })
app.stage.addChild(frame);
// Create a graphics object to define our mask
let mask = new Graphics()
// Add the rectangular area to show
.rect(0,0,200,200)
.fill(0xffffff);
// Add container that will hold our masked content
let maskContainer = new Container();
// Set the mask to use our graphics object from above
maskContainer.mask = mask;
// Add the mask as a child, so that the mask is positioned relative to its parent
maskContainer.addChild(mask);
// Offset by the window's frame width
maskContainer.position.set(4,4);
// And add the container to the window!
frame.addChild(maskContainer);
// Create contents for the masked container
let text = new Text({
text:'This text will scroll up and be masked, so you can see how masking works. Lorem ipsum and all that.\n\n' +
'You can put anything in the container and it will be masked!',
style:{
fontSize: 24,
fill: 0x1010ff,
wordWrap: true,
wordWrapWidth: 180
},
x:10
});
maskContainer.addChild(text);
// Add a ticker callback to scroll the text up and down
let elapsed = 0.0;
app.ticker.add((ticker) => {
// Update the text's y coordinate to scroll it
elapsed += ticker.deltaTime;
text.y = 10 + -100.0 + Math.cos(elapsed/50.0) * 100.0;
});
PixiJS 支持两种类型的遮罩
使用一个图形对象创建一个任意形状的遮罩 - 功能强大,但不支持抗锯齿
精灵:使用来自精灵的 Alpha 通道作为遮罩,提供抗锯齿边缘 - 画布渲染器不支持
滤镜
容器对象的另一个常见用途是作为滤镜内容的宿主。滤镜是一种高级 WebGL/WebGPU 专有功能,它允许 PixiJS 执行逐像素效果,如模糊和变换。通过在容器上设置滤镜,容器所包含的屏幕区域将在容器内容渲染后由滤镜处理。
以下是 PixiJS 中默认提供的滤镜列表。然而,有一个开源库,有更多滤镜。
滤镜 | 说明 |
---|---|
AlphaFilter | 与设置 alpha 属性类似,但它使容器扁平化,而不是单独应用于子项。 |
BlurFilter | 应用模糊效果 |
着色矩阵滤镜 | 作为一种灵活的方法,着色矩阵可用于应用更为复杂的色调或颜色转换(例如复古调)。 |
位移滤镜 | 位移贴图可创建视觉偏移像素,例如创建波浪水效果。 |
噪点滤镜 | 创建随机噪点(例如,颗粒效果)。 |
实际上,我们提供的每款现成滤镜都以 glsl(适用于 WebGL)和 wgsl(适用于 WebGPU)这两种语言编写。这意味着所有滤镜均应适用于这两种渲染器。
重要信息:滤镜的使用应较为谨慎。如果在一个场景中过于频繁地使用滤镜,则可能会降低性能并增加内存使用量。