@next2d/display 1.14.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1775 @@
1
+ import { InteractiveObject } from "./InteractiveObject";
2
+ import { Event as Next2DEvent } from "@next2d/events";
3
+ import { $createInstance, $currentPlayer, $hitContext, $isTouch, $MATRIX_HIT_ARRAY_IDENTITY, $rendererWorker } from "@next2d/util";
4
+ import { $doUpdated, $boundsMatrix, $clamp, $getArray, $getBoundsObject, $getFloat32Array6, $getFloat32Array8, $getMap, $getPreObject, $Math, $COLOR_ARRAY_IDENTITY, $MATRIX_ARRAY_IDENTITY, $multiplicationColor, $multiplicationMatrix, $Number, $poolArray, $poolBoundsObject, $poolFloat32Array6, $poolFloat32Array8, $poolMap, $poolPreObject } from "@next2d/share";
5
+ /**
6
+ * DisplayObjectContainer クラスは、表示リストで表示オブジェクトコンテナとして機能するすべてのオブジェクトの基本クラスです。
7
+ * このクラス自体は、画面上でのコンテンツの描画のための API を含みません。
8
+ * そのため、DisplayObject クラスのカスタムサブクラスを作成する場合は、
9
+ * Sprite、または MovieClip など、画面上にコンテンツを描画する API を持つサブクラスの 1 つを拡張する必要があります。
10
+ *
11
+ * The DisplayObjectContainer class is the base class for all objects that can serve
12
+ * as display object containers on the display list.
13
+ * This class itself does not contain any API for drawing content on the screen.
14
+ * Therefore, if you want to create a custom subclass of the DisplayObject class,
15
+ * you need to extend one of its subclasses that has an API for drawing content on the screen,
16
+ * such as Sprite or MovieClip.
17
+ *
18
+ * @class
19
+ * @memberOf next2d.display
20
+ * @extends InteractiveObject
21
+ */
22
+ export class DisplayObjectContainer extends InteractiveObject {
23
+ /**
24
+ * @constructor
25
+ * @public
26
+ */
27
+ constructor() {
28
+ super();
29
+ /**
30
+ * @type {array}
31
+ * @default null
32
+ * @private
33
+ */
34
+ this._$placeMap = null;
35
+ /**
36
+ * @type {array}
37
+ * @default null
38
+ * @private
39
+ */
40
+ this._$placeObjects = null;
41
+ /**
42
+ * @type {array}
43
+ * @default null
44
+ * @private
45
+ */
46
+ this._$controller = null;
47
+ /**
48
+ * @type {array}
49
+ * @default null
50
+ * @private
51
+ */
52
+ this._$dictionary = null;
53
+ /**
54
+ * @type {array}
55
+ * @private
56
+ */
57
+ this._$children = $getArray();
58
+ /**
59
+ * @type {boolean}
60
+ * @default true
61
+ * @private
62
+ */
63
+ this._$needsChildren = true;
64
+ /**
65
+ * @type {boolean}
66
+ * @default true
67
+ * @private
68
+ */
69
+ this._$mouseChildren = true;
70
+ /**
71
+ * @type {boolean}
72
+ * @default true
73
+ * @private
74
+ */
75
+ this._$wait = true;
76
+ /**
77
+ * @type {Map}
78
+ * @private
79
+ */
80
+ this._$names = $getMap();
81
+ return new Proxy(this, {
82
+ "get": (object, name) => {
83
+ if (object._$names.size && object._$names.has(name)) {
84
+ return object._$names.get(name);
85
+ }
86
+ // @ts-ignore
87
+ return object[name];
88
+ }
89
+ });
90
+ }
91
+ /**
92
+ * @description オブジェクトの子がマウスまたはユーザー入力デバイスに対応しているかどうかを判断します。
93
+ * Determine if the object's children are compatible with mouse or user input devices.
94
+ *
95
+ * @member {boolean}
96
+ * @public
97
+ */
98
+ get mouseChildren() {
99
+ return this._$mouseChildren;
100
+ }
101
+ set mouseChildren(mouse_children) {
102
+ this._$mouseChildren = !!mouse_children;
103
+ }
104
+ /**
105
+ * @description このオブジェクトの子の数を返します。
106
+ * Returns the number of children of this object.
107
+ *
108
+ * @member {number}
109
+ * @readonly
110
+ * @public
111
+ */
112
+ get numChildren() {
113
+ return this._$needsChildren
114
+ ? this._$getChildren().length
115
+ : this._$children.length;
116
+ }
117
+ /**
118
+ * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。
119
+ * Adds a child DisplayObject instance to this DisplayObjectContainer instance.
120
+ *
121
+ * @param {DisplayObject} child
122
+ * @return {DisplayObject}
123
+ * @method
124
+ * @public
125
+ */
126
+ addChild(child) {
127
+ if (child._$parent) {
128
+ child._$parent._$remove(child, !(child._$parent._$instanceId === this._$instanceId));
129
+ }
130
+ this._$getChildren().push(child);
131
+ if (child._$name) {
132
+ this._$names.set(child._$name, child);
133
+ }
134
+ return this._$addChild(child);
135
+ }
136
+ /**
137
+ * @description この DisplayObjectContainer インスタンスに子 DisplayObject インスタンスを追加します。
138
+ * Adds a child DisplayObject instance to this DisplayObjectContainer instance.
139
+ *
140
+ * @param {DisplayObject} child
141
+ * @param {number} index
142
+ * @return {DisplayObject}
143
+ * @method
144
+ * @public
145
+ */
146
+ addChildAt(child, index) {
147
+ if (child._$parent) {
148
+ child._$parent._$remove(child, !(child._$parent._$instanceId === this._$instanceId));
149
+ }
150
+ const children = this._$getChildren();
151
+ const length = children.length;
152
+ if (0 > index || index > length) {
153
+ throw new RangeError(`RangeError: addChildAt: index error: ${index}`);
154
+ }
155
+ if (length && length > index) {
156
+ children.splice(index, 0, child);
157
+ for (let idx = 0; idx < index; ++idx) {
158
+ const instance = children[idx];
159
+ if (instance._$name) {
160
+ this._$names.set(instance._$name, instance);
161
+ }
162
+ }
163
+ }
164
+ else {
165
+ children.push(child);
166
+ if (child._$name) {
167
+ this._$names.set(child._$name, child);
168
+ }
169
+ }
170
+ return this._$addChild(child);
171
+ }
172
+ /**
173
+ * @description 指定された表示オブジェクトが、DisplayObjectContainer インスタンスの子であるか
174
+ * インスタンス自体であるかを指定します。
175
+ * Determines whether the specified display object is a child
176
+ * of the DisplayObjectContainer instance or the instance itself.
177
+ *
178
+ * @param {DisplayObject} child
179
+ * @return {boolean}
180
+ * @method
181
+ * @public
182
+ */
183
+ contains(child) {
184
+ if (this._$instanceId === child._$instanceId) {
185
+ return true;
186
+ }
187
+ const children = this._$getChildren();
188
+ for (let idx = 0; idx < children.length; ++idx) {
189
+ const instance = children[idx];
190
+ if (instance._$instanceId === child._$instanceId) {
191
+ return true;
192
+ }
193
+ if (instance instanceof DisplayObjectContainer) {
194
+ if (instance.contains(child)) {
195
+ return true;
196
+ }
197
+ }
198
+ }
199
+ return false;
200
+ }
201
+ /**
202
+ * @description 指定のインデックス位置にある子表示オブジェクトインスタンスを返します。
203
+ * Returns the child display object instance that exists at the specified index.
204
+ *
205
+ * @param {number} index
206
+ * @return {DisplayObject}
207
+ * @method
208
+ * @public
209
+ */
210
+ getChildAt(index) {
211
+ const children = this._$getChildren();
212
+ if (0 > index || index > children.length) {
213
+ throw new RangeError(`RangeError: getChildAt: index error: ${index}`);
214
+ }
215
+ return index in children ? children[index] : null;
216
+ }
217
+ /**
218
+ * @description 指定された名前に一致する子表示オブジェクトを返します。
219
+ * Returns the child display object that exists with the specified name.
220
+ *
221
+ * @param {string} name
222
+ * @return {{DisplayObject}|null}
223
+ * @method
224
+ * @public
225
+ */
226
+ getChildByName(name) {
227
+ if (!name) {
228
+ return null;
229
+ }
230
+ // fixed logic
231
+ const children = this._$getChildren();
232
+ for (let idx = 0; idx < children.length; ++idx) {
233
+ const child = children[idx];
234
+ if (child.name !== name) {
235
+ continue;
236
+ }
237
+ return child;
238
+ }
239
+ return null;
240
+ }
241
+ /**
242
+ * @description 子 DisplayObject インスタンスのインデックス位置を返します。
243
+ * Returns the index position of a child DisplayObject instance.
244
+ *
245
+ * @param {DisplayObject} child
246
+ * @return {number}
247
+ * @method
248
+ * @public
249
+ */
250
+ getChildIndex(child) {
251
+ if (child._$parent !== this) {
252
+ throw new Error("ArgumentError: getChildIndex: not child");
253
+ }
254
+ const index = this._$getChildren().indexOf(child);
255
+ if (index === -1) {
256
+ throw new Error("ArgumentError: getChildIndex: not found.");
257
+ }
258
+ return index;
259
+ }
260
+ /**
261
+ * @description DisplayObjectContainer インスタンスの子リストから指定の
262
+ * child DisplayObject インスタンスを削除します。
263
+ * Removes the specified child DisplayObject instance from the
264
+ * child list of the DisplayObjectContainer instance.
265
+ *
266
+ * @param {DisplayObject} child
267
+ * @return {DisplayObject}
268
+ * @method
269
+ * @public
270
+ */
271
+ removeChild(child) {
272
+ if (child._$parent !== this) {
273
+ throw new Error("ArgumentError: removeChild: not child");
274
+ }
275
+ return this._$remove(child);
276
+ }
277
+ /**
278
+ * @description DisplayObjectContainer の子リストの指定された index 位置から子 DisplayObject を削除します。
279
+ * Removes a child DisplayObject from the specified index position
280
+ * in the child list of the DisplayObjectContainer.
281
+ *
282
+ * @param {number} index
283
+ * @return {DisplayObject}
284
+ * @method
285
+ * @public
286
+ */
287
+ removeChildAt(index) {
288
+ return this._$remove(this.getChildAt(index));
289
+ }
290
+ /**
291
+ * @description DisplayObjectContainer インスタンスの子リストから
292
+ * すべての child DisplayObject インスタンスを削除します。
293
+ * Removes all child DisplayObject instances from
294
+ * the child list of the DisplayObjectContainer instance.
295
+ *
296
+ * @param {number} [begin_index=0]
297
+ * @param {number} [end_index=0x7fffffff]
298
+ * @return {void}
299
+ * @method
300
+ * @public
301
+ */
302
+ removeChildren(begin_index = 0, end_index = 0x7fffffff) {
303
+ const children = this._$getChildren();
304
+ if (!children.length) {
305
+ return;
306
+ }
307
+ begin_index = $clamp(begin_index, 0, 0x7ffffffe, 0) - 1;
308
+ end_index = $clamp(end_index, 1, 0x7ffffff, 0x7ffffff);
309
+ for (let idx = $Math.min(end_index, children.length - 1); idx > begin_index; --idx) {
310
+ this._$remove(children[idx]);
311
+ }
312
+ }
313
+ /**
314
+ * @description 表示オブジェクトコンテナの既存の子の位置を変更します。
315
+ * Changes the position of an existing child in the display object container.
316
+ *
317
+ * @param {DisplayObject} child
318
+ * @param {number} index
319
+ * @return {void}
320
+ * @method
321
+ * @public
322
+ */
323
+ setChildIndex(child, index) {
324
+ const currentIndex = this.getChildIndex(child);
325
+ if (currentIndex === index) {
326
+ return;
327
+ }
328
+ const children = this._$getChildren();
329
+ children.splice(currentIndex, 1);
330
+ children.splice(index, 0, child);
331
+ if ($rendererWorker) {
332
+ this._$postChildrenIds();
333
+ }
334
+ this._$doChanged();
335
+ }
336
+ /**
337
+ * @description 指定された 2 つの子オブジェクトの z 順序(重ね順)を入れ替えます。
338
+ * Swaps the z-order (front-to-back order) of the two specified child objects.
339
+ *
340
+ * @param {DisplayObject} child1
341
+ * @param {DisplayObject} child2
342
+ * @return {void}
343
+ * @method
344
+ * @public
345
+ */
346
+ swapChildren(child1, child2) {
347
+ const children = this._$getChildren();
348
+ const index1 = this.getChildIndex(child1);
349
+ const index2 = this.getChildIndex(child2);
350
+ children[index1] = child2;
351
+ children[index2] = child1;
352
+ if ($rendererWorker) {
353
+ this._$postChildrenIds();
354
+ }
355
+ this._$doChanged();
356
+ }
357
+ /**
358
+ * @description 子リスト内の指定されたインデックス位置に該当する 2 つの子オブジェクトの z 順序(重ね順)を入れ替えます。
359
+ * Swaps the z-order (front-to-back order) of the child objects at
360
+ * the two specified index positions in the child list.
361
+ *
362
+ * @param {number} index1
363
+ * @param {number} index2
364
+ * @return {void}
365
+ * @method
366
+ * @public
367
+ */
368
+ swapChildrenAt(index1, index2) {
369
+ this.swapChildren(this.getChildAt(index1), this.getChildAt(index2));
370
+ }
371
+ /**
372
+ * @param {array} [matrix=null]
373
+ * @return {object}
374
+ * @private
375
+ */
376
+ _$getBounds(matrix = null) {
377
+ let multiMatrix = $MATRIX_ARRAY_IDENTITY;
378
+ if (matrix) {
379
+ multiMatrix = matrix;
380
+ const rawMatrix = this._$transform._$rawMatrix();
381
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
382
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
383
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
384
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
385
+ }
386
+ }
387
+ const graphics = "_$graphics" in this
388
+ ? this._$graphics
389
+ : null;
390
+ const children = this._$needsChildren
391
+ ? this._$getChildren()
392
+ : this._$children;
393
+ // size zero
394
+ if (!children.length && !graphics) {
395
+ const bounds = $getBoundsObject(multiMatrix[4], -multiMatrix[4], multiMatrix[5], -multiMatrix[5]);
396
+ if (matrix && multiMatrix !== matrix) {
397
+ $poolFloat32Array6(multiMatrix);
398
+ }
399
+ return bounds;
400
+ }
401
+ // data init
402
+ const no = $Number.MAX_VALUE;
403
+ let xMin = no;
404
+ let xMax = -no;
405
+ let yMin = no;
406
+ let yMax = -no;
407
+ if (graphics) {
408
+ const baseBounds = graphics._$getBounds();
409
+ const bounds = $boundsMatrix(baseBounds, multiMatrix);
410
+ $poolBoundsObject(baseBounds);
411
+ xMin = bounds.xMin;
412
+ xMax = bounds.xMax;
413
+ yMin = bounds.yMin;
414
+ yMax = bounds.yMax;
415
+ $poolBoundsObject(bounds);
416
+ }
417
+ for (let idx = 0; idx < children.length; ++idx) {
418
+ const bounds = children[idx]._$getBounds(multiMatrix);
419
+ xMin = $Math.min(xMin, bounds.xMin);
420
+ xMax = $Math.max(xMax, bounds.xMax);
421
+ yMin = $Math.min(yMin, bounds.yMin);
422
+ yMax = $Math.max(yMax, bounds.yMax);
423
+ $poolBoundsObject(bounds);
424
+ }
425
+ if (matrix && multiMatrix !== matrix) {
426
+ $poolFloat32Array6(multiMatrix);
427
+ }
428
+ // end
429
+ return $getBoundsObject(xMin, xMax, yMin, yMax);
430
+ }
431
+ /**
432
+ * @param {array} [matrix=null]
433
+ * @return {object}
434
+ * @private
435
+ */
436
+ _$getLayerBounds(matrix = null) {
437
+ let multiMatrix = $MATRIX_ARRAY_IDENTITY;
438
+ if (matrix) {
439
+ multiMatrix = matrix;
440
+ const rawMatrix = this._$transform._$rawMatrix();
441
+ if (rawMatrix !== $MATRIX_ARRAY_IDENTITY) {
442
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
443
+ }
444
+ }
445
+ const graphics = "_$graphics" in this
446
+ ? this._$graphics
447
+ : null;
448
+ const children = this._$needsChildren
449
+ ? this._$getChildren()
450
+ : this._$children;
451
+ // size zero
452
+ if (!children.length && !graphics) {
453
+ const bounds = $getBoundsObject(multiMatrix[4], -multiMatrix[4], multiMatrix[5], -multiMatrix[5]);
454
+ if (matrix && multiMatrix !== matrix) {
455
+ $poolFloat32Array6(multiMatrix);
456
+ }
457
+ return bounds;
458
+ }
459
+ // data init
460
+ const no = $Number.MAX_VALUE;
461
+ let xMin = no;
462
+ let xMax = -no;
463
+ let yMin = no;
464
+ let yMax = -no;
465
+ if (graphics) {
466
+ const baseBounds = graphics._$getBounds();
467
+ const bounds = $boundsMatrix(baseBounds, multiMatrix);
468
+ $poolBoundsObject(baseBounds);
469
+ xMin = +bounds.xMin;
470
+ xMax = +bounds.xMax;
471
+ yMin = +bounds.yMin;
472
+ yMax = +bounds.yMax;
473
+ $poolBoundsObject(bounds);
474
+ }
475
+ for (let idx = 0; idx < children.length; ++idx) {
476
+ const bounds = children[idx]
477
+ ._$getLayerBounds(multiMatrix);
478
+ xMin = $Math.min(xMin, bounds.xMin);
479
+ xMax = $Math.max(xMax, bounds.xMax);
480
+ yMin = $Math.min(yMin, bounds.yMin);
481
+ yMax = $Math.max(yMax, bounds.yMax);
482
+ $poolBoundsObject(bounds);
483
+ }
484
+ if (matrix && multiMatrix !== matrix) {
485
+ $poolFloat32Array6(multiMatrix);
486
+ }
487
+ // end
488
+ if (!matrix) {
489
+ return $getBoundsObject(xMin, xMax, yMin, yMax);
490
+ }
491
+ const filters = this._$filters || this.filters;
492
+ if (!filters.length) {
493
+ return $getBoundsObject(xMin, xMax, yMin, yMax);
494
+ }
495
+ let filterBounds = $getBoundsObject(xMin, xMax - xMin, yMin, yMax - yMin);
496
+ for (let idx = 0; idx < filters.length; ++idx) {
497
+ filterBounds = filters[idx]
498
+ ._$generateFilterRect(filterBounds, 0, 0);
499
+ }
500
+ xMin = filterBounds.xMin;
501
+ xMax = filterBounds.xMin + filterBounds.xMax;
502
+ yMin = filterBounds.yMin;
503
+ yMax = filterBounds.yMin + filterBounds.yMax;
504
+ $poolBoundsObject(filterBounds);
505
+ return $getBoundsObject(xMin, xMax, yMin, yMax);
506
+ }
507
+ /**
508
+ * @return {array}
509
+ * @private
510
+ */
511
+ _$getChildren() {
512
+ if (this._$needsChildren) {
513
+ // set flag
514
+ this._$needsChildren = false;
515
+ const currentChildren = this._$children;
516
+ if (!this._$controller) {
517
+ return currentChildren;
518
+ }
519
+ const frame = "_$currentFrame" in this ? this._$currentFrame : 1;
520
+ const controller = this._$controller[frame];
521
+ // first build
522
+ if (!currentChildren.length) {
523
+ if (controller) {
524
+ for (let idx = 0; idx < controller.length; ++idx) {
525
+ const instance = this._$createInstance(controller[idx]);
526
+ instance._$placeId = idx;
527
+ const loopConfig = instance.loopConfig;
528
+ if (loopConfig) {
529
+ instance._$currentFrame = instance
530
+ ._$getLoopFrame(loopConfig);
531
+ }
532
+ currentChildren.push(instance);
533
+ if (instance._$name) {
534
+ this._$names.set(instance._$name, instance);
535
+ }
536
+ }
537
+ }
538
+ return currentChildren;
539
+ }
540
+ const player = $currentPlayer();
541
+ const cacheStore = player.cacheStore;
542
+ const useWorker = !!$rendererWorker && !!this._$stage;
543
+ const skipIds = $getMap();
544
+ const poolInstances = $getMap();
545
+ let depth = 0;
546
+ const children = $getArray();
547
+ for (let idx = 0; idx < currentChildren.length; ++idx) {
548
+ const instance = currentChildren[idx];
549
+ const parent = instance._$parent;
550
+ if (!parent || parent._$instanceId !== this._$instanceId) {
551
+ continue;
552
+ }
553
+ const instanceId = instance._$instanceId;
554
+ const startFrame = instance._$startFrame;
555
+ const endFrame = instance._$endFrame;
556
+ if (startFrame === 1 && endFrame === 0
557
+ || startFrame <= frame && endFrame > frame) {
558
+ // reset
559
+ instance._$isNext = true;
560
+ instance._$placeObject = null;
561
+ instance._$filters = null;
562
+ instance._$blendMode = null;
563
+ if (instance._$id === -1) {
564
+ children.push(instance);
565
+ if (instance._$name) {
566
+ this._$names.set(instance._$name, instance);
567
+ }
568
+ continue;
569
+ }
570
+ const id = controller[depth];
571
+ if (instance._$id === id) {
572
+ instance._$placeId = depth;
573
+ children.push(instance);
574
+ if (instance._$name) {
575
+ this._$names.set(instance._$name, instance);
576
+ }
577
+ if (poolInstances.has(id)) {
578
+ poolInstances.delete(id);
579
+ }
580
+ skipIds.set(id, true);
581
+ depth++;
582
+ if (useWorker) {
583
+ instance._$postProperty();
584
+ }
585
+ continue;
586
+ }
587
+ poolInstances.set(instance._$id, instance);
588
+ continue;
589
+ }
590
+ if (useWorker) {
591
+ instance._$removeWorkerInstance();
592
+ }
593
+ cacheStore.setRemoveTimer(instanceId);
594
+ if (instance._$loaderInfo && instance._$characterId) {
595
+ cacheStore.setRemoveTimer(`${instance._$loaderInfo._$id}@${instance._$characterId}`);
596
+ }
597
+ // remove event
598
+ if (instance.willTrigger(Next2DEvent.REMOVED)) {
599
+ instance.dispatchEvent(new Next2DEvent(Next2DEvent.REMOVED, true));
600
+ }
601
+ if (instance.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) {
602
+ instance.dispatchEvent(new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE, true));
603
+ }
604
+ // reset
605
+ instance._$added = false;
606
+ instance._$addedStage = false;
607
+ instance._$active = false;
608
+ instance._$updated = true;
609
+ instance._$filters = null;
610
+ instance._$blendMode = null;
611
+ instance._$isNext = true;
612
+ instance._$placeObject = null;
613
+ instance._$created = false;
614
+ instance._$posted = false;
615
+ if (instance instanceof DisplayObjectContainer) {
616
+ instance._$executeRemovedFromStage();
617
+ instance._$removeParentAndStage();
618
+ }
619
+ }
620
+ if (controller) {
621
+ for (let idx = 0; idx < controller.length; ++idx) {
622
+ const id = controller[idx];
623
+ if (skipIds.has(id)) {
624
+ continue;
625
+ }
626
+ const instance = poolInstances.has(id)
627
+ ? poolInstances.get(id)
628
+ : this._$createInstance(id);
629
+ instance._$placeId = idx;
630
+ const loopConfig = instance.loopConfig;
631
+ if (loopConfig) {
632
+ instance._$currentFrame = instance
633
+ ._$getLoopFrame(loopConfig);
634
+ }
635
+ children.push(instance);
636
+ if (instance._$name) {
637
+ this._$names.set(instance._$name, instance);
638
+ }
639
+ }
640
+ }
641
+ // object pool
642
+ $poolMap(skipIds);
643
+ $poolMap(poolInstances);
644
+ // update
645
+ currentChildren.length = 0;
646
+ currentChildren.push(...children);
647
+ $poolArray(children);
648
+ }
649
+ return this._$children;
650
+ }
651
+ /**
652
+ * @return void
653
+ * @private
654
+ */
655
+ _$clearChildren() {
656
+ this._$doChanged();
657
+ $doUpdated();
658
+ // reset
659
+ this._$names.clear();
660
+ // clear
661
+ this._$needsChildren = true;
662
+ }
663
+ /**
664
+ * @param {DisplayObject} child
665
+ * @returns {DisplayObject}
666
+ * @private
667
+ */
668
+ _$addChild(child) {
669
+ // init
670
+ child._$parent = this;
671
+ if (!child._$stage || !child._$root) {
672
+ child._$stage = this._$stage;
673
+ child._$root = this._$root;
674
+ }
675
+ // setup
676
+ if (child instanceof DisplayObjectContainer) {
677
+ child._$setParentAndStage();
678
+ child._$wait = true;
679
+ }
680
+ // added event
681
+ if (!child._$added) {
682
+ if (child.willTrigger(Next2DEvent.ADDED)) {
683
+ child.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED, true));
684
+ }
685
+ child._$added = true;
686
+ }
687
+ if (this._$stage !== null && !child._$addedStage) {
688
+ if (child.willTrigger(Next2DEvent.ADDED_TO_STAGE)) {
689
+ child.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED_TO_STAGE));
690
+ }
691
+ child._$addedStage = true;
692
+ // set params
693
+ if (child instanceof DisplayObjectContainer) {
694
+ child._$executeAddedToStage();
695
+ }
696
+ if ($rendererWorker) {
697
+ child._$createWorkerInstance();
698
+ child._$postProperty();
699
+ this._$postChildrenIds();
700
+ }
701
+ }
702
+ this._$doChanged();
703
+ child._$active = true;
704
+ child._$updated = true;
705
+ child._$isNext = true;
706
+ return child;
707
+ }
708
+ /**
709
+ * @return {void}
710
+ * @method
711
+ * @private
712
+ */
713
+ _$setParentAndStage() {
714
+ const children = this._$needsChildren
715
+ ? this._$getChildren()
716
+ : this._$children;
717
+ for (let idx = 0; idx < children.length; ++idx) {
718
+ const instance = children[idx];
719
+ instance._$root = this._$root;
720
+ instance._$stage = this._$stage;
721
+ if (instance instanceof DisplayObjectContainer) {
722
+ instance._$setParentAndStage();
723
+ instance._$wait = true;
724
+ }
725
+ }
726
+ }
727
+ /**
728
+ * @return {void}
729
+ * @method
730
+ * @private
731
+ */
732
+ _$executeAddedToStage() {
733
+ const children = this._$needsChildren
734
+ ? this._$getChildren()
735
+ : this._$children;
736
+ const childrenIds = $getArray();
737
+ for (let idx = 0; idx < children.length; ++idx) {
738
+ const instance = children[idx];
739
+ if (!instance) {
740
+ continue;
741
+ }
742
+ childrenIds.push(instance._$instanceId);
743
+ if (!instance._$addedStage) {
744
+ if ($rendererWorker) {
745
+ instance._$createWorkerInstance();
746
+ instance._$postProperty();
747
+ }
748
+ if (instance.willTrigger(Next2DEvent.ADDED_TO_STAGE)) {
749
+ instance.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED_TO_STAGE));
750
+ }
751
+ instance._$addedStage = true;
752
+ }
753
+ if (instance instanceof DisplayObjectContainer) {
754
+ instance._$executeAddedToStage();
755
+ }
756
+ }
757
+ if ($rendererWorker) {
758
+ this._$postChildrenIds(childrenIds);
759
+ }
760
+ $poolArray(childrenIds);
761
+ }
762
+ /**
763
+ * @param {DisplayObject} child
764
+ * @param {boolean} do_event
765
+ * @return {DisplayObject}
766
+ * @private
767
+ */
768
+ _$remove(child, do_event = true) {
769
+ child._$transform._$transform();
770
+ // remove all broadcast events
771
+ if (child.hasEventListener(Next2DEvent.ENTER_FRAME)) {
772
+ child.removeAllEventListener(Next2DEvent.ENTER_FRAME);
773
+ }
774
+ if (child.hasEventListener(Next2DEvent.EXIT_FRAME)) {
775
+ child.removeAllEventListener(Next2DEvent.EXIT_FRAME);
776
+ }
777
+ if (child.hasEventListener(Next2DEvent.FRAME_CONSTRUCTED)) {
778
+ child.removeAllEventListener(Next2DEvent.FRAME_CONSTRUCTED);
779
+ }
780
+ if (child.hasEventListener(Next2DEvent.RENDER)) {
781
+ child.removeAllEventListener(Next2DEvent.RENDER);
782
+ }
783
+ if (child.hasEventListener(Next2DEvent.ACTIVATE)) {
784
+ child.removeAllEventListener(Next2DEvent.ACTIVATE);
785
+ }
786
+ if (child.hasEventListener(Next2DEvent.DEACTIVATE)) {
787
+ child.removeAllEventListener(Next2DEvent.DEACTIVATE);
788
+ }
789
+ if (child.hasEventListener("keyDown")) {
790
+ child.removeAllEventListener("keyDown");
791
+ }
792
+ if (child.hasEventListener("keyUp")) {
793
+ child.removeAllEventListener("keyUp");
794
+ }
795
+ // remove
796
+ const children = this._$needsChildren
797
+ ? this._$getChildren()
798
+ : this._$children;
799
+ const depth = this.getChildIndex(child);
800
+ children.splice(depth, 1);
801
+ this._$names.delete(child.name);
802
+ if (do_event) {
803
+ // event
804
+ if (child.willTrigger(Next2DEvent.REMOVED)) {
805
+ child.dispatchEvent(new Next2DEvent(Next2DEvent.REMOVED, true));
806
+ }
807
+ // remove stage event
808
+ if (this._$stage !== null) {
809
+ // worker側のDisplayObjectも削除
810
+ if ($rendererWorker) {
811
+ child._$removeWorkerInstance();
812
+ this._$postChildrenIds();
813
+ }
814
+ if (child.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) {
815
+ child.dispatchEvent(new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE));
816
+ }
817
+ if (child instanceof DisplayObjectContainer) {
818
+ child._$executeRemovedFromStage();
819
+ }
820
+ }
821
+ const player = $currentPlayer();
822
+ const cacheStore = player.cacheStore;
823
+ cacheStore.setRemoveTimer(child._$instanceId);
824
+ if (child._$loaderInfo && child._$characterId) {
825
+ cacheStore.setRemoveTimer(`${child._$loaderInfo._$id}@${child._$characterId}`);
826
+ }
827
+ // reset params
828
+ if (child instanceof DisplayObjectContainer) {
829
+ child._$removeParentAndStage();
830
+ }
831
+ // reset
832
+ child._$stage = null;
833
+ child._$parent = null;
834
+ child._$root = null;
835
+ child._$active = false;
836
+ child._$wait = true;
837
+ child._$updated = true;
838
+ child._$added = false;
839
+ child._$addedStage = false;
840
+ child._$created = false;
841
+ child._$posted = false;
842
+ this._$doChanged();
843
+ }
844
+ return child;
845
+ }
846
+ /**
847
+ * @return {void}
848
+ * @method
849
+ * @private
850
+ */
851
+ _$executeRemovedFromStage() {
852
+ const children = this._$getChildren().slice(0);
853
+ for (let idx = 0; idx < children.length; ++idx) {
854
+ const instance = children[idx];
855
+ if (!instance) {
856
+ continue;
857
+ }
858
+ if (instance._$addedStage) {
859
+ // workerのDisplayObjectを削除
860
+ if ($rendererWorker) {
861
+ instance._$removeWorkerInstance();
862
+ }
863
+ if (instance.willTrigger(Next2DEvent.REMOVED_FROM_STAGE)) {
864
+ instance.dispatchEvent(new Next2DEvent(Next2DEvent.REMOVED_FROM_STAGE));
865
+ }
866
+ instance._$created = false;
867
+ instance._$posted = false;
868
+ instance._$addedStage = false;
869
+ }
870
+ if (instance instanceof DisplayObjectContainer) {
871
+ instance._$executeRemovedFromStage();
872
+ }
873
+ }
874
+ }
875
+ /**
876
+ * @return {void}
877
+ * @method
878
+ * @private
879
+ */
880
+ _$removeParentAndStage() {
881
+ const children = this._$needsChildren
882
+ ? this._$getChildren()
883
+ : this._$children;
884
+ const player = $currentPlayer();
885
+ const cacheStore = player.cacheStore;
886
+ for (let idx = 0; idx < children.length; ++idx) {
887
+ const instance = children[idx];
888
+ cacheStore.setRemoveTimer(instance._$instanceId);
889
+ if (instance._$loaderInfo && instance._$characterId) {
890
+ cacheStore.setRemoveTimer(`${instance._$loaderInfo._$id}@${instance._$characterId}`);
891
+ }
892
+ if (instance instanceof DisplayObjectContainer) {
893
+ instance._$removeParentAndStage();
894
+ }
895
+ instance._$stage = null;
896
+ instance._$root = null;
897
+ instance._$addedStage = false;
898
+ }
899
+ if ("_$sounds" in this) {
900
+ const soundsMap = this._$sounds;
901
+ if (soundsMap.size) {
902
+ for (const sounds of soundsMap.values()) {
903
+ for (let idx = 0; idx < sounds.length; ++idx) {
904
+ const sound = sounds[idx];
905
+ sound.stop();
906
+ }
907
+ }
908
+ }
909
+ }
910
+ this._$needsChildren = true;
911
+ }
912
+ /**
913
+ * @return {void}
914
+ * @method
915
+ * @private
916
+ */
917
+ _$prepareActions() {
918
+ const children = this._$needsChildren
919
+ ? this._$getChildren()
920
+ : this._$children;
921
+ for (let idx = children.length - 1; idx > -1; --idx) {
922
+ children[idx]._$prepareActions();
923
+ }
924
+ // added event
925
+ this._$executeAddedEvent();
926
+ }
927
+ /**
928
+ * @return {boolean}
929
+ * @method
930
+ * @private
931
+ */
932
+ _$nextFrame() {
933
+ let isNext = false;
934
+ const children = this._$getChildren();
935
+ for (let idx = children.length - 1; idx > -1; --idx) {
936
+ const child = children[idx];
937
+ if (!child._$isNext) {
938
+ continue;
939
+ }
940
+ if (isNext) {
941
+ child._$nextFrame();
942
+ }
943
+ else {
944
+ isNext = child._$nextFrame();
945
+ }
946
+ }
947
+ // added event
948
+ this._$executeAddedEvent();
949
+ this._$isNext = isNext;
950
+ if (!this._$posted && $rendererWorker) {
951
+ this._$postProperty();
952
+ }
953
+ return this._$isNext;
954
+ }
955
+ /**
956
+ * @param {CanvasToWebGLContext} context
957
+ * @param {Float32Array} matrix
958
+ * @return {void}
959
+ * @method
960
+ * @private
961
+ */
962
+ _$clip(context, matrix) {
963
+ let multiMatrix = matrix;
964
+ const rawMatrix = this._$transform._$rawMatrix();
965
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
966
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
967
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
968
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
969
+ }
970
+ const graphics = "_$graphics" in this
971
+ ? this._$graphics
972
+ : null;
973
+ if (graphics && graphics._$canDraw) {
974
+ graphics._$clip(context, multiMatrix);
975
+ }
976
+ const children = this._$getChildren();
977
+ for (let idx = 0; idx < children.length; ++idx) {
978
+ const instance = children[idx];
979
+ // mask instance
980
+ if (instance._$isMask) {
981
+ continue;
982
+ }
983
+ instance._$clip(context, multiMatrix);
984
+ instance._$updated = false;
985
+ }
986
+ if (multiMatrix !== matrix) {
987
+ $poolFloat32Array6(multiMatrix);
988
+ }
989
+ }
990
+ /**
991
+ * @param {CanvasToWebGLContext} context
992
+ * @param {Float32Array} matrix
993
+ * @return {object}
994
+ * @private
995
+ */
996
+ _$preDraw(context, matrix) {
997
+ let multiMatrix = matrix;
998
+ const rawMatrix = this._$transform._$rawMatrix();
999
+ if (rawMatrix !== $MATRIX_HIT_ARRAY_IDENTITY
1000
+ && rawMatrix[0] !== 1 || rawMatrix[1] !== 0
1001
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
1002
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
1003
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1004
+ }
1005
+ // size zero
1006
+ if (!multiMatrix[0] && !multiMatrix[1]
1007
+ || !multiMatrix[2] && !multiMatrix[3]) {
1008
+ return null;
1009
+ }
1010
+ // return object
1011
+ const object = $getPreObject();
1012
+ // setup
1013
+ object.matrix = multiMatrix;
1014
+ // check
1015
+ const filters = this._$filters || this.filters;
1016
+ const blendMode = this._$blendMode || this.blendMode;
1017
+ if (filters.length > 0 || blendMode !== "normal") {
1018
+ // check size
1019
+ const baseBounds = this._$getBounds(null);
1020
+ const bounds = $boundsMatrix(baseBounds, multiMatrix);
1021
+ $poolBoundsObject(baseBounds);
1022
+ const xMax = +bounds.xMax;
1023
+ const xMin = +bounds.xMin;
1024
+ const yMax = +bounds.yMax;
1025
+ const yMin = +bounds.yMin;
1026
+ $poolBoundsObject(bounds);
1027
+ const width = $Math.abs(xMax - xMin);
1028
+ const height = $Math.abs(yMax - yMin);
1029
+ if (0 >= width || 0 >= height) {
1030
+ $poolPreObject(object);
1031
+ return null;
1032
+ }
1033
+ if (0 > xMin + width || 0 > yMin + height) {
1034
+ $poolPreObject(object);
1035
+ return null;
1036
+ }
1037
+ const currentAttachment = context
1038
+ .frameBuffer
1039
+ .currentAttachment;
1040
+ if (!currentAttachment
1041
+ || !currentAttachment.texture
1042
+ || xMin > currentAttachment.width
1043
+ || yMin > currentAttachment.height) {
1044
+ $poolPreObject(object);
1045
+ return null;
1046
+ }
1047
+ // set origin position
1048
+ object.basePosition.x = rawMatrix[4];
1049
+ object.basePosition.y = rawMatrix[5];
1050
+ // check after size
1051
+ const baseLayerBounds = this._$getLayerBounds(null);
1052
+ const layerBounds = $boundsMatrix(baseLayerBounds, multiMatrix);
1053
+ // filter size
1054
+ let layerWidth = $Math.abs(layerBounds.xMax - layerBounds.xMin);
1055
+ let layerHeight = $Math.abs(layerBounds.yMax - layerBounds.yMin);
1056
+ $poolBoundsObject(layerBounds);
1057
+ // move size
1058
+ let tx = multiMatrix[4] - $Math.floor(xMin);
1059
+ let ty = multiMatrix[5] - $Math.floor(yMin);
1060
+ let dx = $Math.floor(xMin);
1061
+ let dy = $Math.floor(yMin);
1062
+ let originX = xMin;
1063
+ let originY = yMin;
1064
+ if (layerWidth !== width || layerHeight !== height) {
1065
+ const layerMatrix = $getFloat32Array6(multiMatrix[0], multiMatrix[1], multiMatrix[2], multiMatrix[3], 0, 0);
1066
+ const moveBounds = $boundsMatrix(baseLayerBounds, layerMatrix);
1067
+ // pool
1068
+ $poolFloat32Array6(layerMatrix);
1069
+ tx += -$Math.floor(moveBounds.xMin) - tx;
1070
+ ty += -$Math.floor(moveBounds.yMin) - ty;
1071
+ dx -= -$Math.floor(moveBounds.xMin) - (multiMatrix[4] - dx);
1072
+ dy -= -$Math.floor(moveBounds.yMin) - (multiMatrix[5] - dy);
1073
+ originX -= -moveBounds.xMin - (multiMatrix[4] - originX);
1074
+ originY -= -moveBounds.yMin - (multiMatrix[5] - originY);
1075
+ $poolBoundsObject(moveBounds);
1076
+ }
1077
+ $poolBoundsObject(baseLayerBounds);
1078
+ // set position
1079
+ object.position.dx = dx > 0 ? dx : 0;
1080
+ object.position.dy = dy > 0 ? dy : 0;
1081
+ // resize
1082
+ if (layerWidth + originX > currentAttachment.texture.width) {
1083
+ layerWidth -= layerWidth - currentAttachment.texture.width + originX;
1084
+ }
1085
+ if (layerHeight + originY > currentAttachment.texture.height) {
1086
+ layerHeight -= layerHeight - currentAttachment.texture.height + originY;
1087
+ }
1088
+ if (0 > dx) {
1089
+ tx += dx;
1090
+ layerWidth += originX;
1091
+ }
1092
+ if (0 > dy) {
1093
+ ty += dy;
1094
+ layerHeight += originY;
1095
+ }
1096
+ if (0 >= layerWidth || 0 >= layerHeight // size (-)
1097
+ || !layerWidth || !layerHeight // NaN or Infinity
1098
+ ) {
1099
+ $poolPreObject(object);
1100
+ return null;
1101
+ }
1102
+ // start layer
1103
+ context._$startLayer($getBoundsObject(originX, 0, originY, 0));
1104
+ // check cache
1105
+ object.canApply = this._$canApply(filters);
1106
+ const updated = this._$isFilterUpdated(layerWidth, layerHeight, multiMatrix, filters, object.canApply, object.basePosition.x, object.basePosition.y);
1107
+ // current mask cache
1108
+ context._$saveCurrentMask();
1109
+ if (updated) {
1110
+ context._$saveAttachment($Math.ceil(layerWidth), $Math.ceil(layerHeight), false);
1111
+ }
1112
+ // setup
1113
+ object.isFilter = true;
1114
+ object.isUpdated = updated;
1115
+ object.color = $getFloat32Array8();
1116
+ object.baseMatrix = multiMatrix;
1117
+ object.filters = filters;
1118
+ object.blendMode = blendMode;
1119
+ object.layerWidth = layerWidth;
1120
+ object.layerHeight = layerHeight;
1121
+ object.matrix = $getFloat32Array6(multiMatrix[0], multiMatrix[1], multiMatrix[2], multiMatrix[3], tx, ty);
1122
+ }
1123
+ return object;
1124
+ }
1125
+ /**
1126
+ * @param {CanvasToWebGLContext} context
1127
+ * @param {Float32Array} matrix
1128
+ * @param {Float32Array} color_transform
1129
+ * @param {object} object
1130
+ * @return {void}
1131
+ * @method
1132
+ * @private
1133
+ */
1134
+ _$postDraw(context, matrix, color_transform, object) {
1135
+ // cache
1136
+ const cacheKeys = $getArray(this._$instanceId, "f");
1137
+ const player = $currentPlayer();
1138
+ const cacheStore = player.cacheStore;
1139
+ const manager = context.frameBuffer;
1140
+ // cache or new texture
1141
+ let texture = null;
1142
+ if (object.isUpdated) {
1143
+ texture = manager
1144
+ .getTextureFromCurrentAttachment();
1145
+ const cacheTexture = cacheStore.get(cacheKeys);
1146
+ if (cacheTexture) {
1147
+ cacheStore.set(cacheKeys, null);
1148
+ manager.releaseTexture(cacheTexture);
1149
+ }
1150
+ }
1151
+ else {
1152
+ texture = cacheStore.get(cacheKeys);
1153
+ if (!texture) {
1154
+ throw new Error("the texture is null.");
1155
+ }
1156
+ }
1157
+ // blend only
1158
+ if (!object.canApply) {
1159
+ texture._$offsetX = 0;
1160
+ texture._$offsetY = 0;
1161
+ }
1162
+ // set cache offset
1163
+ let offsetX = texture._$offsetX;
1164
+ let offsetY = texture._$offsetY;
1165
+ // execute filter
1166
+ if (object.isUpdated && object.canApply) {
1167
+ // cache clear
1168
+ const cache = cacheStore.get(cacheKeys);
1169
+ if (cache) {
1170
+ // reset cache params
1171
+ cacheStore.set(cacheKeys, null);
1172
+ cache.layerWidth = 0;
1173
+ cache.layerHeight = 0;
1174
+ cache._$offsetX = 0;
1175
+ cache._$offsetY = 0;
1176
+ cache.matrix = null;
1177
+ cache.colorTransform = null;
1178
+ manager.releaseTexture(cache);
1179
+ }
1180
+ // apply filter
1181
+ const filters = object.filters;
1182
+ if (filters && filters.length) {
1183
+ // init
1184
+ context._$offsetX = 0;
1185
+ context._$offsetY = 0;
1186
+ for (let idx = 0; idx < filters.length; ++idx) {
1187
+ texture = filters[idx]
1188
+ ._$applyFilter(context, matrix);
1189
+ }
1190
+ offsetX = context._$offsetX;
1191
+ offsetY = context._$offsetY;
1192
+ // reset
1193
+ context._$offsetX = 0;
1194
+ context._$offsetY = 0;
1195
+ // set offset
1196
+ texture._$offsetX = offsetX;
1197
+ texture._$offsetY = offsetY;
1198
+ }
1199
+ }
1200
+ // update cache params
1201
+ if (object.isUpdated) {
1202
+ texture.filterState = object.canApply;
1203
+ // cache texture
1204
+ const matrix = object.baseMatrix;
1205
+ if (matrix) {
1206
+ texture.matrix = `${matrix[0]}_${matrix[1]}_${matrix[2]}_${matrix[3]}`;
1207
+ }
1208
+ texture.layerWidth = object.layerWidth;
1209
+ texture.layerHeight = object.layerHeight;
1210
+ }
1211
+ // cache texture
1212
+ cacheStore.set(cacheKeys, texture);
1213
+ $poolArray(cacheKeys);
1214
+ // set current buffer
1215
+ if (object.isUpdated) {
1216
+ context._$restoreAttachment();
1217
+ }
1218
+ // set
1219
+ context.reset();
1220
+ context.globalAlpha = $clamp(color_transform[3] + color_transform[7] / 255, 0, 1);
1221
+ context.globalCompositeOperation = object.blendMode;
1222
+ context.setTransform(1, 0, 0, 1, 0, 0);
1223
+ context.drawImage(texture, -offsetX + object.position.dx, -offsetY + object.position.dy, texture.width, texture.height, color_transform);
1224
+ // end blend
1225
+ context._$endLayer();
1226
+ // reset
1227
+ context._$restoreCurrentMask();
1228
+ // object pool
1229
+ if (object.baseMatrix !== matrix) {
1230
+ $poolFloat32Array6(object.baseMatrix);
1231
+ }
1232
+ $poolFloat32Array6(object.matrix);
1233
+ $poolPreObject(object);
1234
+ }
1235
+ /**
1236
+ * @param {CanvasToWebGLContext} context
1237
+ * @param {Float32Array} matrix
1238
+ * @param {Float32Array} color_transform
1239
+ * @return {void}
1240
+ * @method
1241
+ * @private
1242
+ */
1243
+ _$draw(context, matrix, color_transform) {
1244
+ // not draw
1245
+ if (!this._$visible) {
1246
+ return;
1247
+ }
1248
+ const transform = this._$transform;
1249
+ let multiColor = color_transform;
1250
+ const rawColor = transform._$rawColorTransform();
1251
+ if (rawColor !== $COLOR_ARRAY_IDENTITY
1252
+ && rawColor[0] !== 1 || rawColor[1] !== 1
1253
+ || rawColor[2] !== 1 || rawColor[3] !== 1
1254
+ || rawColor[4] !== 0 || rawColor[5] !== 0
1255
+ || rawColor[6] !== 0 || rawColor[7] !== 0) {
1256
+ multiColor = $multiplicationColor(color_transform, rawColor);
1257
+ }
1258
+ // not draw
1259
+ const alpha = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1, 0);
1260
+ if (!alpha) {
1261
+ return;
1262
+ }
1263
+ // not draw
1264
+ const children = this._$getChildren();
1265
+ const length = children.length;
1266
+ const graphics = "_$graphics" in this
1267
+ ? this._$graphics
1268
+ : null;
1269
+ if (!length && (!graphics || !graphics._$canDraw)) {
1270
+ return;
1271
+ }
1272
+ // pre data
1273
+ const preObject = this._$preDraw(context, matrix);
1274
+ if (!preObject) {
1275
+ return;
1276
+ }
1277
+ // use cache
1278
+ if (preObject.isFilter && !preObject.isUpdated) {
1279
+ this._$postDraw(context, matrix, multiColor, preObject);
1280
+ return;
1281
+ }
1282
+ let preMatrix = preObject.matrix;
1283
+ const preColorTransform = preObject.isFilter && preObject.color
1284
+ ? preObject.color
1285
+ : multiColor;
1286
+ // if graphics draw
1287
+ if (graphics && graphics._$canDraw) {
1288
+ graphics._$draw(context, preMatrix, preColorTransform);
1289
+ }
1290
+ // init clip params
1291
+ let shouldClip = true;
1292
+ let clipDepth = 0;
1293
+ const clipMatrix = $getArray();
1294
+ const instanceMatrix = $getArray();
1295
+ const clipStack = $getArray();
1296
+ const shouldClips = $getArray();
1297
+ const player = $currentPlayer();
1298
+ // draw children
1299
+ const isLayer = context.isLayer;
1300
+ const isUpdate = this._$isUpdated();
1301
+ for (let idx = 0; idx < length; ++idx) {
1302
+ const instance = children[idx];
1303
+ if (isUpdate) {
1304
+ instance._$placeObject = null;
1305
+ }
1306
+ // mask instance
1307
+ if (instance._$isMask) {
1308
+ continue;
1309
+ }
1310
+ // not layer mode
1311
+ const blendMode = instance._$blendMode || instance.blendMode;
1312
+ if ((blendMode === "alpha" || blendMode === "erase")
1313
+ && !isLayer) {
1314
+ continue;
1315
+ }
1316
+ // mask end
1317
+ if (clipDepth
1318
+ && (instance._$placeId > clipDepth || instance._$clipDepth > 0)) {
1319
+ context.restore();
1320
+ if (shouldClip) {
1321
+ context._$leaveClip();
1322
+ if (clipMatrix.length) {
1323
+ const matrix = clipMatrix.pop();
1324
+ if (matrix) {
1325
+ $poolFloat32Array6(preMatrix);
1326
+ preMatrix = matrix;
1327
+ }
1328
+ }
1329
+ }
1330
+ // clear
1331
+ clipDepth = clipStack.length ? clipStack.pop() || 0 : 0;
1332
+ shouldClip = !!shouldClips.pop();
1333
+ }
1334
+ // mask size 0
1335
+ if (!shouldClip) {
1336
+ continue;
1337
+ }
1338
+ // mask start
1339
+ if (instance._$clipDepth > 0) {
1340
+ context.save();
1341
+ if (clipDepth) {
1342
+ clipStack.push(clipDepth);
1343
+ }
1344
+ shouldClips.push(shouldClip);
1345
+ clipDepth = instance._$clipDepth;
1346
+ shouldClip = instance._$shouldClip(preMatrix);
1347
+ if (shouldClip) {
1348
+ const adjMatrix = instance._$startClip(context, preMatrix);
1349
+ if (adjMatrix === false) { // fixed
1350
+ shouldClip = false;
1351
+ continue;
1352
+ }
1353
+ if (adjMatrix instanceof Float32Array) {
1354
+ clipMatrix.push(preMatrix);
1355
+ preMatrix = adjMatrix;
1356
+ }
1357
+ }
1358
+ continue;
1359
+ }
1360
+ // mask start
1361
+ const maskInstance = instance._$mask;
1362
+ if (maskInstance) {
1363
+ maskInstance._$updated = false;
1364
+ let maskMatrix;
1365
+ if (this === maskInstance._$parent) {
1366
+ maskMatrix = preMatrix;
1367
+ }
1368
+ else {
1369
+ maskMatrix = $MATRIX_ARRAY_IDENTITY;
1370
+ let parent = maskInstance._$parent;
1371
+ while (parent) {
1372
+ maskMatrix = $multiplicationMatrix(parent._$transform._$rawMatrix(), maskMatrix);
1373
+ parent = parent._$parent;
1374
+ }
1375
+ const mScale = player.scaleX;
1376
+ const playerMatrix = $getFloat32Array6(mScale, 0, 0, mScale, 0, 0);
1377
+ maskMatrix = $multiplicationMatrix(playerMatrix, maskMatrix);
1378
+ $poolFloat32Array6(playerMatrix);
1379
+ if (context.isLayer) {
1380
+ const currentPosition = context.getCurrentPosition();
1381
+ maskMatrix[4] -= currentPosition.xMin;
1382
+ maskMatrix[5] -= currentPosition.yMin;
1383
+ }
1384
+ if (context.cacheBounds) {
1385
+ maskMatrix[4] -= context.cacheBounds.xMin;
1386
+ maskMatrix[5] -= context.cacheBounds.yMin;
1387
+ }
1388
+ }
1389
+ if (!maskInstance._$shouldClip(maskMatrix)) {
1390
+ continue;
1391
+ }
1392
+ const adjMatrix = maskInstance._$startClip(context, maskMatrix);
1393
+ context.save();
1394
+ if (adjMatrix === false) { // fixed
1395
+ context.restore();
1396
+ continue;
1397
+ }
1398
+ if (adjMatrix instanceof Float32Array) {
1399
+ instanceMatrix.push(preMatrix);
1400
+ if (this !== maskInstance._$parent) {
1401
+ const rawMatrix = transform._$rawMatrix();
1402
+ adjMatrix[0] = $Math.abs(preMatrix[0]) * $Math.sign(rawMatrix[0]);
1403
+ adjMatrix[1] = $Math.abs(preMatrix[1]) * $Math.sign(rawMatrix[1]);
1404
+ adjMatrix[2] = $Math.abs(preMatrix[2]) * $Math.sign(rawMatrix[2]);
1405
+ adjMatrix[3] = $Math.abs(preMatrix[3]) * $Math.sign(rawMatrix[3]);
1406
+ adjMatrix[4] = preMatrix[4] - context.cacheBounds.xMin;
1407
+ adjMatrix[5] = preMatrix[5] - context.cacheBounds.yMin;
1408
+ }
1409
+ preMatrix = adjMatrix;
1410
+ }
1411
+ }
1412
+ instance._$draw(context, preMatrix, preColorTransform);
1413
+ instance._$updated = false;
1414
+ // mask end
1415
+ if (maskInstance) {
1416
+ context.restore();
1417
+ context._$leaveClip();
1418
+ if (instanceMatrix.length) {
1419
+ const matrix = instanceMatrix.pop();
1420
+ if (matrix) {
1421
+ $poolFloat32Array6(preMatrix);
1422
+ preMatrix = matrix;
1423
+ }
1424
+ }
1425
+ }
1426
+ }
1427
+ // end mask
1428
+ if (clipDepth) {
1429
+ context.restore();
1430
+ if (shouldClips.pop()) {
1431
+ context._$leaveClip();
1432
+ }
1433
+ }
1434
+ // object pool
1435
+ $poolArray(clipMatrix);
1436
+ $poolArray(instanceMatrix);
1437
+ $poolArray(clipStack);
1438
+ $poolArray(shouldClips);
1439
+ // filter and blend
1440
+ if (preObject.isFilter) {
1441
+ return this._$postDraw(context, matrix, multiColor, preObject);
1442
+ }
1443
+ if (preObject.matrix !== matrix) {
1444
+ $poolFloat32Array6(preObject.matrix);
1445
+ }
1446
+ if (multiColor !== color_transform) {
1447
+ $poolFloat32Array8(multiColor);
1448
+ }
1449
+ $poolPreObject(preObject);
1450
+ }
1451
+ /**
1452
+ * @param {CanvasRenderingContext2D} context
1453
+ * @param {Float32Array} matrix
1454
+ * @param {object} options
1455
+ * @param {boolean} [mouse_children=true]
1456
+ * @return {boolean}
1457
+ * @method
1458
+ * @private
1459
+ */
1460
+ _$mouseHit(context, matrix, options, mouse_children = true) {
1461
+ let multiMatrix = matrix;
1462
+ const rawMatrix = this._$transform._$rawMatrix();
1463
+ if (rawMatrix !== $MATRIX_ARRAY_IDENTITY) {
1464
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1465
+ }
1466
+ const children = this._$getChildren();
1467
+ // mask set
1468
+ const clips = $getArray();
1469
+ const targets = $getArray();
1470
+ const clipIndexes = $getMap();
1471
+ let clipDepth = 0;
1472
+ let clipIdx = 0;
1473
+ for (let idx = 0; idx < children.length; ++idx) {
1474
+ const instance = children[idx];
1475
+ if (!instance._$visible && !instance._$hitObject) {
1476
+ continue;
1477
+ }
1478
+ if (instance._$clipDepth) {
1479
+ clipIdx = clips.length;
1480
+ clipDepth = instance._$clipDepth;
1481
+ clips.push(instance);
1482
+ continue;
1483
+ }
1484
+ // clip end
1485
+ if (clipDepth && instance._$placeId > clipDepth) {
1486
+ clipIdx = 0;
1487
+ clipDepth = 0;
1488
+ }
1489
+ // clip check on
1490
+ if (clipIdx) {
1491
+ clipIndexes.set(instance._$instanceId, clipIdx);
1492
+ }
1493
+ targets.push(instance);
1494
+ }
1495
+ // setup
1496
+ const mouseChildren = this._$mouseChildren && mouse_children;
1497
+ let hit = false;
1498
+ const isRoot = this._$root === this;
1499
+ while (targets.length) {
1500
+ const instance = targets.pop();
1501
+ if (instance._$isMask) {
1502
+ continue;
1503
+ }
1504
+ if (isRoot && !(instance instanceof InteractiveObject)) {
1505
+ continue;
1506
+ }
1507
+ // mask target
1508
+ if (clipIndexes.has(instance._$instanceId)) {
1509
+ const index = clipIndexes.get(instance._$instanceId);
1510
+ if (!index) {
1511
+ continue;
1512
+ }
1513
+ const clip = clips[index];
1514
+ if (!clip._$hit(context, multiMatrix, options, true)) {
1515
+ continue;
1516
+ }
1517
+ }
1518
+ // mask hit test
1519
+ const maskInstance = instance._$mask;
1520
+ if (maskInstance) {
1521
+ if (this === maskInstance._$parent) {
1522
+ if (!maskInstance._$hit(context, multiMatrix, options, true)) {
1523
+ continue;
1524
+ }
1525
+ }
1526
+ else {
1527
+ let maskMatrix = $MATRIX_ARRAY_IDENTITY;
1528
+ let parent = maskInstance._$parent;
1529
+ while (parent) {
1530
+ maskMatrix = $multiplicationMatrix(parent._$transform._$rawMatrix(), maskMatrix);
1531
+ parent = parent._$parent;
1532
+ }
1533
+ if (!maskInstance._$hit(context, maskMatrix, options, true)) {
1534
+ continue;
1535
+ }
1536
+ }
1537
+ }
1538
+ if (instance._$mouseHit(context, multiMatrix, options, mouseChildren)
1539
+ || instance._$hitArea
1540
+ && instance
1541
+ ._$hitArea
1542
+ ._$mouseHit(context, multiMatrix, options, mouseChildren)) {
1543
+ if (instance._$root === instance) {
1544
+ return true;
1545
+ }
1546
+ if (!mouseChildren) {
1547
+ return true;
1548
+ }
1549
+ hit = true;
1550
+ if (instance instanceof InteractiveObject) {
1551
+ if (!instance.mouseEnabled && !instance._$hitObject) {
1552
+ continue;
1553
+ }
1554
+ if (!$isTouch && !options.pointer) {
1555
+ if ("_$text" in instance
1556
+ && "type" in instance
1557
+ && instance.type === "input") {
1558
+ options.pointer = "text";
1559
+ }
1560
+ if ("buttonMode" in instance
1561
+ && "useHandCursor" in instance
1562
+ && instance.buttonMode
1563
+ && instance.useHandCursor) {
1564
+ options.pointer = "pointer";
1565
+ }
1566
+ }
1567
+ if (!options.hit) {
1568
+ options.hit = !instance.mouseEnabled && instance._$hitObject
1569
+ ? instance._$hitObject
1570
+ : instance;
1571
+ }
1572
+ return true;
1573
+ }
1574
+ }
1575
+ }
1576
+ // pool
1577
+ $poolArray(clips);
1578
+ $poolArray(targets);
1579
+ $poolMap(clipIndexes);
1580
+ // graphics
1581
+ if (!hit) {
1582
+ const graphics = "_$graphics" in this
1583
+ ? this._$graphics
1584
+ : null;
1585
+ if (graphics) {
1586
+ hit = graphics._$hit(context, multiMatrix, options);
1587
+ }
1588
+ }
1589
+ if (multiMatrix !== matrix) {
1590
+ $poolFloat32Array6(multiMatrix);
1591
+ }
1592
+ // not found
1593
+ return hit;
1594
+ }
1595
+ /**
1596
+ * @param {CanvasRenderingContext2D} context
1597
+ * @param {Float32Array} matrix
1598
+ * @param {object} options
1599
+ * @param {boolean} [is_clip=false]
1600
+ * @return {boolean}
1601
+ * @method
1602
+ * @private
1603
+ */
1604
+ _$hit(context, matrix, options, is_clip = false) {
1605
+ let multiMatrix = matrix;
1606
+ const rawMatrix = this._$transform._$rawMatrix();
1607
+ if (rawMatrix !== $MATRIX_ARRAY_IDENTITY) {
1608
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1609
+ }
1610
+ const children = this._$getChildren();
1611
+ for (let idx = children.length; idx > -1; --idx) {
1612
+ const instance = children[idx];
1613
+ if (instance._$isMask) {
1614
+ continue;
1615
+ }
1616
+ if (instance._$hit(context, multiMatrix, options, is_clip)) {
1617
+ return true;
1618
+ }
1619
+ }
1620
+ let hit = false;
1621
+ const graphics = "_$graphics" in this
1622
+ ? this._$graphics
1623
+ : null;
1624
+ if (graphics) {
1625
+ hit = graphics._$hit(context, multiMatrix, options);
1626
+ }
1627
+ if (multiMatrix !== matrix) {
1628
+ $poolFloat32Array6(multiMatrix);
1629
+ }
1630
+ return hit;
1631
+ }
1632
+ /**
1633
+ * @param {number} index
1634
+ * @return {DisplayObject}
1635
+ * @method
1636
+ * @private
1637
+ */
1638
+ _$createInstance(index) {
1639
+ if (!this._$dictionary) {
1640
+ throw new Error("the dictionary is null.");
1641
+ }
1642
+ // build
1643
+ const tag = this._$dictionary[index];
1644
+ const loaderInfo = this._$loaderInfo;
1645
+ if (!loaderInfo || !loaderInfo._$data) {
1646
+ throw new Error("the loaderInfo or data is null.");
1647
+ }
1648
+ const character = loaderInfo._$data.characters[tag.characterId];
1649
+ // symbol class
1650
+ const instance = $createInstance(character.extends);
1651
+ instance._$build(tag, this);
1652
+ instance._$id = index;
1653
+ return instance;
1654
+ }
1655
+ /**
1656
+ * @param {number} x
1657
+ * @param {number} y
1658
+ * @return {boolean}
1659
+ * @method
1660
+ * @private
1661
+ */
1662
+ _$outCheck(x, y) {
1663
+ let matrix = $MATRIX_ARRAY_IDENTITY;
1664
+ let parent = this._$parent;
1665
+ while (parent) {
1666
+ matrix = $multiplicationMatrix(parent._$transform._$rawMatrix(), matrix);
1667
+ parent = parent._$parent;
1668
+ }
1669
+ $hitContext.setTransform(1, 0, 0, 1, 0, 0);
1670
+ $hitContext.beginPath();
1671
+ const options = {
1672
+ "x": x,
1673
+ "y": y,
1674
+ "pointer": "",
1675
+ "hit": null
1676
+ };
1677
+ return this._$mouseHit($hitContext, matrix, options);
1678
+ }
1679
+ /**
1680
+ * @return {void}
1681
+ * @method
1682
+ * @private
1683
+ */
1684
+ _$createWorkerInstance() {
1685
+ if (this._$created || !$rendererWorker) {
1686
+ return;
1687
+ }
1688
+ this._$created = true;
1689
+ const options = $getArray();
1690
+ const message = {
1691
+ "command": "createDisplayObjectContainer",
1692
+ "instanceId": this._$instanceId,
1693
+ "parentId": this._$parent ? this._$parent._$instanceId : -1
1694
+ };
1695
+ const graphics = "_$graphics" in this
1696
+ ? this._$graphics
1697
+ : null;
1698
+ if (graphics) {
1699
+ const recodes = graphics._$getRecodes();
1700
+ options.push(recodes.buffer);
1701
+ message.recodes = recodes;
1702
+ message.maxAlpha = graphics._$maxAlpha;
1703
+ message.canDraw = graphics._$canDraw;
1704
+ message.xMin = graphics._$xMin;
1705
+ message.yMin = graphics._$yMin;
1706
+ message.xMax = graphics._$xMax;
1707
+ message.yMax = graphics._$yMax;
1708
+ }
1709
+ $rendererWorker.postMessage(message, options);
1710
+ }
1711
+ /**
1712
+ * @return {object}
1713
+ * @method
1714
+ * @private
1715
+ */
1716
+ _$postProperty() {
1717
+ if (!$rendererWorker) {
1718
+ return;
1719
+ }
1720
+ this._$postChildrenIds();
1721
+ const options = $getArray();
1722
+ const message = this._$createMessage();
1723
+ const graphics = "_$graphics" in this
1724
+ ? this._$graphics
1725
+ : null;
1726
+ if (graphics && !graphics._$buffer) {
1727
+ message.maxAlpha = graphics._$maxAlpha;
1728
+ message.canDraw = graphics._$canDraw;
1729
+ const recodes = graphics._$getRecodes();
1730
+ message.recodes = recodes;
1731
+ options.push(recodes.buffer);
1732
+ const bounds = this._$getBounds();
1733
+ message.xMin = bounds.xMin;
1734
+ message.yMin = bounds.yMin;
1735
+ message.xMax = bounds.xMax;
1736
+ message.yMax = bounds.yMax;
1737
+ }
1738
+ $rendererWorker
1739
+ .postMessage(message, options);
1740
+ $poolArray(options);
1741
+ this._$posted = true;
1742
+ this._$updated = false;
1743
+ }
1744
+ /**
1745
+ * @param {array} [childrenIds=null]
1746
+ * @return {void}
1747
+ * @method
1748
+ * @private
1749
+ */
1750
+ _$postChildrenIds(childrenIds = null) {
1751
+ if (!$rendererWorker) {
1752
+ return;
1753
+ }
1754
+ if (!childrenIds) {
1755
+ const children = this._$getChildren();
1756
+ childrenIds = $getArray();
1757
+ for (let idx = 0; idx < children.length; ++idx) {
1758
+ childrenIds.push(children[idx]._$instanceId);
1759
+ }
1760
+ $rendererWorker.postMessage({
1761
+ "command": "setChildren",
1762
+ "instanceId": this._$instanceId,
1763
+ "children": childrenIds
1764
+ });
1765
+ $poolArray(childrenIds);
1766
+ }
1767
+ else {
1768
+ $rendererWorker.postMessage({
1769
+ "command": "setChildren",
1770
+ "instanceId": this._$instanceId,
1771
+ "children": childrenIds
1772
+ });
1773
+ }
1774
+ }
1775
+ }