const PIXI = 'undefined' !== typeof window ? require('pixi.js') : undefined; import {Renderable} from './renderable'; export class Container extends Renderable { constructor() { super(); this._children = []; this._childrenIndexes = new Map(); this.container = PIXI ? new PIXI.Container() : undefined; } addChild(child) { child.parent = this; this.isDirty = true; const index = this._children.push(child) - 1; this._childrenIndexes.set(child, index); this.container.addChild(child.internal); } get children() { return this._children; } desaturate() { let filter = new PIXI.filters.ColorMatrixFilter(); filter.desaturate(); this.container.filters = [filter]; } destroy() { this.container.filters = []; this.children.forEach((child) => { this.removeChild(child); child.destroy(); }); super.destroy(); } get internal() { return this.container; } night(intensity = 1) { let filter; const {filters} = this.container; if ( filters && filters.length > 0 && filters[0] instanceof PIXI.filters.ColorMatrixFilter ) { filter = filters[0]; } else { filter = new PIXI.filters.ColorMatrixFilter(); } const nightness = 0.1; const double = nightness * 2; const half = nightness / 2; const redDown = 1 - (intensity * (1 + double)); const blueUp = 1 - (intensity * (1 - half)); const scale = intensity * nightness; const matrix = [ redDown , -scale , 0 , 0, 0, -scale , (1 - intensity), scale , 0, 0, 0 , scale , blueUp , 0, 0, 0 , 0 , 0 , 1, 0, ]; filter._loadMatrix(matrix); this.container.filters = [filter]; } paused(intensity = 1) { let filter = new PIXI.filters.ColorMatrixFilter(); filter.sepia(); filter.brightness(1 - intensity, true); this.container.filters = [filter]; } removeAllFilters() { this.container.filters = []; } _removeChild(child) { const index = this._children.indexOf(child); if (-1 === index) { return; } this._children.splice(index, 1); this.container.removeChild(child.internal); } removeChild(child) { this._removeChild(child); this._resetChildrenIndexes(); } removeAllChildren() { for (const child of this._children) { this._removeChild(child); } this._childrenIndexes = new Map(); } renderTick(elapsed) { for (let i = 0; i < this._children.length; i++) { const child = this._children[i]; if (child instanceof Container) { child.renderTick(elapsed); } } let needsSort = false; let currentZ = -Infinity; for (let i = 0; i < this._children.length; i++) { const child = this._children[i]; if (currentZ > child.zIndex) { needsSort = true; break; } currentZ = child.zIndex; } if (!needsSort) { return; } this._children.sort((l, r) => { if (l.zIndex !== r.zIndex) { return l.zIndex - r.zIndex; } const lIndex = this._childrenIndexes.get(l); const rIndex = this._childrenIndexes.get(r); return lIndex - rIndex; }); this.container.children = this._children.map((child) => { return child.internal; }); this._resetChildrenIndexes(); } _resetChildrenIndexes() { this._childrenIndexes = new Map(); for (const i in this._children) { const child = this._children[i]; this._childrenIndexes.set(child, i); } } sepia() { let filter = new PIXI.filters.ColorMatrixFilter(); filter.sepia(); this.container.filters = [filter]; } setFilter(filter) { switch (filter) { case 'bloom': const {AdvancedBloomFilter} = require('@pixi/filter-advanced-bloom'); this.container.filters = [new AdvancedBloomFilter({ threshold: 0.5, bloomScale: .8, brightness: 0.7, blur: 2, quality: 6, })]; break; } } }