### Install and Build PixiJS Layers Source: https://github.com/pixijs-userland/layers/blob/main/README.md Use npm to install dependencies and build the project. Ensure you have Node.js and npm installed. ```bash npm install npm run build ``` -------------------------------- ### Install @pixi/layers Source: https://github.com/pixijs-userland/layers/blob/main/README.md Install the package using npm. ```bash npm install --save @pixi/layers ``` -------------------------------- ### Setup PixiJS Application and Stage with Layers Source: https://github.com/pixijs-userland/layers/blob/main/examples/blend-modes.html Initializes a PixiJS application and replaces the default container with a PIXI.layers.Stage. A TilingSprite is added as a background. ```javascript const W = 800; const H = 600; const PAD = 80; const resolution = 1; const WIDTH = W / resolution; const HEIGHT = H / resolution; const app = new PIXI.Application({ width: WIDTH, height: HEIGHT, resolution, }); document.body.appendChild(app.view); app.stage = new PIXI.layers.Stage(); const background = new PIXI.TilingSprite( PIXI.Texture.from('assets/p2.jpg'), WIDTH, HEIGHT, ); app.stage.addChild(background); ``` -------------------------------- ### Install @pixi/layers Source: https://context7.com/pixijs-userland/layers/llms.txt Install the package from npm alongside your PixiJS v7 dependencies. ```bash npm install @pixi/layers # peer deps npm install @pixi/core @pixi/display ``` -------------------------------- ### Vanilla JS PixiJS Layers Setup Source: https://github.com/pixijs-userland/layers/blob/main/README.md Include the pixi-layers.js script in your HTML after pixi.min.js for use in vanilla JavaScript environments. ```html ``` -------------------------------- ### Interactive Sprite Setup Source: https://github.com/pixijs-userland/layers/blob/main/examples/z-order.html Configures sprites to be interactive, enabling drag-and-drop functionality by subscribing them to mouse and touch events. ```javascript function subscribe(obj) { obj.interactive = true; obj.on('mousedown', onDragStart) .on('touchstart', onDragStart) .on('mouseup', onDragEnd) .on('mouseupoutside', onDragEnd) .on('touchend', onDragEnd) .on('touchendoutside', onDragEnd); } app.stage .on('mousemove', onDragMove) .on('touchmove', onDragMove); let dragTarget = null; let dragPoint = new PIXI.Point(); ``` -------------------------------- ### Drag and Drop Handlers Source: https://github.com/pixijs-userland/layers/blob/main/examples/z-order.html Implements the logic for starting, ending, and moving a dragged sprite. When dragging starts, the sprite is moved to the drag group and scaled up. When dragging ends, it reverts to its original group and scale. ```javascript function onDragStart(event) { if (!dragTarget) { this.oldGroup = this.parentGroup; this.parentGroup = dragGroup; this.scale.x *= 1.1; this.scale.y *= 1.1; this.toLocal(event.global, null, dragPoint); dragTarget = this; } } function onDragEnd() { if (dragTarget) { this.parentGroup = this.oldGroup; this.scale.x /= 1.1; this.scale.y /= 1.1; dragTarget = null; } } function onDragMove(event) { if (dragTarget) { const newPosition = event.global; dragTarget.x = event.global.x - dragPoint.x; dragTarget.y = event.global.y - dragPoint.y; } } ``` -------------------------------- ### Intercept Group Sort Event Source: https://github.com/pixijs-userland/layers/blob/main/README.md Intercept the 'sort' event on a layer's group to dynamically set the zOrder for each item, for example, based on its y-position. ```javascript layer.group.on('sort', function onWillSort(sprite) { sprite.zOrder = sprite.y }); ``` -------------------------------- ### Initialize PixiJS Application and Layers Source: https://github.com/pixijs-userland/layers/blob/main/examples/z-order.html Sets up the PixiJS application and its stage with layers. Groups are defined with custom sorting logic for different types of sprites. ```javascript const app = new PIXI.Application({ backgroundColor: 0x1099bb }); document.body.appendChild(app.view); // META STUFF, groups exist without stage just fine // z-index = 0, sorting = true; const greenGroup = new PIXI.layers.Group(0, true); greenGroup.on('sort', (sprite) => { // green bunnies go down sprite.zOrder = sprite.y; }); // z-index = 1, sorting = true, we can provide zOrder function directly in constructor const blueGroup = new PIXI.layers.Group(1, ((sprite) => { // blue bunnies go up sprite.zOrder = -sprite.y; })); // Drag is the best layer, dragged element is above everything else const dragGroup = new PIXI.layers.Group(2, false); // Shadows are the lowest const shadowGroup = new PIXI.layers.Group(-1, false); // specify display list component app.stage = new PIXI.layers.Stage(); // PixiJS v5 sorting - works on zIndex - and layer gets its zIndex from a group! app.stage.sortableChildren = true; app.stage.interactive = true; app.stage.hitArea = app.screen; // sorry, group cant exist without layer yet (; app.stage.addChild(new PIXI.layers.Layer(greenGroup)); app.stage.addChild(new PIXI.layers.Layer(blueGroup)); app.stage.addChild(new PIXI.layers.Layer(dragGroup)); app.stage.addChild(new PIXI.layers.Layer(shadowGroup)); ``` -------------------------------- ### Create a Layer Instance Source: https://github.com/pixijs-userland/layers/blob/main/README.md Import and create a new Layer instance. This extends PIXI.Container. ```javascript import { Layer } from '@pixi/layers'; const layer = new Layer(); ``` -------------------------------- ### Create and Configure Lighting Layer Source: https://github.com/pixijs-userland/layers/blob/main/examples/blend-modes.html Sets up a PIXI.layers.Layer for lighting effects. It uses a render texture and applies the ADD blend mode on display. The clear color is set to ambient gray. ```javascript const lighting = new PIXI.layers.Layer(); lighting.on('display', (element) => { element.blendMode = PIXI.BLEND_MODES.ADD; }); lighting.useRenderTexture = true; lighting.clearColor = [0.5, 0.5, 0.5, 1]; // ambient gray app.stage.addChild(lighting); ``` -------------------------------- ### Initialize and Animate Bunnies Source: https://github.com/pixijs-userland/layers/blob/main/examples/blend-modes.html Creates 40 bunnies and adds them to a container. The application's ticker is used to continuously update the position of each bunny. ```javascript const bunnyTexture = PIXI.Texture.from('assets/bunny.png'); const bunnyWorld = new PIXI.Container(); app.stage.addChild(bunnyWorld); for (let i = 0; i < 40; i++) { bunnyWorld.addChild(createBunny()); } app.ticker.add(() => { bunnyWorld.children.forEach(updateBunny); }); ``` -------------------------------- ### Initialize Stage with @pixi/layers Source: https://context7.com/pixijs-userland/layers/llms.txt Replace the default PIXI.Container root with a Stage to enable the layers system. The Stage automatically updates when the renderer renders it. ```typescript import { Application } from 'pixi.js'; import { Stage } from '@pixi/layers'; const app = new Application({ width: 800, height: 600 }); document.body.appendChild(app.view); // Replace the default PIXI.Container root with a Stage const stage = new Stage(); app.stage = stage; // All children added to stage will participate in the layers system ``` -------------------------------- ### Vanilla JS Layer Instance Source: https://github.com/pixijs-userland/layers/blob/main/README.md Instantiate a PIXI.layers.Layer in a vanilla JavaScript context. ```javascript const layer = new PIXI.layers.Layer(); ``` -------------------------------- ### Create and Position Sprites with Groups Source: https://github.com/pixijs-userland/layers/blob/main/examples/z-order.html Generates green and blue bunny sprites, assigns them to specific groups, and adds them to the stage. Includes event listeners for interactivity. ```javascript const blurFilter = new PIXI.filters.BlurFilter(); blurFilter.blur = 0.5; // create a texture from an image path const textureGreen = PIXI.Texture.from('assets/bunny_green.png'); const textureBlue = PIXI.Texture.from('assets/bunny_blue.png'); // make obsolete containers. Why do we need them? // Just to show that we can do everything without caring of actual parent container const bunniesOdd = new PIXI.Container(); const bunniesEven = new PIXI.Container(); const bunniesBlue = new PIXI.Container(); app.stage.addChild(bunniesOdd); app.stage.addChild(bunniesBlue); app.stage.addChild(bunniesEven); for (let i = 0; i < 15; i++) { const bunny = new PIXI.Sprite(textureGreen); bunny.width = 50; bunny.height = 50; bunny.position.set(100 + 20 * i, 100 + 20 * i); bunny.anchor.set(0.5); // that thing is required bunny.parentGroup = greenGroup; if (i % 2 === 0) { bunniesEven.addChild(bunny); } else { bunniesOdd.addChild(bunny); } subscribe(bunny); addShadow(bunny); } for (let i = 9; i >= 0; i--) { const bunny = new PIXI.Sprite(textureBlue); bunny.width = 50; bunny.height = 50; bunny.position.set(400 + 20 * i, 400 - 20 * i); bunny.anchor.set(0.5); // that thing is required bunny.parentGroup = blueGroup; bunniesBlue.addChild(bunny); subscribe(bunny); addShadow(bunny); } ``` -------------------------------- ### ES6 Hipster Bring-to-Front/Back Source: https://github.com/pixijs-userland/layers/wiki/Home Provides functional utilities for manipulating array order, specifically for moving an item to the front or back. This approach uses ES6 features and creates new array instances. ```javascript //moves an item in an array to either the front or back export const PopTo = (isFront:boolean) => items => item => { const copy = items.concat(); const ret = copy.splice(copy.indexOf(item), 1); return (isFront) ? copy.concat(ret) : ret.concat(copy); } export const PopToFront = PopTo(true); export const PopToBack = PopTo(false); //move item to back this.children = PopToBack (this.children) (target) //move item to front this.children = PopToFront (this.children) (target) ``` -------------------------------- ### Create a Trail Effect with PixiJS Layers Source: https://github.com/pixijs-userland/layers/blob/main/examples/trail.html This snippet initializes a PixiJS application, sets up a layers stage, and creates a trail effect. The trail is generated by rendering a layer to a texture and displaying it as a semi-transparent sprite. It also adds animated bunnies that follow a circular path and rotate. ```javascript const app = new PIXI.Application({ backgroundColor: 0x1099bb }); document.body.appendChild(app.view); app.stage = new PIXI.layers.Stage(); const layer = new PIXI.layers.Layer(); layer.useRenderTexture = true; // this flag is required, or you'll get // "glDrawElements: Source and destination textures of the draw are the same." layer.useDoubleBuffer = true; const trailSprite = new PIXI.Sprite(layer.getRenderTexture()); trailSprite.alpha = 0.6; layer.addChild(trailSprite); app.stage.addChild(layer); const showLayer = new PIXI.Sprite(layer.getRenderTexture()); app.stage.addChild(showLayer); const bunnyTex = PIXI.Texture.from('assets/bunny.png'); const bunnies = []; for (let i = 0; i < 5; i++) { bunnies[i] = new PIXI.Container(); bunnies[i].position.set(app.screen.width / 2, app.screen.height / 2); bunnies[i].rotation = (i / 5) * (Math.PI * 2); bunnies[i].pivot.set(0, -200); const sprite = new PIXI.Sprite(bunnyTex); bunnies[i].addChild(sprite); sprite.anchor.set(0.5); sprite.scale.set(2 + Math.random()); layer.addChild(bunnies[i]); } // Listen for animate update app.ticker.add((delta) => { // just for fun, let's rotate mr rabbit a little // delta is 1 if running at 100% performance // creates frame-independent transformation for (let i = 0; i < bunnies.length; i++) { bunnies[i].rotation += 0.05 * delta; bunnies[i].children[0].rotation += 0.1 * delta; } }); ``` -------------------------------- ### Create Bunny with Light Source Source: https://github.com/pixijs-userland/layers/blob/main/examples/blend-modes.html Generates a bunny sprite with a random color lightbulb child. The lightbulb is assigned to the lighting layer, enabling it to contribute to the lighting effect. ```javascript function createBunny() { const bunny = new PIXI.Sprite(bunnyTexture); bunny.update = updateBunny; const angle = Math.random() * Math.PI * 2; const speed = 200.0; // px per second bunny.vx = Math.cos(angle) * speed / 60.0; bunny.vy = Math.sin(angle) * speed / 60.0; bunny.position.set(Math.random() * WIDTH, Math.random() * HEIGHT); bunny.anchor.set(0.5, 0.5); const lightbulb = new PIXI.Graphics(); const rr = Math.random() * 0x80 | 0; const rg = Math.random() * 0x80 | 0; const rb = Math.random() * 0x80 | 0; const rad = 50 + Math.random() * 20; lightbulb.beginFill((rr << 16) + (rg << 8) + rb, 1.0); lightbulb.drawCircle(0, 0, rad); lightbulb.endFill(); lightbulb.parentLayer = lighting;// <-- try comment it bunny.addChild(lightbulb); return bunny; } ``` -------------------------------- ### `applyParticleMixin(ParticleContainer)` Source: https://context7.com/pixijs-userland/layers/llms.txt Integrates PixiJS Layers functionality with `ParticleContainer`. This ensures that particle containers correctly respect `parentLayer` and `parentGroup` assignments and are skipped when not part of the active layer's children. ```APIDOC ## `applyParticleMixin(ParticleContainer)` `ParticleContainer` has its own optimised render path that bypasses the normal container render cycle. Call `applyParticleMixin` so particle containers respect `parentLayer`/`parentGroup` assignments and are correctly skipped when they are not the active layer's children. ```ts import { ParticleContainer } from 'pixi.js'; import { applyParticleMixin, Stage, Layer, Group } from '@pixi/layers'; applyParticleMixin(ParticleContainer); const stage = new Stage(); const fxGroup = new Group(3, false); const fxLayer = new Layer(fxGroup); stage.addChild(fxLayer); const particles = new ParticleContainer(10000, { position: true, alpha: true }); particles.parentGroup = fxGroup; // now works correctly stage.addChild(particles); ``` ``` -------------------------------- ### Create a New Display Group Source: https://github.com/pixijs-userland/layers/blob/main/README.md Create a new display group to manage sprites across different layers or stages. Assign sprites to this group and create a layer bound to it. ```javascript const lightGroup = new Group(); bunnySprite.parentGroup = lightGroup; const lightLayer = new Layer(lightGroup); ``` -------------------------------- ### Fast Container Sort with Z-Order Tracking Source: https://github.com/pixijs-userland/layers/wiki/Home Implements a custom PIXI.Container that sorts children based on zOrder and arrivalOrder, optimizing for frequent updates by only resorting changed elements. Requires manual calls to `sortChildren()` on the ticker or when changes occur. ```javascript const INF = 1e+100; let tmpChanged = [], tmpOld = []; let tmpArrivalCounter = 0; function awesomeCompare(a, b) { if (a.zOrder > b.zOrder) return 1; if (a.zOrder < b.zOrder) return -1; if (a.arrivalOrder > b.arrivalOrder) return 1; if (a.arrivalOrder < b.arrivalOrder) return -1; return 0; } class SContainer extends PIXI.Container { addChildZ(child, zOrder) { child.zOrder = zOrder || 0; // assign those vars whenever new element joins child.oldZOrder = INF; child.arrivalOrder = ++tmpArrivalCounter; super.addChild(child); } // you can call it every tick - its not heavy sortChildren() { const children = this.children; let len = children.length; for (let i = 0; i < len; i++) { const elem = children[i]; if (elem.zOrder !== elem.oldZOrder) { tmpChanged.push(elem); } else { tmpOld.push(elem); } elem.oldZOrder = elem.zOrder; } if (tmpChanged.length === 0) { tmpOld.length = 0; return; } if (tmpChanged.length > 1) { tmpChanged.sort(awesomeCompare); } let j = 0, a = 0, b = 0; while (a < tmpChanged.length && b < tmpOld.length) { if (awesomeCompare(tmpChanged[a], tmpOld[b]) < 0) { children[j++] = tmpChanged[a++]; } else { children[j++] = tmpOld[b++]; } } while (a < tmpChanged.length) { children[j++] = tmpChanged[a++]; } while (b < tmpOld.length) { children[j++] = tmpOld[b++]; } tmpChanged.length = 0; tmpOld.length = 0; } } ``` ```javascript var app = new PIXI.Application(800, 600, {backgroundColor: 0x1099bb}); document.body.appendChild(app.view); var texture_green = PIXI.Texture.fromImage('required/assets/bunnies/square_green.png'); var bunnies = new SContainer(); app.stage.addChild(bunnies); var FRONT = 10000;//FRONT zORder for (var i = 15; i >=0; i--) { var bunny = new PIXI.Sprite(texture_green); bunny.width = 50; bunny.height = 50; bunny.position.set(100 + 20 * i, 100 + 20 * i); bunny.anchor.set(0.5); bunnies.addChildZ(bunny, bunny.position.y); subscribe(bunny); } app.ticker.add(() => { bunnies.sortChildren(); }); function subscribe(obj) { obj.interactive = true; obj.on('mousedown', onDragStart) .on('touchstart', onDragStart) .on('mouseup', onDragEnd) .on('mouseupoutside', onDragEnd) .on('touchend', onDragEnd) .on('touchendoutside', onDragEnd) .on('mousemove', onDragMove) .on('touchmove', onDragMove); } function onDragStart(event) { if (!this.dragging) { this.data = event.data; this.dragging = true; this.zOrder = FRONT; this.scale.x *= 1.1; this.scale.y *= 1.1; this.dragPoint = event.data.getLocalPosition(this.parent); this.dragPoint.x -= this.x; this.dragPoint.y -= this.y; } } function onDragEnd() { if (this.dragging) { this.dragging = false; this.zOrder = this.position.y; this.scale.x /= 1.1; this.scale.y /= 1.1; // set the interaction data to null this.data = null; } } function onDragMove() { if (this.dragging) { var newPosition = this.data.getLocalPosition(this.parent); this.x = newPosition.x - this.dragPoint.x; this.y = newPosition.y - this.dragPoint.y; } } ``` -------------------------------- ### Create and Assign Sprites to Layers Source: https://context7.com/pixijs-userland/layers/llms.txt Create Layer instances and assign sprites to them using the `parentLayer` property. Layers are added to the stage and their `zIndex` determines draw order. ```typescript import { Sprite, Texture } from 'pixi.js'; import { Stage, Layer } from '@pixi/layers'; const stage = new Stage(); // Three layers: background drawn first, then characters, then UI on top const bgLayer = new Layer(); bgLayer.zIndex = 0; const charLayer = new Layer(); charLayer.zIndex = 1; const uiLayer = new Layer(); uiLayer.zIndex = 2; stage.addChild(bgLayer, charLayer, uiLayer); // These sprites are logically children of a "player" container ... const playerBody = new Sprite(Texture.from('body.png')); const playerName = new Sprite(Texture.from('name.png')); // ... but they render in their respective layers playerBody.parentLayer = charLayer; playerName.parentLayer = uiLayer; stage.addChild(playerBody, playerName); // scene-graph parents are stage // Result: playerBody is drawn in pass 1, playerName in pass 2 ``` -------------------------------- ### Enable Double Buffering for Motion Trails Source: https://context7.com/pixijs-userland/layers/llms.txt Use `useDoubleBuffer = true` with `useRenderTexture = true` to keep the previous frame readable for effects like motion trails. Set a near-transparent `clearColor` for a fading effect. ```typescript import { Sprite, BLEND_MODES } from 'pixi.js'; import { Stage, Layer, Group } from '@pixi/layers'; const stage = new Stage(); const trailGroup = new Group(0, false); const trailLayer = new Layer(trailGroup); trailLayer.useRenderTexture = true; trailLayer.useDoubleBuffer = true; // previous frame stays readable trailLayer.clearColor = [0, 0, 0, 0.05]; // near-transparent clear = fade effect stage.addChild(trailLayer); // Sprite that renders the previous frame back into the current frame const feedback = new Sprite(trailLayer.getRenderTexture()); feedback.parentGroup = trailGroup; // renders inside the layer itself const particle = new Sprite(/* ... */); particle.parentGroup = trailGroup; stage.addChild(feedback, particle); // Result: a motion-trail effect as old frames fade out ``` -------------------------------- ### Simple Insertion Sort for PixiJS Container Source: https://github.com/pixijs-userland/layers/wiki/Home Implement a custom container that sorts children based on a zOrder property, with arrivalOrder as a tie-breaker. This is suitable for projects that require simple sorting within a container without needing stage-wide sorting. ```javascript class DContainer extends Container { addChildZ(container, zOrder) { container.zOrder = zOrder || 0; container.arrivalOrder = this.children.length; this.addChild(container); this.sortChildren(); } sortChildren() { const _children = this.children; let len = _children.length, i, j, tmp; for (i = 1; i < len; i++) { tmp = _children[i]; j = i - 1; while (j >= 0) { if (tmp.zOrder < _children[j].zOrder) { _children[j + 1] = _children[j]; } else if (tmp.zOrder === _children[j].zOrder && tmp.arrivalOrder < _children[j].arrivalOrder) { _children[j + 1] = _children[j]; } else { break; } j--; } _children[j + 1] = tmp; } }; } ``` -------------------------------- ### `applyCanvasMixin(CanvasRenderer)` Source: https://context7.com/pixijs-userland/layers/llms.txt Applies the PixiJS Layers mixin to the legacy CanvasRenderer. This must be called manually after importing `CanvasRenderer` if you intend to use canvas rendering with layer and group assignments. ```APIDOC ## `applyCanvasMixin(CanvasRenderer)` The WebGL renderer mixin is applied automatically on import. For PixiJS's legacy canvas renderer, call `applyCanvasMixin` manually after importing `CanvasRenderer`. ```ts import { CanvasRenderer } from '@pixi/canvas-renderer'; import { applyCanvasMixin } from '@pixi/layers'; // Must be called once before creating any Stage/Layer with canvas rendering applyCanvasMixin(CanvasRenderer); // Canvas rendering now fully supports parentLayer / parentGroup assignments ``` ``` -------------------------------- ### Apply Particle Container Mixin Source: https://github.com/pixijs-userland/layers/blob/main/README.md If using @pixi/particles, apply the particle mixin from @pixi/layers to enable layer functionality with ParticleContainer. ```javascript import { ParticleContainer } from 'pixi.js'; import { applyCanvasMixin } from '@pixi/layers'; applyParticleMixin(ParticleContainer); ``` -------------------------------- ### Apply Multiply Blend Mode to Lighting Sprite Source: https://github.com/pixijs-userland/layers/blob/main/examples/blend-modes.html Creates a sprite from the lighting layer's render texture and applies the MULTIPLY blend mode to it. This sprite is then added to the main stage. ```javascript const lightingSprite = new PIXI.Sprite(lighting.getRenderTexture()); lightingSprite.blendMode = PIXI.BLEND_MODES.MULTIPLY; app.stage.addChild(lightingSprite); ``` -------------------------------- ### Apply Canvas Renderer Mixin Source: https://github.com/pixijs-userland/layers/blob/main/README.md If using @pixi/canvas-renderer, apply the canvas mixin from @pixi/layers to enable layer functionality. ```javascript import { CanvasRenderer } from 'pixi.js-legacy'; import { applyCanvasMixin } from '@pixi/layers'; applyCanvasMixin(CanvasRenderer); ``` -------------------------------- ### `applyContainerRenderMixin(CustomContainer.prototype)` Source: https://context7.com/pixijs-userland/layers/llms.txt Patches the prototype of a custom `Container` subclass to ensure it correctly skips rendering when it belongs to a non-active layer, preventing potential double-draw issues. ```APIDOC ## `applyContainerRenderMixin(CustomContainer.prototype)` Use this when you have a custom `Container` subclass with its own `render` method. It wraps the render method so the container correctly skips rendering when it belongs to a layer that is not currently active, preventing double-draws. ```ts import { Container } from '@pixi/display'; import { applyContainerRenderMixin } from '@pixi/layers'; class TilemapContainer extends Container { render(renderer: any) { // custom tile rendering ... super.render(renderer); } } // Patch the prototype once, before any instances are created applyContainerRenderMixin(TilemapContainer.prototype); // TilemapContainer instances can now safely use parentLayer / parentGroup ``` ``` -------------------------------- ### Apply Canvas Renderer Mixin Source: https://context7.com/pixijs-userland/layers/llms.txt Call `applyCanvasMixin(CanvasRenderer)` once after importing `CanvasRenderer` to enable PixiJS's legacy canvas renderer to fully support `parentLayer`/`parentGroup` assignments. ```typescript import { CanvasRenderer } from '@pixi/canvas-renderer'; import { applyCanvasMixin } from '@pixi/layers'; // Must be called once before creating any Stage/Layer with canvas rendering applyCanvasMixin(CanvasRenderer); // Canvas rendering now fully supports parentLayer / parentGroup assignments ``` -------------------------------- ### Dynamic Sorting with Group Sort Callback Source: https://context7.com/pixijs-userland/layers/llms.txt Instead of manually setting `zOrder`, provide a callback to the `Group` constructor for dynamic sorting. This callback is invoked before each sort pass, ideal for behaviors like isometric depth sorting based on the object's `y` position. ```typescript import { Stage, Layer, Group } from '@pixi/layers'; import { Sprite } from 'pixi.js'; // Callback automatically sets zOrder = y before each sort pass const depthGroup = new Group(0, (sprite) => { sprite.zOrder = (sprite as Sprite).y; }); const depthLayer = new Layer(depthGroup); const stage = new Stage(); stage.addChild(depthLayer); for (let i = 0; i < 5; i++) { const s = Sprite.from('character.png'); s.y = Math.random() * 400; s.parentGroup = depthGroup; stage.addChild(s); } // No per-frame zOrder updates needed — the callback handles it each render ``` -------------------------------- ### Configure Group for Layer Sorting Source: https://context7.com/pixijs-userland/layers/llms.txt Create a Group with a zIndex and enable sorting. Assign objects to this group using `parentGroup`. Define a custom sort function to control the order within the layer. ```typescript import { Sprite, Texture } from 'pixi.js'; import { Stage, Layer, Group } from '@pixi/layers'; const stage = new Stage(); // Create a group at zIndex=1 with sorting enabled const charGroup = new Group(1, true); const charLayer = new Layer(charGroup); stage.addChild(charLayer); const bunny1 = new Sprite(Texture.from('bunny.png')); const bunny2 = new Sprite(Texture.from('bunny.png')); bunny1.position.set(100, 200); bunny2.position.set(150, 100); // Assign group membership; objects are sorted by zOrder ascending bunny1.parentGroup = charGroup; bunny2.parentGroup = charGroup; // Sort by y-position so lower sprites appear in front (isometric style) charGroup.on('sort', (sprite) => { sprite.zOrder = sprite.y; }); stage.addChild(bunny1, bunny2); // bunny2 (y=100) renders before bunny1 (y=200) → bunny1 appears "in front" ``` -------------------------------- ### `Layer.useDoubleBuffer` Source: https://context7.com/pixijs-userland/layers/llms.txt Enables double buffering for a layer, which is useful for effects like trails and feedback by keeping two RenderTextures and alternating between them. This feature requires `useRenderTexture = true` to be set on the layer. ```APIDOC ## `Layer.useDoubleBuffer` Double buffering keeps two `RenderTexture`s for a layer and alternates between them each frame. This is useful for trail/feedback effects where the previous frame's output is sampled while rendering the new frame. Must be used together with `useRenderTexture = true`. ```ts import { Sprite, BLEND_MODES } from 'pixi.js'; import { Stage, Layer, Group } from '@pixi/layers'; const stage = new Stage(); const trailGroup = new Group(0, false); const trailLayer = new Layer(trailGroup); trailLayer.useRenderTexture = true; trailLayer.useDoubleBuffer = true; // previous frame stays readable trailLayer.clearColor = [0, 0, 0, 0.05]; // near-transparent clear = fade effect stage.addChild(trailLayer); // Sprite that renders the previous frame back into the current frame const feedback = new Sprite(trailLayer.getRenderTexture()); feedback.parentGroup = trailGroup; // renders inside the layer itself const particle = new Sprite(/* ... */); particle.parentGroup = trailGroup; stage.addChild(feedback, particle); // Result: a motion-trail effect as old frames fade out ``` ``` -------------------------------- ### Automatic Stage Update Source: https://github.com/pixijs-userland/layers/blob/main/README.md When using a Stage as the root and rendering with the PixiJS renderer, 'updateStage' is called automatically. You can check sorted children after rendering. ```javascript renderer.render(stage); console.log(layer._sortedChildren); ``` -------------------------------- ### `Stage.updateStage()` Source: https://context7.com/pixijs-userland/layers/llms.txt Manually triggers the scene tree traversal and layer resolution process. Normally called automatically during `renderer.render(stage)`, this method is useful for inspecting sorted children outside the render loop. ```APIDOC ## `Stage.updateStage()` `updateStage()` traverses the entire scene tree, resolves every `DisplayObject` to its target `Layer`, and prepares the sorted child lists. It is called automatically by the renderer mixin when `renderer.render(stage)` is invoked. Call it manually only if you need to inspect `layer._sortedChildren` outside of the render loop. ```ts import { Stage, Layer, Group } from '@pixi/layers'; import { Sprite } from 'pixi.js'; const stage = new Stage(); const group = new Group(0, true); const layer = new Layer(group); stage.addChild(layer); const a = Sprite.from('a.png'); a.zOrder = 2; a.parentGroup = group; const b = Sprite.from('b.png'); b.zOrder = 1; b.parentGroup = group; stage.addChild(a, b); // Manually trigger stage resolution (normally automatic) stage.updateStage(); console.log(layer._sortedChildren); // → [b, a] (b has lower zOrder → renders first → appears behind a) ``` ``` -------------------------------- ### Apply Particle Container Mixin Source: https://context7.com/pixijs-userland/layers/llms.txt Call `applyParticleMixin(ParticleContainer)` to make `ParticleContainer` respect `parentLayer`/`parentGroup` assignments and be correctly skipped when not part of the active layer. This is necessary because `ParticleContainer` bypasses the normal container render cycle. ```typescript import { ParticleContainer } from 'pixi.js'; import { applyParticleMixin, Stage, Layer, Group } from '@pixi/layers'; applyParticleMixin(ParticleContainer); const stage = new Stage(); const fxGroup = new Group(3, false); const fxLayer = new Layer(fxGroup); stage.addChild(fxLayer); const particles = new ParticleContainer(10000, { position: true, alpha: true }); particles.parentGroup = fxGroup; // now works correctly stage.addChild(particles); ``` -------------------------------- ### Bunny Update Logic Source: https://github.com/pixijs-userland/layers/blob/main/examples/blend-modes.html Defines a function to update the position of a bunny sprite, handling boundary wrapping within the application's dimensions. ```javascript function updateBunny(bunny) { bunny.x += bunny.vx; bunny.y += bunny.vy; if (bunny.x > WIDTH + PAD) { bunny.x -= WIDTH + 2 * PAD; } if (bunny.x < -PAD) { bunny.x += WIDTH + 2 * PAD; } if (bunny.y > HEIGHT + PAD) { bunny.y -= HEIGHT + 2 * PAD; } if (bunny.y < -PAD) { bunny.y += HEIGHT + 2 * PAD; } } ``` -------------------------------- ### Layer Filter Area Configuration Source: https://github.com/pixijs-userland/layers/blob/main/README.md To ensure filters work correctly on layers, set the layer's filterArea to the renderer's screen dimensions. ```javascript layer.filterArea = renderer.screen; ``` -------------------------------- ### Assign DisplayObject to a Layer Source: https://github.com/pixijs-userland/layers/blob/main/README.md Assign a DisplayObject or Container to a specific layer instead of its direct parent. ```javascript bunnySprite.parentLayer = layer; ``` -------------------------------- ### Apply Custom Container Render Mixin Source: https://context7.com/pixijs-userland/layers/llms.txt Use `applyContainerRenderMixin(CustomContainer.prototype)` to wrap the render method of a custom `Container` subclass. This ensures the container correctly skips rendering when it belongs to a non-active layer, preventing double-draws. ```typescript import { Container } from '@pixi/display'; import { applyContainerRenderMixin } from '@pixi/layers'; class TilemapContainer extends Container { render(renderer: any) { // custom tile rendering ... super.render(renderer); } } // Patch the prototype once, before any instances are created applyContainerRenderMixin(TilemapContainer.prototype); // TilemapContainer instances can now safely use parentLayer / parentGroup ``` -------------------------------- ### Layer Ordering with zOrder Source: https://github.com/pixijs-userland/layers/blob/main/README.md Set zOrder on sprites within a layer to control their rendering order. Enable sorting on the layer's group. ```javascript bunnySprite.zOrder = 2; cloudSprite.zOrder = 1; badCloudSprite.zOrder = 1.01; layer.group.enableSort = true; ``` -------------------------------- ### Bring Element to Top with PixiJS Layers Source: https://github.com/pixijs-userland/layers/blob/main/examples/bring-to-top.html Assign a sprite to a specific layer to ensure it renders above all other elements. This is useful for UI elements or pop-ups that need to be persistently visible. ```javascript const app = new PIXI.Application({ backgroundColor: 0x1099bb }); document.body.appendChild(app.view); const textureGreen = PIXI.Texture.from('assets/bunny_green.png'); const textureBlue = PIXI.Texture.from('assets/bunny_blue.png'); const blue = new PIXI.Container(); const green = new PIXI.Container(); app.stage = new PIXI.layers.Stage(); const topLayer = new PIXI.layers.Layer(); app.stage.addChild(blue, green, topLayer); for (let i = 0; i < 15; i++) { const bunny = new PIXI.Sprite(textureGreen); bunny.width = 50; bunny.height = 50; bunny.position.set(100 + 20 * i, 100 + 20 * i); bunny.anchor.set(0.5); green.addChild(bunny); } for (let i = 9; i >= 0; i--) { const bunny = new PIXI.Sprite(textureBlue); bunny.width = 50; bunny.height = 50; bunny.position.set(100 + 20 * i, 150 + 20 * i); bunny.anchor.set(0.5); if (i === 9) { bunny.tint = 0xFF0000; bunny.parentLayer = topLayer; } blue.addChild(bunny); } ``` -------------------------------- ### Check Layer's Sorted Children Source: https://github.com/pixijs-userland/layers/blob/main/README.md After updating the stage, you can inspect the sorted children of a layer. The order of rendering is shown in the comment. ```javascript stage.updateStage(); console.log(layer._sortedChildren); // Order of rendering: // bunnySprite (index=1) // badCloudSprite (index=2, order=1) // cloudSprite (index=2, order=0) ``` -------------------------------- ### Assign Display Object to a Specific Layer Source: https://context7.com/pixijs-userland/layers/llms.txt Use `parentLayer` to directly bind a display object to a specific `Layer` instance. This is suitable when you have a direct reference to the target layer. ```typescript import { Graphics } from 'pixi.js'; import { Stage, Layer } from '@pixi/layers'; const stage = new Stage(); const lightLayer = new Layer(); lightLayer.zIndex = 10; stage.addChild(lightLayer); const glowCircle = new Graphics(); glowCircle.beginFill(0xffff00, 0.4).drawCircle(0, 0, 60).endFill(); glowCircle.position.set(200, 200); // Render glowCircle inside lightLayer, not at its scene-graph position glowCircle.parentLayer = lightLayer; stage.addChild(glowCircle); ``` -------------------------------- ### Render Layer Contents to a RenderTexture Source: https://context7.com/pixijs-userland/layers/llms.txt Enable `useRenderTexture` on a `Layer` to render its contents into an off-screen `RenderTexture`. This texture can then be used in other sprites, for post-processing filters, or for lighting effects. The texture automatically resizes with the renderer. ```typescript import { Sprite, Texture } from 'pixi.js'; import { Stage, Layer, Group } from '@pixi/layers'; const stage = new Stage(); // Layer that captures all "light" sprites into a texture const lightGroup = new Group(5, false); const lightLayer = new Layer(lightGroup); lightLayer.useRenderTexture = true; lightLayer.clearColor = [0, 0, 0, 1]; // clear to opaque black each frame stage.addChild(lightLayer); // Composite the light texture on top with MULTIPLY blend const lightOverlay = new Sprite(lightLayer.getRenderTexture()); lightOverlay.blendMode = PIXI.BLEND_MODES.MULTIPLY; stage.addChild(lightOverlay); // Any sprite assigned to lightGroup will be captured into the texture const torch = new Sprite(Texture.from('torch_light.png')); torch.parentGroup = lightGroup; stage.addChild(torch); ``` -------------------------------- ### Assign Display Object to a Group for Layer Membership Source: https://context7.com/pixijs-userland/layers/llms.txt Use `parentGroup` to bind an object to a `Group`. The object will be rendered in whichever `Layer` currently holds that group, allowing for portable layer membership. ```typescript import { Container, Sprite, Texture } from 'pixi.js'; import { Stage, Layer, Group } from '@pixi/layers'; const shadowGroup = new Group(0, false); const bodyGroup = new Group(1, false); function buildScene(shadowTex: Texture, bodyTex: Texture): Stage { const stage = new Stage(); stage.addChild(new Layer(shadowGroup)); // zIndex from group stage.addChild(new Layer(bodyGroup)); const enemy = new Container(); const shadow = new Sprite(shadowTex); const body = new Sprite(bodyTex); shadow.parentGroup = shadowGroup; body.parentGroup = bodyGroup; enemy.addChild(shadow, body); stage.addChild(enemy); return stage; } ``` -------------------------------- ### Manually Update Stage for Z-Order Inspection Source: https://context7.com/pixijs-userland/layers/llms.txt Call `stage.updateStage()` manually if you need to inspect `layer._sortedChildren` outside the automatic render loop. This traverses the scene tree and prepares sorted child lists. ```typescript import { Stage, Layer, Group } from '@pixi/layers'; import { Sprite } from 'pixi.js'; const stage = new Stage(); const group = new Group(0, true); const layer = new Layer(group); stage.addChild(layer); const a = Sprite.from('a.png'); a.zOrder = 2; a.parentGroup = group; const b = Sprite.from('b.png'); b.zOrder = 1; b.parentGroup = group; stage.addChild(a, b); // Manually trigger stage resolution (normally automatic) stage.updateStage(); console.log(layer._sortedChildren); // → [b, a] (b has lower zOrder → renders first → appears behind a) ``` -------------------------------- ### Add Shadow to Sprite Source: https://github.com/pixijs-userland/layers/blob/main/examples/z-order.html Creates a shadow effect for a sprite by drawing a scaled rectangle with a blur filter and assigning it to the shadow group. ```javascript function addShadow(obj) { const gr = new PIXI.Graphics(); gr.beginFill(0x0, 1); // yes , I know bunny size, I'm sorry for this hack const scale = 1.1; gr.drawRect(-25 / 2 * scale, -36 / 2 * scale, 25 * scale, 36 * scale); gr.endFill(); gr.filters = [blurFilter]; gr.parentGroup = shadowGroup; obj.addChild(gr); } ``` -------------------------------- ### Assign Sprite to Layer in PixiJS Source: https://github.com/pixijs-userland/layers/wiki/Home Assign a sprite or container to a specific layer to control its rendering order and optimize draw calls. This is useful for grouping similar elements like player bodies, health bars, or names. ```javascript PlayerName.parentLayer = NameLayer; PlayerHealth.parentLayer = HealthLayer; PlayerBody.parentLayer = PlayerLayer; ``` -------------------------------- ### Set Group Sort Priority Source: https://github.com/pixijs-userland/layers/blob/main/README.md Set the 'sortPriority' on a group to influence sorting behavior for children with different parentLayers than their direct parent. Priority 1 is for special cases. ```javascript layer.group.sortPriority = 1; ``` -------------------------------- ### Control Draw Order Within a Layer Using zOrder Source: https://context7.com/pixijs-userland/layers/llms.txt The `zOrder` property controls the draw order within a layer when `Group.enableSort` is true. Lower values render first. Objects are grouped by `zIndex` and then sorted by `zOrder` within each group. ```typescript import { Sprite, Texture } from 'pixi.js'; import { Stage, Layer, Group } from '@pixi/layers'; const stage = new Stage(); const isoGroup = new Group(0, true); // sorting on const isoLayer = new Layer(isoGroup); stage.addChild(isoLayer); const sprites = [ { tex: 'tree.png', x: 300, y: 400 }, { tex: 'rock.png', x: 200, y: 250 }, { tex: 'player.png', x: 250, y: 350 }, ].map(({ tex, x, y }) => { const s = Sprite.from(tex); s.position.set(x, y); s.parentGroup = isoGroup; // sort by y so objects lower on screen render last (appear in front) s.zOrder = y; stage.addChild(s); return s; }); // tree (y=400) renders last → appears in front of player (y=350) and rock (y=250) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.