UNPKG

6.05 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var MaskData = require('./MaskData.js');
6var SpriteMaskFilter = require('../filters/spriteMask/SpriteMaskFilter.js');
7var constants = require('@pixi/constants');
8var extensions = require('@pixi/extensions');
9
10class MaskSystem {
11 constructor(renderer) {
12 this.renderer = renderer;
13 this.enableScissor = true;
14 this.alphaMaskPool = [];
15 this.maskDataPool = [];
16 this.maskStack = [];
17 this.alphaMaskIndex = 0;
18 }
19 setMaskStack(maskStack) {
20 this.maskStack = maskStack;
21 this.renderer.scissor.setMaskStack(maskStack);
22 this.renderer.stencil.setMaskStack(maskStack);
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 = true;
29 d.maskObject = maskDataOrTarget;
30 maskData = d;
31 }
32 const maskAbove = this.maskStack.length !== 0 ? this.maskStack[this.maskStack.length - 1] : null;
33 maskData.copyCountersOrReset(maskAbove);
34 maskData._colorMask = maskAbove ? maskAbove._colorMask : 15;
35 if (maskData.autoDetect) {
36 this.detect(maskData);
37 }
38 maskData._target = target;
39 if (maskData.type !== constants.MASK_TYPES.SPRITE) {
40 this.maskStack.push(maskData);
41 }
42 if (maskData.enabled) {
43 switch (maskData.type) {
44 case constants.MASK_TYPES.SCISSOR:
45 this.renderer.scissor.push(maskData);
46 break;
47 case constants.MASK_TYPES.STENCIL:
48 this.renderer.stencil.push(maskData);
49 break;
50 case constants.MASK_TYPES.SPRITE:
51 maskData.copyCountersOrReset(null);
52 this.pushSpriteMask(maskData);
53 break;
54 case constants.MASK_TYPES.COLOR:
55 this.pushColorMask(maskData);
56 break;
57 default:
58 break;
59 }
60 }
61 if (maskData.type === constants.MASK_TYPES.SPRITE) {
62 this.maskStack.push(maskData);
63 }
64 }
65 pop(target) {
66 const maskData = this.maskStack.pop();
67 if (!maskData || maskData._target !== target) {
68 return;
69 }
70 if (maskData.enabled) {
71 switch (maskData.type) {
72 case constants.MASK_TYPES.SCISSOR:
73 this.renderer.scissor.pop(maskData);
74 break;
75 case constants.MASK_TYPES.STENCIL:
76 this.renderer.stencil.pop(maskData.maskObject);
77 break;
78 case constants.MASK_TYPES.SPRITE:
79 this.popSpriteMask(maskData);
80 break;
81 case constants.MASK_TYPES.COLOR:
82 this.popColorMask(maskData);
83 break;
84 default:
85 break;
86 }
87 }
88 maskData.reset();
89 if (maskData.pooled) {
90 this.maskDataPool.push(maskData);
91 }
92 if (this.maskStack.length !== 0) {
93 const maskCurrent = this.maskStack[this.maskStack.length - 1];
94 if (maskCurrent.type === constants.MASK_TYPES.SPRITE && maskCurrent._filters) {
95 maskCurrent._filters[0].maskSprite = maskCurrent.maskObject;
96 }
97 }
98 }
99 detect(maskData) {
100 const maskObject = maskData.maskObject;
101 if (!maskObject) {
102 maskData.type = constants.MASK_TYPES.COLOR;
103 } else if (maskObject.isSprite) {
104 maskData.type = constants.MASK_TYPES.SPRITE;
105 } else if (this.enableScissor && this.renderer.scissor.testScissor(maskData)) {
106 maskData.type = constants.MASK_TYPES.SCISSOR;
107 } else {
108 maskData.type = constants.MASK_TYPES.STENCIL;
109 }
110 }
111 pushSpriteMask(maskData) {
112 const { maskObject } = maskData;
113 const target = maskData._target;
114 let alphaMaskFilter = maskData._filters;
115 if (!alphaMaskFilter) {
116 alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex];
117 if (!alphaMaskFilter) {
118 alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new SpriteMaskFilter.SpriteMaskFilter()];
119 }
120 }
121 const renderer = this.renderer;
122 const renderTextureSystem = renderer.renderTexture;
123 let resolution;
124 let multisample;
125 if (renderTextureSystem.current) {
126 const renderTexture = renderTextureSystem.current;
127 resolution = maskData.resolution || renderTexture.resolution;
128 multisample = maskData.multisample ?? renderTexture.multisample;
129 } else {
130 resolution = maskData.resolution || renderer.resolution;
131 multisample = maskData.multisample ?? renderer.multisample;
132 }
133 alphaMaskFilter[0].resolution = resolution;
134 alphaMaskFilter[0].multisample = multisample;
135 alphaMaskFilter[0].maskSprite = maskObject;
136 const stashFilterArea = target.filterArea;
137 target.filterArea = maskObject.getBounds(true);
138 renderer.filter.push(target, alphaMaskFilter);
139 target.filterArea = stashFilterArea;
140 if (!maskData._filters) {
141 this.alphaMaskIndex++;
142 }
143 }
144 popSpriteMask(maskData) {
145 this.renderer.filter.pop();
146 if (maskData._filters) {
147 maskData._filters[0].maskSprite = null;
148 } else {
149 this.alphaMaskIndex--;
150 this.alphaMaskPool[this.alphaMaskIndex][0].maskSprite = null;
151 }
152 }
153 pushColorMask(maskData) {
154 const currColorMask = maskData._colorMask;
155 const nextColorMask = maskData._colorMask = currColorMask & maskData.colorMask;
156 if (nextColorMask !== currColorMask) {
157 this.renderer.gl.colorMask((nextColorMask & 1) !== 0, (nextColorMask & 2) !== 0, (nextColorMask & 4) !== 0, (nextColorMask & 8) !== 0);
158 }
159 }
160 popColorMask(maskData) {
161 const currColorMask = maskData._colorMask;
162 const nextColorMask = this.maskStack.length > 0 ? this.maskStack[this.maskStack.length - 1]._colorMask : 15;
163 if (nextColorMask !== currColorMask) {
164 this.renderer.gl.colorMask((nextColorMask & 1) !== 0, (nextColorMask & 2) !== 0, (nextColorMask & 4) !== 0, (nextColorMask & 8) !== 0);
165 }
166 }
167 destroy() {
168 this.renderer = null;
169 }
170}
171MaskSystem.extension = {
172 type: extensions.ExtensionType.RendererSystem,
173 name: "mask"
174};
175extensions.extensions.add(MaskSystem);
176
177exports.MaskSystem = MaskSystem;
178//# sourceMappingURL=MaskSystem.js.map