UNPKG

6.46 kBJavaScriptView Raw
1"use strict";
2var constants = require("@pixi/constants"), extensions = require("@pixi/extensions"), SpriteMaskFilter = require("../filters/spriteMask/SpriteMaskFilter.js"), MaskData = require("./MaskData.js");
3class MaskSystem {
4 /**
5 * @param renderer - The renderer this System works for.
6 */
7 constructor(renderer) {
8 this.renderer = renderer, this.enableScissor = !0, this.alphaMaskPool = [], this.maskDataPool = [], this.maskStack = [], this.alphaMaskIndex = 0;
9 }
10 /**
11 * Changes the mask stack that is used by this System.
12 * @param maskStack - The mask stack
13 */
14 setMaskStack(maskStack) {
15 this.maskStack = maskStack, this.renderer.scissor.setMaskStack(maskStack), this.renderer.stencil.setMaskStack(maskStack);
16 }
17 /**
18 * Enables the mask and appends it to the current mask stack.
19 *
20 * NOTE: The batch renderer should be flushed beforehand to prevent pending renders from being masked.
21 * @param {PIXI.DisplayObject} target - Display Object to push the mask to
22 * @param {PIXI.MaskData|PIXI.Sprite|PIXI.Graphics|PIXI.DisplayObject} maskDataOrTarget - The masking data.
23 */
24 push(target, maskDataOrTarget) {
25 let maskData = maskDataOrTarget;
26 if (!maskData.isMaskData) {
27 const d = this.maskDataPool.pop() || new MaskData.MaskData();
28 d.pooled = !0, d.maskObject = maskDataOrTarget, maskData = d;
29 }
30 const maskAbove = this.maskStack.length !== 0 ? this.maskStack[this.maskStack.length - 1] : null;
31 if (maskData.copyCountersOrReset(maskAbove), maskData._colorMask = maskAbove ? maskAbove._colorMask : 15, maskData.autoDetect && this.detect(maskData), maskData._target = target, maskData.type !== constants.MASK_TYPES.SPRITE && this.maskStack.push(maskData), maskData.enabled)
32 switch (maskData.type) {
33 case constants.MASK_TYPES.SCISSOR:
34 this.renderer.scissor.push(maskData);
35 break;
36 case constants.MASK_TYPES.STENCIL:
37 this.renderer.stencil.push(maskData);
38 break;
39 case constants.MASK_TYPES.SPRITE:
40 maskData.copyCountersOrReset(null), this.pushSpriteMask(maskData);
41 break;
42 case constants.MASK_TYPES.COLOR:
43 this.pushColorMask(maskData);
44 break;
45 default:
46 break;
47 }
48 maskData.type === constants.MASK_TYPES.SPRITE && this.maskStack.push(maskData);
49 }
50 /**
51 * Removes the last mask from the mask stack and doesn't return it.
52 *
53 * NOTE: The batch renderer should be flushed beforehand to render the masked contents before the mask is removed.
54 * @param {PIXI.IMaskTarget} target - Display Object to pop the mask from
55 */
56 pop(target) {
57 const maskData = this.maskStack.pop();
58 if (!(!maskData || maskData._target !== target)) {
59 if (maskData.enabled)
60 switch (maskData.type) {
61 case constants.MASK_TYPES.SCISSOR:
62 this.renderer.scissor.pop(maskData);
63 break;
64 case constants.MASK_TYPES.STENCIL:
65 this.renderer.stencil.pop(maskData.maskObject);
66 break;
67 case constants.MASK_TYPES.SPRITE:
68 this.popSpriteMask(maskData);
69 break;
70 case constants.MASK_TYPES.COLOR:
71 this.popColorMask(maskData);
72 break;
73 default:
74 break;
75 }
76 if (maskData.reset(), maskData.pooled && this.maskDataPool.push(maskData), this.maskStack.length !== 0) {
77 const maskCurrent = this.maskStack[this.maskStack.length - 1];
78 maskCurrent.type === constants.MASK_TYPES.SPRITE && maskCurrent._filters && (maskCurrent._filters[0].maskSprite = maskCurrent.maskObject);
79 }
80 }
81 }
82 /**
83 * Sets type of MaskData based on its maskObject.
84 * @param maskData
85 */
86 detect(maskData) {
87 const maskObject = maskData.maskObject;
88 maskObject ? maskObject.isSprite ? maskData.type = constants.MASK_TYPES.SPRITE : this.enableScissor && this.renderer.scissor.testScissor(maskData) ? maskData.type = constants.MASK_TYPES.SCISSOR : maskData.type = constants.MASK_TYPES.STENCIL : maskData.type = constants.MASK_TYPES.COLOR;
89 }
90 /**
91 * Applies the Mask and adds it to the current filter stack.
92 * @param maskData - Sprite to be used as the mask.
93 */
94 pushSpriteMask(maskData) {
95 const { maskObject } = maskData, target = maskData._target;
96 let alphaMaskFilter = maskData._filters;
97 alphaMaskFilter || (alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex], alphaMaskFilter || (alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new SpriteMaskFilter.SpriteMaskFilter()])), alphaMaskFilter[0].resolution = maskData.resolution, alphaMaskFilter[0].multisample = maskData.multisample, alphaMaskFilter[0].maskSprite = maskObject;
98 const stashFilterArea = target.filterArea;
99 target.filterArea = maskObject.getBounds(!0), this.renderer.filter.push(target, alphaMaskFilter), target.filterArea = stashFilterArea, maskData._filters || this.alphaMaskIndex++;
100 }
101 /**
102 * Removes the last filter from the filter stack and doesn't return it.
103 * @param maskData - Sprite to be used as the mask.
104 */
105 popSpriteMask(maskData) {
106 this.renderer.filter.pop(), maskData._filters ? maskData._filters[0].maskSprite = null : (this.alphaMaskIndex--, this.alphaMaskPool[this.alphaMaskIndex][0].maskSprite = null);
107 }
108 /**
109 * Pushes the color mask.
110 * @param maskData - The mask data
111 */
112 pushColorMask(maskData) {
113 const currColorMask = maskData._colorMask, nextColorMask = maskData._colorMask = currColorMask & maskData.colorMask;
114 nextColorMask !== currColorMask && this.renderer.gl.colorMask(
115 (nextColorMask & 1) !== 0,
116 (nextColorMask & 2) !== 0,
117 (nextColorMask & 4) !== 0,
118 (nextColorMask & 8) !== 0
119 );
120 }
121 /**
122 * Pops the color mask.
123 * @param maskData - The mask data
124 */
125 popColorMask(maskData) {
126 const currColorMask = maskData._colorMask, nextColorMask = this.maskStack.length > 0 ? this.maskStack[this.maskStack.length - 1]._colorMask : 15;
127 nextColorMask !== currColorMask && this.renderer.gl.colorMask(
128 (nextColorMask & 1) !== 0,
129 (nextColorMask & 2) !== 0,
130 (nextColorMask & 4) !== 0,
131 (nextColorMask & 8) !== 0
132 );
133 }
134 destroy() {
135 this.renderer = null;
136 }
137}
138MaskSystem.extension = {
139 type: extensions.ExtensionType.RendererSystem,
140 name: "mask"
141};
142extensions.extensions.add(MaskSystem);
143exports.MaskSystem = MaskSystem;
144//# sourceMappingURL=MaskSystem.js.map