@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,1671 @@
1
+ import { Event as Next2DEvent, EventDispatcher } from "@next2d/events";
2
+ import { Transform, Rectangle, Point } from "@next2d/geom";
3
+ import { $getEvent, $getInstanceId, $currentMousePoint, $currentPlayer, $poolColorTransform, $rendererWorker, $poolMatrix, $hitContext, $variables } from "@next2d/util";
4
+ import { $doUpdated, $clamp, $getArray, $boundsMatrix, $Math, $poolBoundsObject, $Infinity, $getBoundsObject, $isNaN, $Deg2Rad, $Number, $Rad2Deg, $SHORT_INT_MIN, $SHORT_INT_MAX, $MATRIX_ARRAY_IDENTITY, $multiplicationMatrix, $poolFloat32Array6, $getMap, $poolMap, $getFloat32Array6 } from "@next2d/share";
5
+ /**
6
+ * DisplayObject クラスは、表示リストに含めることのできるすべてのオブジェクトに関する基本クラスです。
7
+ * DisplayObject クラス自体は、画面上でのコンテンツの描画のための API を含みません。
8
+ * そのため、DisplayObject クラスのカスタムサブクラスを作成する場合は、
9
+ * Shape、Sprite、Bitmap、TextField または MovieClip など、
10
+ * 画面上にコンテンツを描画する API を持つサブクラスの 1 つを拡張する必要があります。
11
+ *
12
+ * The DisplayObject class is the base class for all objects that can be placed on the display list.
13
+ * The DisplayObject class itself does not include any APIs for rendering content onscreen.
14
+ * For that reason, if you want create a custom subclass of the DisplayObject class,
15
+ * you will want to extend one of its subclasses that do have APIs for rendering content onscreen,
16
+ * such as the Shape, Sprite, Bitmap, TextField, or MovieClip class.
17
+ *
18
+ * @class
19
+ * @memberOf next2d.display
20
+ * @extends EventDispatcher
21
+ */
22
+ export class DisplayObject extends EventDispatcher {
23
+ /**
24
+ * @constructor
25
+ * @public
26
+ */
27
+ constructor() {
28
+ super();
29
+ /**
30
+ * @type {number}
31
+ * @private
32
+ */
33
+ this._$id = -1;
34
+ /**
35
+ * @type {number}
36
+ * @private
37
+ */
38
+ this._$instanceId = $getInstanceId();
39
+ /**
40
+ * @type {number}
41
+ * @private
42
+ */
43
+ this._$characterId = 0;
44
+ /**
45
+ * @type {boolean}
46
+ * @default false
47
+ * @private
48
+ */
49
+ this._$active = false;
50
+ /**
51
+ * @type {boolean}
52
+ * @default false
53
+ * @private
54
+ */
55
+ this._$isMask = false;
56
+ /**
57
+ * @type {boolean}
58
+ * @default false
59
+ * @private
60
+ */
61
+ this._$updated = true;
62
+ /**
63
+ * @type {boolean}
64
+ * @default false
65
+ * @private
66
+ */
67
+ this._$added = false;
68
+ /**
69
+ * @type {boolean}
70
+ * @default false
71
+ * @private
72
+ */
73
+ this._$addedStage = false;
74
+ /**
75
+ * @type {array|null}
76
+ * @default null
77
+ * @private
78
+ */
79
+ this._$filters = null;
80
+ /**
81
+ * @type {string|null}
82
+ * @default null
83
+ * @private
84
+ */
85
+ this._$blendMode = null;
86
+ /**
87
+ * @type {Sprite|null}
88
+ * @default null
89
+ * @private
90
+ */
91
+ this._$hitObject = null;
92
+ /**
93
+ * @type {boolean}
94
+ * @default true
95
+ * @private
96
+ */
97
+ this._$isNext = true;
98
+ /**
99
+ * @type {boolean}
100
+ * @default false
101
+ * @private
102
+ */
103
+ this._$created = false;
104
+ /**
105
+ * @type {boolean}
106
+ * @default false
107
+ * @private
108
+ */
109
+ this._$posted = false;
110
+ /**
111
+ * @type {number}
112
+ * @default 0
113
+ * @private
114
+ */
115
+ this._$clipDepth = 0;
116
+ /**
117
+ * @type {string}
118
+ * @default ""
119
+ * @private
120
+ */
121
+ this._$name = "";
122
+ /**
123
+ * @type {boolean}
124
+ * @default true
125
+ * @private
126
+ */
127
+ this._$visible = true;
128
+ /**
129
+ * @type {DisplayObject|null}
130
+ * @default null
131
+ * @private
132
+ */
133
+ this._$mask = null;
134
+ /**
135
+ * @type {Rectangle|null}
136
+ * @default null
137
+ * @private
138
+ */
139
+ this._$scale9Grid = null;
140
+ /**
141
+ * @type {Sprite | null}
142
+ * @default null
143
+ * @private
144
+ */
145
+ this._$parent = null;
146
+ /**
147
+ * @type {Stage|null}
148
+ * @default null
149
+ * @private
150
+ */
151
+ this._$stage = null;
152
+ /**
153
+ * @type {Sprite|null}
154
+ * @default null
155
+ * @private
156
+ */
157
+ this._$root = null;
158
+ /**
159
+ * @type {number|null}
160
+ * @default null
161
+ * @private
162
+ */
163
+ this._$loaderInfo = null;
164
+ /**
165
+ * @type {number|null}
166
+ * @default null
167
+ * @private
168
+ */
169
+ this._$placeId = -1;
170
+ /**
171
+ * @type {number}
172
+ * @default null
173
+ * @private
174
+ */
175
+ this._$startFrame = 1;
176
+ /**
177
+ * @type {number}
178
+ * @default 0
179
+ * @private
180
+ */
181
+ this._$endFrame = 0;
182
+ /**
183
+ * @type {Transform}
184
+ * @private
185
+ */
186
+ this._$transform = new Transform(this);
187
+ /**
188
+ * @type {Map}
189
+ * @default null
190
+ * @private
191
+ */
192
+ this._$variables = null;
193
+ /**
194
+ * @type {object}
195
+ * @default null
196
+ * @private
197
+ */
198
+ this._$placeObject = null;
199
+ /**
200
+ * @type {number}
201
+ * @default -1
202
+ * @private
203
+ */
204
+ this._$currentPlaceId = -1;
205
+ /**
206
+ * @type {boolean}
207
+ * @default false
208
+ * @private
209
+ */
210
+ this._$changePlace = false;
211
+ /**
212
+ * @type {number}
213
+ * @default null
214
+ * @private
215
+ */
216
+ this._$scaleX = null;
217
+ /**
218
+ * @type {number}
219
+ * @default null
220
+ * @private
221
+ */
222
+ this._$scaleY = null;
223
+ /**
224
+ * @type {number}
225
+ * @default null
226
+ * @private
227
+ */
228
+ this._$rotation = null;
229
+ }
230
+ /**
231
+ * @description 指定されたオブジェクトのアルファ透明度値を示します。
232
+ * 有効な値は 0.0(完全な透明)~ 1.0(完全な不透明)です。
233
+ * デフォルト値は 1.0 です。alpha が 0.0 に設定されている表示オブジェクトは、
234
+ * 表示されない場合でも、アクティブです。
235
+ * Indicates the alpha transparency value of the object specified.
236
+ * Valid values are 0.0 (fully transparent) to 1.0 (fully opaque).
237
+ * The default value is 1.0. Display objects with alpha set to 0.0 are active,
238
+ * even though they are invisible.
239
+ *
240
+ * @member {number}
241
+ * @default 1
242
+ * @public
243
+ */
244
+ get alpha() {
245
+ const colorTransform = this
246
+ ._$transform
247
+ ._$rawColorTransform();
248
+ return colorTransform[3] + colorTransform[7] / 255;
249
+ }
250
+ set alpha(alpha) {
251
+ alpha = $clamp(alpha, 0, 1, 0);
252
+ // clone
253
+ const colorTransform = this
254
+ ._$transform
255
+ .colorTransform;
256
+ colorTransform._$colorTransform[3] = alpha;
257
+ colorTransform._$colorTransform[7] = 0;
258
+ this._$transform.colorTransform = colorTransform;
259
+ $poolColorTransform(colorTransform);
260
+ }
261
+ /**
262
+ * @description 使用するブレンドモードを指定する BlendMode クラスの値です。
263
+ * A value from the BlendMode class that specifies which blend mode to use.
264
+ *
265
+ * @member {string}
266
+ * @default BlendMode.NORMAL
267
+ * @public
268
+ */
269
+ get blendMode() {
270
+ // use cache
271
+ if (this._$blendMode) {
272
+ return this._$blendMode;
273
+ }
274
+ const transform = this._$transform;
275
+ if (transform._$blendMode) {
276
+ // cache
277
+ this._$blendMode = transform._$blendMode;
278
+ return transform._$blendMode;
279
+ }
280
+ const placeObject = this._$getPlaceObject();
281
+ if (placeObject && placeObject.blendMode) {
282
+ // cache
283
+ this._$blendMode = placeObject.blendMode;
284
+ return placeObject.blendMode;
285
+ }
286
+ // cache
287
+ this._$blendMode = "normal";
288
+ return "normal";
289
+ }
290
+ set blendMode(blend_mode) {
291
+ this._$transform._$transform(null, null, null, blend_mode);
292
+ this._$blendMode = blend_mode;
293
+ }
294
+ /**
295
+ * @description 表示オブジェクトに現在関連付けられている各フィルターオブジェクトが
296
+ * 格納されているインデックス付きの配列です。
297
+ * An indexed array that contains each filter object
298
+ * currently associated with the display object.
299
+ *
300
+ * @member {array}
301
+ * @default {array}
302
+ * @public
303
+ */
304
+ get filters() {
305
+ // use cache
306
+ if (this._$filters) {
307
+ const filters = $getArray();
308
+ for (let idx = 0; idx < this._$filters.length; ++idx) {
309
+ filters[idx] = this._$filters[idx].clone();
310
+ }
311
+ return filters;
312
+ }
313
+ const transform = this._$transform;
314
+ if (transform._$filters) {
315
+ const clone = $getArray();
316
+ const filters = $getArray();
317
+ for (let idx = 0; idx < transform._$filters.length; ++idx) {
318
+ const filter = transform._$filters[idx];
319
+ clone[idx] = filter.clone();
320
+ filters[idx] = filter.clone();
321
+ }
322
+ // cache
323
+ this._$filters = clone;
324
+ return filters;
325
+ }
326
+ const placeObject = this._$getPlaceObject();
327
+ if (placeObject && placeObject.surfaceFilterList) {
328
+ // create filter
329
+ if (!placeObject.filters) {
330
+ placeObject.filters = transform
331
+ ._$buildFilter(placeObject.surfaceFilterList);
332
+ }
333
+ const clone = $getArray();
334
+ // @ts-ignore
335
+ const filters = $getArray();
336
+ for (let idx = 0; idx < placeObject.filters.length; ++idx) {
337
+ const filter = placeObject.filters[idx];
338
+ clone[idx] = filter.clone();
339
+ filters[idx] = filter.clone();
340
+ }
341
+ // cache
342
+ this._$filters = clone;
343
+ return filters;
344
+ }
345
+ const filters = $getArray();
346
+ // cache
347
+ this._$filters = filters;
348
+ return filters;
349
+ }
350
+ set filters(filters) {
351
+ if (!filters) {
352
+ filters = $getArray();
353
+ }
354
+ this._$transform._$transform(null, null, filters);
355
+ this._$filters = filters;
356
+ }
357
+ /**
358
+ * @description 表示オブジェクトの高さを示します(ピクセル単位)。
359
+ * Indicates the height of the display object, in pixels.
360
+ *
361
+ * @member {number}
362
+ * @public
363
+ */
364
+ get height() {
365
+ const baseBounds = "_$getBounds" in this && typeof this._$getBounds === "function"
366
+ ? this._$getBounds()
367
+ : $getBoundsObject();
368
+ const bounds = $boundsMatrix(baseBounds, this._$transform._$rawMatrix());
369
+ $poolBoundsObject(baseBounds);
370
+ const height = $Math.abs(bounds.yMax - bounds.yMin);
371
+ // object pool
372
+ $poolBoundsObject(bounds);
373
+ switch (height) {
374
+ case 0:
375
+ case $Infinity:
376
+ case -$Infinity:
377
+ return 0;
378
+ default:
379
+ return +height.toFixed(2);
380
+ }
381
+ }
382
+ set height(height) {
383
+ height = +height;
384
+ if (!$isNaN(height) && height > -1) {
385
+ const baseBounds = "_$getBounds" in this && typeof this._$getBounds === "function"
386
+ ? this._$getBounds()
387
+ : $getBoundsObject();
388
+ const rotation = this.rotation;
389
+ const bounds = rotation
390
+ ? $boundsMatrix(baseBounds, this._$transform._$rawMatrix())
391
+ : baseBounds;
392
+ if (rotation) {
393
+ $poolBoundsObject(baseBounds);
394
+ }
395
+ const exHeight = $Math.abs(bounds.yMax - bounds.yMin);
396
+ $poolBoundsObject(bounds);
397
+ switch (exHeight) {
398
+ case 0:
399
+ case $Infinity:
400
+ case -$Infinity:
401
+ this.scaleY = 0;
402
+ break;
403
+ default:
404
+ this.scaleY = height / exHeight;
405
+ break;
406
+ }
407
+ }
408
+ }
409
+ /**
410
+ * @description この表示オブジェクトが属するファイルの読み込み情報を含む LoaderInfo オブジェクトを返します。
411
+ * Returns a LoaderInfo object containing information
412
+ * about loading the file to which this display object belongs.
413
+ *
414
+ * @member {LoaderInfo}
415
+ * @default null
416
+ * @readonly
417
+ * @public
418
+ */
419
+ get loaderInfo() {
420
+ return this._$loaderInfo;
421
+ }
422
+ /**
423
+ * @description 呼び出し元の表示オブジェクトは、指定された mask オブジェクトによってマスクされます。
424
+ * The calling display object is masked by the specified mask object.
425
+ *
426
+ * @member {DisplayObject|null}
427
+ * @public
428
+ */
429
+ get mask() {
430
+ return this._$mask;
431
+ }
432
+ set mask(mask) {
433
+ if (mask === this._$mask) {
434
+ return;
435
+ }
436
+ // reset
437
+ if (this._$mask) {
438
+ if ($rendererWorker && this._$mask.stage) {
439
+ this._$mask._$removeWorkerInstance();
440
+ }
441
+ this._$mask._$isMask = false;
442
+ this._$mask = null;
443
+ }
444
+ if (mask) {
445
+ if ($rendererWorker
446
+ && "_$createWorkerInstance" in mask
447
+ && typeof mask._$createWorkerInstance === "function") {
448
+ mask._$createWorkerInstance();
449
+ }
450
+ mask._$isMask = true;
451
+ this._$mask = mask;
452
+ }
453
+ this._$doChanged();
454
+ }
455
+ /**
456
+ * @description マウスまたはユーザー入力デバイスの x 軸の位置をピクセルで示します。
457
+ * Indicates the x coordinate of the mouse or user input device position, in pixels.
458
+ *
459
+ * @member {number}
460
+ * @default 0
461
+ * @readonly
462
+ * @public
463
+ */
464
+ get mouseX() {
465
+ return $getEvent()
466
+ ? this.globalToLocal($currentMousePoint()).x
467
+ : 0;
468
+ }
469
+ /**
470
+ * @description マウスまたはユーザー入力デバイスの y 軸の位置をピクセルで示します。
471
+ * Indicates the y coordinate of the mouse or user input device position, in pixels.
472
+ *
473
+ * @member {number}
474
+ * @default 0
475
+ * @readonly
476
+ * @public
477
+ */
478
+ get mouseY() {
479
+ return $getEvent()
480
+ ? this.globalToLocal($currentMousePoint()).y
481
+ : 0;
482
+ }
483
+ /**
484
+ * @description DisplayObject のインスタンス名を示します。
485
+ * Indicates the instance name of the DisplayObject.
486
+ *
487
+ * @member {string}
488
+ * @public
489
+ */
490
+ get name() {
491
+ if (this._$name) {
492
+ return this._$name;
493
+ }
494
+ return `instance${this._$instanceId}`;
495
+ }
496
+ set name(name) {
497
+ this._$name = `${name}`;
498
+ const parent = this._$parent;
499
+ if (parent && parent._$names) {
500
+ parent._$names.clear();
501
+ const children = parent._$getChildren();
502
+ for (let idx = 0; idx < children.length; ++idx) {
503
+ const child = children[idx];
504
+ if (child._$name) {
505
+ parent._$names.set(child.name, child);
506
+ }
507
+ }
508
+ }
509
+ }
510
+ /**
511
+ * @description この表示オブジェクトを含む DisplayObjectContainer オブジェクトを示します。
512
+ * Indicates the DisplayObjectContainer object that contains this display object.
513
+ *
514
+ * @member {DisplayObjectContainer | null}
515
+ * @readonly
516
+ * @public
517
+ */
518
+ get parent() {
519
+ return this._$parent;
520
+ }
521
+ /**
522
+ * @description 読み込まれた SWF ファイル内の表示オブジェクトの場合、
523
+ * root プロパティはその SWF ファイルが表す表示リストのツリー構造部分の一番上にある表示オブジェクトとなります。
524
+ * For a display object in a loaded SWF file,
525
+ * the root property is the top-most display object
526
+ * in the portion of the display list's tree structure represented by that SWF file.
527
+ *
528
+ * @member {DisplayObject|null}
529
+ * @readonly
530
+ * @public
531
+ */
532
+ get root() {
533
+ return this._$root;
534
+ }
535
+ /**
536
+ * @description DisplayObject インスタンスの元の位置からの回転角を度単位で示します。
537
+ * Indicates the rotation of the DisplayObject instance,
538
+ * in degrees, from its original orientation.
539
+ *
540
+ * @member {number}
541
+ * @public
542
+ */
543
+ get rotation() {
544
+ if (this._$rotation !== null) {
545
+ return this._$rotation;
546
+ }
547
+ const matrix = this._$transform._$rawMatrix();
548
+ return $Math.atan2(matrix[1], matrix[0]) * $Rad2Deg;
549
+ }
550
+ set rotation(rotation) {
551
+ rotation = $clamp(rotation % 360, 0 - 360, 360, 0);
552
+ if (this._$rotation === rotation) {
553
+ return;
554
+ }
555
+ const transform = this._$transform;
556
+ const matrix = transform.matrix;
557
+ const scaleX = $Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b);
558
+ const scaleY = $Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d);
559
+ if (rotation === 0) {
560
+ matrix.a = scaleX;
561
+ matrix.b = 0;
562
+ matrix.c = 0;
563
+ matrix.d = scaleY;
564
+ }
565
+ else {
566
+ let radianX = $Math.atan2(matrix.b, matrix.a);
567
+ let radianY = $Math.atan2(0 - matrix.c, matrix.d);
568
+ const radian = rotation * $Deg2Rad;
569
+ radianY = radianY + radian - radianX;
570
+ radianX = radian;
571
+ matrix.b = scaleX * $Math.sin(radianX);
572
+ if (matrix.b === 1 || matrix.b === -1) {
573
+ matrix.a = 0;
574
+ }
575
+ else {
576
+ matrix.a = scaleX * $Math.cos(radianX);
577
+ }
578
+ matrix.c = -scaleY * $Math.sin(radianY);
579
+ if (matrix.c === 1 || matrix.c === -1) {
580
+ matrix.d = 0;
581
+ }
582
+ else {
583
+ matrix.d = scaleY * $Math.cos(radianY);
584
+ }
585
+ }
586
+ transform.matrix = matrix;
587
+ $poolMatrix(matrix);
588
+ this._$rotation = rotation;
589
+ }
590
+ /**
591
+ * @description 現在有効な拡大 / 縮小グリッドです。
592
+ * The current scaling grid that is in effect.
593
+ *
594
+ * @member {Rectangle}
595
+ * @public
596
+ */
597
+ get scale9Grid() {
598
+ return this._$scale9Grid;
599
+ }
600
+ set scale9Grid(scale_9_grid) {
601
+ if (this._$scale9Grid !== scale_9_grid) {
602
+ this._$scale9Grid = scale_9_grid;
603
+ this._$doChanged();
604
+ $doUpdated();
605
+ }
606
+ }
607
+ /**
608
+ * @description 基準点から適用されるオブジェクトの水平スケール(パーセンテージ)を示します。
609
+ * Indicates the horizontal scale (percentage)
610
+ * of the object as applied from the registration point.
611
+ *
612
+ * @member {number}
613
+ * @public
614
+ */
615
+ get scaleX() {
616
+ if (this._$scaleX !== null) {
617
+ return this._$scaleX;
618
+ }
619
+ const matrix = this._$transform._$rawMatrix();
620
+ let xScale = $Math.sqrt(matrix[0] * matrix[0]
621
+ + matrix[1] * matrix[1]);
622
+ if (!$Number.isInteger(xScale)) {
623
+ const value = xScale.toString();
624
+ const index = value.indexOf("e");
625
+ if (index !== -1) {
626
+ xScale = +value.slice(0, index);
627
+ }
628
+ xScale = +xScale.toFixed(4);
629
+ }
630
+ return 0 > matrix[0] ? xScale * -1 : xScale;
631
+ }
632
+ set scaleX(scale_x) {
633
+ scale_x = $clamp(+scale_x, $SHORT_INT_MIN, $SHORT_INT_MAX);
634
+ if (!$Number.isInteger(scale_x)) {
635
+ const value = scale_x.toString();
636
+ const index = value.indexOf("e");
637
+ if (index !== -1) {
638
+ scale_x = +value.slice(0, index);
639
+ }
640
+ scale_x = +scale_x.toFixed(4);
641
+ }
642
+ if (this._$scaleX === scale_x) {
643
+ return;
644
+ }
645
+ const transform = this._$transform;
646
+ const matrix = transform.matrix;
647
+ if (matrix.b === 0 || $isNaN(matrix.b)) {
648
+ matrix.a = scale_x;
649
+ }
650
+ else {
651
+ let radianX = $Math.atan2(matrix.b, matrix.a);
652
+ if (radianX === -$Math.PI) {
653
+ radianX = 0;
654
+ }
655
+ matrix.b = scale_x * $Math.sin(radianX);
656
+ matrix.a = scale_x * $Math.cos(radianX);
657
+ }
658
+ transform.matrix = matrix;
659
+ $poolMatrix(matrix);
660
+ this._$scaleX = scale_x;
661
+ }
662
+ /**
663
+ * @description 基準点から適用されるオブジェクトの垂直スケール(パーセンテージ)を示します。
664
+ * IIndicates the vertical scale (percentage)
665
+ * of an object as applied from the registration point.
666
+ *
667
+ * @member {number}
668
+ * @public
669
+ */
670
+ get scaleY() {
671
+ if (this._$scaleY !== null) {
672
+ return this._$scaleY;
673
+ }
674
+ const matrix = this._$transform._$rawMatrix();
675
+ let yScale = $Math.sqrt(matrix[2] * matrix[2]
676
+ + matrix[3] * matrix[3]);
677
+ if (!$Number.isInteger(yScale)) {
678
+ const value = yScale.toString();
679
+ const index = value.indexOf("e");
680
+ if (index !== -1) {
681
+ yScale = +value.slice(0, index);
682
+ }
683
+ yScale = +yScale.toFixed(4);
684
+ }
685
+ return 0 > matrix[3] ? yScale * -1 : yScale;
686
+ }
687
+ set scaleY(scale_y) {
688
+ scale_y = $clamp(+scale_y, $SHORT_INT_MIN, $SHORT_INT_MAX);
689
+ if (!$Number.isInteger(scale_y)) {
690
+ const value = scale_y.toString();
691
+ const index = value.indexOf("e");
692
+ if (index !== -1) {
693
+ scale_y = +value.slice(0, index);
694
+ }
695
+ scale_y = +scale_y.toFixed(4);
696
+ }
697
+ if (this._$scaleY === scale_y) {
698
+ return;
699
+ }
700
+ const transform = this._$transform;
701
+ const matrix = transform.matrix;
702
+ if (matrix.c === 0 || $isNaN(matrix.c)) {
703
+ matrix.d = scale_y;
704
+ }
705
+ else {
706
+ let radianY = $Math.atan2(-matrix.c, matrix.d);
707
+ if (radianY === -$Math.PI) {
708
+ radianY = 0;
709
+ }
710
+ matrix.c = -scale_y * $Math.sin(radianY);
711
+ matrix.d = scale_y * $Math.cos(radianY);
712
+ }
713
+ transform.matrix = matrix;
714
+ $poolMatrix(matrix);
715
+ this._$scaleY = scale_y;
716
+ }
717
+ /**
718
+ * @description 表示オブジェクトのステージです。
719
+ * The Stage of the display object.
720
+ *
721
+ * @member {Stage}
722
+ * @readonly
723
+ * @public
724
+ */
725
+ get stage() {
726
+ if (this._$stage) {
727
+ return this._$stage;
728
+ }
729
+ // find parent
730
+ const parent = this._$parent;
731
+ if (parent) {
732
+ return parent._$stage;
733
+ }
734
+ return null;
735
+ }
736
+ /**
737
+ * @description 表示オブジェクトのマトリックス、カラー変換、
738
+ * ピクセル境界に関係するプロパティを持つオブジェクトです。
739
+ * An object with properties pertaining
740
+ * to a display object's matrix, color transform, and pixel bounds.
741
+ *
742
+ * @member {Transform}
743
+ * @public
744
+ */
745
+ get transform() {
746
+ return this._$transform;
747
+ }
748
+ set transform(transform) {
749
+ this._$transform = transform;
750
+ }
751
+ /**
752
+ * @description 表示オブジェクトが可視かどうかを示します。
753
+ * Whether or not the display object is visible.
754
+ *
755
+ * @member {boolean}
756
+ * @public
757
+ */
758
+ get visible() {
759
+ return this._$visible;
760
+ }
761
+ set visible(visible) {
762
+ if (this._$visible !== visible) {
763
+ this._$visible = !!visible;
764
+ this._$doChanged();
765
+ $doUpdated();
766
+ }
767
+ }
768
+ /**
769
+ * @description 表示オブジェクトの幅を示します(ピクセル単位)。
770
+ * Indicates the width of the display object, in pixels.
771
+ *
772
+ * @member {number}
773
+ * @public
774
+ */
775
+ get width() {
776
+ const baseBounds = "_$getBounds" in this && typeof this._$getBounds === "function"
777
+ ? this._$getBounds()
778
+ : $getBoundsObject();
779
+ const bounds = $boundsMatrix(baseBounds, this._$transform._$rawMatrix());
780
+ $poolBoundsObject(baseBounds);
781
+ const width = $Math.abs(bounds.xMax - bounds.xMin);
782
+ $poolBoundsObject(bounds);
783
+ switch (true) {
784
+ case width === 0:
785
+ case width === $Infinity:
786
+ case width === 0 - $Infinity:
787
+ return 0;
788
+ default:
789
+ return +width.toFixed(2);
790
+ }
791
+ }
792
+ set width(width) {
793
+ width = +width;
794
+ if (!$isNaN(width) && width > -1) {
795
+ const baseBounds = "_$getBounds" in this && typeof this._$getBounds === "function"
796
+ ? this._$getBounds()
797
+ : $getBoundsObject();
798
+ const rotation = this.rotation;
799
+ const bounds = rotation
800
+ ? $boundsMatrix(baseBounds, this._$transform._$rawMatrix())
801
+ : baseBounds;
802
+ if (rotation) {
803
+ $poolBoundsObject(baseBounds);
804
+ }
805
+ const exWidth = $Math.abs(bounds.xMax - bounds.xMin);
806
+ $poolBoundsObject(bounds);
807
+ switch (true) {
808
+ case exWidth === 0:
809
+ case exWidth === $Infinity:
810
+ case exWidth === -$Infinity:
811
+ this.scaleX = 0;
812
+ break;
813
+ default:
814
+ this.scaleX = width / exWidth;
815
+ break;
816
+ }
817
+ }
818
+ }
819
+ /**
820
+ * @description 親 DisplayObjectContainer のローカル座標を基準にした
821
+ * DisplayObject インスタンスの x 座標を示します。
822
+ * Indicates the x coordinate
823
+ * of the DisplayObject instance relative to the local coordinates
824
+ * of the parent DisplayObjectContainer.
825
+ *
826
+ * @member {number}
827
+ * @public
828
+ */
829
+ get x() {
830
+ return this._$transform._$rawMatrix()[4];
831
+ }
832
+ set x(x) {
833
+ const transform = this._$transform;
834
+ const matrix = transform.matrix;
835
+ matrix.tx = x;
836
+ transform.matrix = matrix;
837
+ $poolMatrix(matrix);
838
+ }
839
+ /**
840
+ * @description 親 DisplayObjectContainer のローカル座標を基準にした
841
+ * DisplayObject インスタンスの y 座標を示します。
842
+ * Indicates the y coordinate
843
+ * of the DisplayObject instance relative to the local coordinates
844
+ * of the parent DisplayObjectContainer.
845
+ *
846
+ * @member {number}
847
+ * @public
848
+ */
849
+ get y() {
850
+ return this._$transform._$rawMatrix()[5];
851
+ }
852
+ set y(y) {
853
+ const transform = this._$transform;
854
+ const matrix = transform.matrix;
855
+ matrix.ty = y;
856
+ transform.matrix = matrix;
857
+ $poolMatrix(matrix);
858
+ }
859
+ /**
860
+ * @description targetCoordinateSpace オブジェクトの座標系を基準にして、
861
+ * 表示オブジェクトの領域を定義する矩形を返します。
862
+ * Returns a rectangle that defines the area
863
+ * of the display object relative to the coordinate system
864
+ * of the targetCoordinateSpace object.
865
+ *
866
+ * @param {DisplayObject} [target=null]
867
+ * @return {Rectangle}
868
+ */
869
+ getBounds(target = null) {
870
+ const baseBounds = "_$getBounds" in this && typeof this._$getBounds === "function"
871
+ ? this._$getBounds()
872
+ : $getBoundsObject();
873
+ const matrix = this._$transform.concatenatedMatrix;
874
+ // to global
875
+ const bounds = $boundsMatrix(baseBounds, matrix._$matrix);
876
+ // pool
877
+ $poolMatrix(matrix);
878
+ $poolBoundsObject(baseBounds);
879
+ // create bounds object
880
+ const targetBaseBounds = $getBoundsObject(bounds.xMin, bounds.xMax, bounds.yMin, bounds.yMax);
881
+ // pool
882
+ $poolBoundsObject(bounds);
883
+ if (!target) {
884
+ target = this;
885
+ }
886
+ const targetMatrix = target._$transform.concatenatedMatrix;
887
+ targetMatrix.invert();
888
+ const resultBounds = $boundsMatrix(targetBaseBounds, targetMatrix._$matrix);
889
+ $poolBoundsObject(targetBaseBounds);
890
+ $poolMatrix(targetMatrix);
891
+ const xMin = resultBounds.xMin;
892
+ const yMin = resultBounds.yMin;
893
+ const xMax = resultBounds.xMax;
894
+ const yMax = resultBounds.yMax;
895
+ // pool
896
+ $poolBoundsObject(resultBounds);
897
+ return new Rectangle(xMin, yMin, $Math.abs(xMax - xMin), $Math.abs(yMax - yMin));
898
+ }
899
+ /**
900
+ * @description point オブジェクトをステージ(グローバル)座標から
901
+ * 表示オブジェクトの(ローカル)座標に変換します。
902
+ * Converts the point object from the Stage (global) coordinates
903
+ * to the display object's (local) coordinates.
904
+ *
905
+ * @param {Point} point
906
+ * @return {Point}
907
+ * @public
908
+ */
909
+ globalToLocal(point) {
910
+ const matrix = this._$transform.concatenatedMatrix;
911
+ matrix.invert();
912
+ const newPoint = new Point(point.x * matrix.a + point.y * matrix.c + matrix.tx, point.x * matrix.b + point.y * matrix.d + matrix.ty);
913
+ $poolMatrix(matrix);
914
+ return newPoint;
915
+ }
916
+ /**
917
+ * @description 表示オブジェクトの境界ボックスを評価して、
918
+ * obj 表示オブジェクトの境界ボックスと重複または交差するかどうかを調べます。
919
+ * Evaluates the bounding box of the display object to see
920
+ * if it overlaps or intersects with the bounding box of the obj display object.
921
+ *
922
+ * @param {DisplayObject} object
923
+ * @returns {boolean}
924
+ * @public
925
+ */
926
+ hitTestObject(object) {
927
+ const baseBounds1 = "_$getBounds" in this && typeof this._$getBounds === "function"
928
+ ? this._$getBounds()
929
+ : $getBoundsObject();
930
+ const matrix1 = this._$transform.concatenatedMatrix;
931
+ const bounds1 = $boundsMatrix(baseBounds1, matrix1._$matrix);
932
+ // pool
933
+ $poolMatrix(matrix1);
934
+ $poolBoundsObject(baseBounds1);
935
+ const baseBounds2 = object._$getBounds(null);
936
+ const matrix2 = object._$transform.concatenatedMatrix;
937
+ const bounds2 = $boundsMatrix(baseBounds2, matrix2._$matrix);
938
+ // pool
939
+ $poolMatrix(matrix2);
940
+ $poolBoundsObject(baseBounds2);
941
+ // calc
942
+ const sx = $Math.max(bounds1.xMin, bounds2.xMin);
943
+ const sy = $Math.max(bounds1.yMin, bounds2.yMin);
944
+ const ex = $Math.min(bounds1.xMax, bounds2.xMax);
945
+ const ey = $Math.min(bounds1.yMax, bounds2.yMax);
946
+ // pool
947
+ $poolBoundsObject(bounds1);
948
+ $poolBoundsObject(bounds2);
949
+ return ex - sx >= 0 && ey - sy >= 0;
950
+ }
951
+ /**
952
+ * @description 表示オブジェクトを評価して、x および y パラメーターで指定された
953
+ * ポイントと重複または交差するかどうかを調べます。
954
+ * Evaluates the display object to see if it overlaps
955
+ * or intersects with the point specified by the x and y parameters.
956
+ *
957
+ * @param {number} x
958
+ * @param {number} y
959
+ * @param {boolean} [shape_flag=false]
960
+ * @returns {boolean}
961
+ * @public
962
+ */
963
+ hitTestPoint(x, y, shape_flag = false) {
964
+ if (shape_flag) {
965
+ let matrix = $MATRIX_ARRAY_IDENTITY;
966
+ let parent = this._$parent;
967
+ while (parent) {
968
+ matrix = $multiplicationMatrix(parent._$transform._$rawMatrix(), matrix);
969
+ parent = parent._$parent;
970
+ }
971
+ $hitContext.setTransform(1, 0, 0, 1, 0, 0);
972
+ $hitContext.beginPath();
973
+ let result = false;
974
+ if ("_$hit" in this && typeof this._$hit === "function") {
975
+ result = this._$hit($hitContext, matrix, { "x": x, "y": y }, true);
976
+ }
977
+ if (matrix !== $MATRIX_ARRAY_IDENTITY) {
978
+ $poolFloat32Array6(matrix);
979
+ }
980
+ return result;
981
+ }
982
+ const baseBounds = "_$getBounds" in this && typeof this._$getBounds === "function"
983
+ ? this._$getBounds()
984
+ : $getBoundsObject();
985
+ const bounds = $boundsMatrix(baseBounds, this._$transform._$rawMatrix());
986
+ $poolBoundsObject(baseBounds);
987
+ const rectangle = new Rectangle(bounds.xMin, bounds.yMin, bounds.xMax - bounds.xMin, bounds.yMax - bounds.yMin);
988
+ // pool
989
+ $poolBoundsObject(bounds);
990
+ const point = this._$parent
991
+ ? this._$parent.globalToLocal(new Point(x, y))
992
+ : new Point(x, y);
993
+ return rectangle.containsPoint(point);
994
+ }
995
+ /**
996
+ * @description point オブジェクトを表示オブジェクトの(ローカル)座標から
997
+ * ステージ(グローバル)座標に変換します。
998
+ * Converts the point object from the display object's (local) coordinates
999
+ * to the Stage (global) coordinates.
1000
+ *
1001
+ *
1002
+ * @param {Point} point
1003
+ * @returns {Point}
1004
+ * @public
1005
+ */
1006
+ localToGlobal(point) {
1007
+ const matrix = this
1008
+ ._$transform
1009
+ .concatenatedMatrix;
1010
+ const newPoint = new Point(point.x * matrix.a + point.y * matrix.c + matrix.tx, point.x * matrix.b + point.y * matrix.d + matrix.ty);
1011
+ $poolMatrix(matrix);
1012
+ return newPoint;
1013
+ }
1014
+ /**
1015
+ * @description クラスのローカル変数空間から値を取得
1016
+ * Get a value from the local variable space of the class
1017
+ *
1018
+ * @param {*} key
1019
+ * @return {*}
1020
+ * @method
1021
+ * @public
1022
+ */
1023
+ getLocalVariable(key) {
1024
+ if (!this._$variables) {
1025
+ return null;
1026
+ }
1027
+ if (this._$variables.has(key)) {
1028
+ return this._$variables.get(key);
1029
+ }
1030
+ }
1031
+ /**
1032
+ * @description クラスのローカル変数空間へ値を保存
1033
+ * Store values in the local variable space of the class
1034
+ *
1035
+ * @param {*} key
1036
+ * @param {*} value
1037
+ * @return {void}
1038
+ * @method
1039
+ * @public
1040
+ */
1041
+ setLocalVariable(key, value) {
1042
+ if (!this._$variables) {
1043
+ this._$variables = $getMap();
1044
+ }
1045
+ this._$variables.set(key, value);
1046
+ }
1047
+ /**
1048
+ * @description クラスのローカル変数空間に値があるかどうかを判断します。
1049
+ * Determines if there is a value in the local variable space of the class.
1050
+ *
1051
+ * @param {*} key
1052
+ * @return {boolean}
1053
+ * @method
1054
+ * @public
1055
+ */
1056
+ hasLocalVariable(key) {
1057
+ return this._$variables
1058
+ ? this._$variables.has(key)
1059
+ : false;
1060
+ }
1061
+ /**
1062
+ * @description クラスのローカル変数空間の値を削除
1063
+ * Remove values from the local variable space of a class
1064
+ *
1065
+ * @param {*} key
1066
+ * @return {void}
1067
+ * @method
1068
+ * @public
1069
+ */
1070
+ deleteLocalVariable(key) {
1071
+ if (this._$variables && this._$variables.has(key)) {
1072
+ this._$variables.delete(key);
1073
+ if (!this._$variables.size) {
1074
+ $poolMap(this._$variables);
1075
+ this._$variables = null;
1076
+ }
1077
+ }
1078
+ }
1079
+ /**
1080
+ * @description グローバル変数空間から値を取得
1081
+ * Get a value from the global variable space
1082
+ *
1083
+ * @param {*} key
1084
+ * @return {*}
1085
+ * @method
1086
+ * @public
1087
+ */
1088
+ getGlobalVariable(key) {
1089
+ if ($variables.has(key)) {
1090
+ return $variables.get(key);
1091
+ }
1092
+ return null;
1093
+ }
1094
+ /**
1095
+ * @description グローバル変数空間へ値を保存
1096
+ * Save values to global variable space
1097
+ *
1098
+ * @param {*} key
1099
+ * @param {*} value
1100
+ * @return {void}
1101
+ * @method
1102
+ * @public
1103
+ */
1104
+ setGlobalVariable(key, value) {
1105
+ $variables.set(key, value);
1106
+ }
1107
+ /**
1108
+ * @description グローバル変数空間に値があるかどうかを判断します。
1109
+ * Determines if there is a value in the global variable space.
1110
+ *
1111
+ * @param {*} key
1112
+ * @return {boolean}
1113
+ * @method
1114
+ * @public
1115
+ */
1116
+ hasGlobalVariable(key) {
1117
+ return $variables.has(key);
1118
+ }
1119
+ /**
1120
+ * @description グローバル変数空間の値を削除
1121
+ * Remove values from global variable space.
1122
+ *
1123
+ * @param {*} key
1124
+ * @return {void}
1125
+ * @method
1126
+ * @public
1127
+ */
1128
+ deleteGlobalVariable(key) {
1129
+ if ($variables.has(key)) {
1130
+ $variables.delete(key);
1131
+ }
1132
+ }
1133
+ /**
1134
+ * @description グローバル変数空間に値を全てクリアします。
1135
+ * Clear all values in the global variable space.
1136
+ *
1137
+ * @return {void}
1138
+ * @method
1139
+ * @public
1140
+ */
1141
+ clearGlobalVariable() {
1142
+ return $variables.clear();
1143
+ }
1144
+ /**
1145
+ * @return {object}
1146
+ * @method
1147
+ * @private
1148
+ */
1149
+ _$getPlaceObject() {
1150
+ if (!this._$placeObject) {
1151
+ const placeId = this._$placeId;
1152
+ if (placeId === -1) {
1153
+ return null;
1154
+ }
1155
+ const parent = this._$parent;
1156
+ if (!parent || !parent._$placeObjects) {
1157
+ return null;
1158
+ }
1159
+ const placeMap = parent._$placeMap;
1160
+ if (!placeMap || !placeMap.length) {
1161
+ return null;
1162
+ }
1163
+ const frame = "currentFrame" in parent ? parent.currentFrame : 1;
1164
+ const places = placeMap[frame];
1165
+ if (!places) {
1166
+ return null;
1167
+ }
1168
+ const currentPlaceId = places[placeId] | 0;
1169
+ const placeObject = parent._$placeObjects[currentPlaceId];
1170
+ if (!placeObject) {
1171
+ return null;
1172
+ }
1173
+ this._$changePlace = currentPlaceId !== this._$currentPlaceId;
1174
+ this._$currentPlaceId = currentPlaceId;
1175
+ this._$placeObject = placeObject;
1176
+ return placeObject;
1177
+ }
1178
+ return this._$placeObject;
1179
+ }
1180
+ /**
1181
+ * @param {object} tag
1182
+ * @param {DisplayObjectContainer} parent
1183
+ * @return {object}
1184
+ * @method
1185
+ * @private
1186
+ */
1187
+ _$baseBuild(tag, parent) {
1188
+ const loaderInfo = parent._$loaderInfo;
1189
+ if (!loaderInfo || !loaderInfo._$data) {
1190
+ throw new Error("the loaderInfo or data is nul.");
1191
+ }
1192
+ // setup
1193
+ this._$parent = parent;
1194
+ this._$root = parent._$root;
1195
+ this._$stage = parent._$stage;
1196
+ this._$loaderInfo = loaderInfo;
1197
+ // bind tag data
1198
+ this._$characterId = tag.characterId | 0;
1199
+ this._$clipDepth = tag.clipDepth | 0;
1200
+ this._$startFrame = tag.startFrame | 0;
1201
+ this._$endFrame = tag.endFrame | 0;
1202
+ this._$name = tag.name || "";
1203
+ return loaderInfo._$data.characters[tag.characterId];
1204
+ }
1205
+ /**
1206
+ * @return {boolean}
1207
+ * @method
1208
+ * @private
1209
+ */
1210
+ _$isUpdated() {
1211
+ return this._$updated;
1212
+ }
1213
+ /**
1214
+ * @return {void}
1215
+ * @method
1216
+ * @private
1217
+ */
1218
+ _$updateState() {
1219
+ this._$isNext = true;
1220
+ const parent = this._$parent;
1221
+ if (parent) {
1222
+ parent._$updateState();
1223
+ }
1224
+ }
1225
+ /**
1226
+ * @return {void}
1227
+ * @method
1228
+ * @private
1229
+ */
1230
+ _$doChanged() {
1231
+ this._$posted = false;
1232
+ this._$isNext = true;
1233
+ this._$updated = true;
1234
+ const parent = this._$parent;
1235
+ if (parent) {
1236
+ if (!parent._$updated) {
1237
+ parent._$doChanged();
1238
+ }
1239
+ }
1240
+ }
1241
+ /**
1242
+ * @param {CanvasToWebGLContext} context
1243
+ * @param {WebGLTexture} target_texture
1244
+ * @param {Float32Array} matrix
1245
+ * @param {array} filters
1246
+ * @param {number} width
1247
+ * @param {number} height
1248
+ * @return {WebGLTexture}
1249
+ * @method
1250
+ * @private
1251
+ */
1252
+ _$drawFilter(context, target_texture, matrix, filters, width, height) {
1253
+ const player = $currentPlayer();
1254
+ const cacheStore = player.cacheStore;
1255
+ const cacheKeys = [this._$instanceId, "f"];
1256
+ const cache = cacheStore.get(cacheKeys);
1257
+ const updated = this._$isFilterUpdated(width, height, matrix, filters, true);
1258
+ if (cache && !updated) {
1259
+ return cache;
1260
+ }
1261
+ // cache clear
1262
+ if (cache) {
1263
+ cacheStore.set(cacheKeys, null);
1264
+ cache.layerWidth = 0;
1265
+ cache.layerHeight = 0;
1266
+ cache._$offsetX = 0;
1267
+ cache._$offsetY = 0;
1268
+ cache.matrix = null;
1269
+ cache.colorTransform = null;
1270
+ context
1271
+ .frameBuffer
1272
+ .releaseTexture(cache);
1273
+ }
1274
+ if (!cache || updated) {
1275
+ const texture = this._$applyFilter(context, filters, target_texture, matrix, width, height);
1276
+ cacheStore.set(cacheKeys, texture);
1277
+ return texture;
1278
+ }
1279
+ return cache;
1280
+ }
1281
+ /**
1282
+ * @param {array} [matrix=null]
1283
+ * @returns {object}
1284
+ * @private
1285
+ */
1286
+ _$getLayerBounds(matrix = null) {
1287
+ const baseBounds = "_$getBounds" in this && typeof this._$getBounds === "function"
1288
+ ? this._$getBounds(matrix)
1289
+ : $getBoundsObject();
1290
+ if (!matrix) {
1291
+ return baseBounds;
1292
+ }
1293
+ const filters = this._$filters || this.filters;
1294
+ if (!filters.length) {
1295
+ return baseBounds;
1296
+ }
1297
+ let filterBounds = $getBoundsObject(baseBounds.xMin, baseBounds.yMin, baseBounds.xMax - baseBounds.xMin, baseBounds.yMax - baseBounds.yMin);
1298
+ $poolBoundsObject(baseBounds);
1299
+ for (let idx = 0; idx < filters.length; ++idx) {
1300
+ filterBounds = filters[idx]
1301
+ ._$generateFilterRect(filterBounds, 0, 0);
1302
+ }
1303
+ const xMin = filterBounds.xMin;
1304
+ const xMax = filterBounds.xMin + filterBounds.xMax;
1305
+ const yMin = filterBounds.yMin;
1306
+ const yMax = filterBounds.yMin + filterBounds.yMax;
1307
+ $poolBoundsObject(filterBounds);
1308
+ return $getBoundsObject(xMin, xMax, yMin, yMax);
1309
+ }
1310
+ /**
1311
+ * @return {void}
1312
+ * @method
1313
+ * @private
1314
+ */
1315
+ _$executeAddedEvent() {
1316
+ if (!this._$parent) {
1317
+ return;
1318
+ }
1319
+ // add event
1320
+ if (!this._$added) {
1321
+ // added event
1322
+ if (this.willTrigger(Next2DEvent.ADDED)) {
1323
+ this.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED, true));
1324
+ }
1325
+ // update
1326
+ this._$added = true;
1327
+ }
1328
+ if (!this._$addedStage && this._$stage !== null) {
1329
+ if (this.willTrigger(Next2DEvent.ADDED_TO_STAGE)) {
1330
+ this.dispatchEvent(new Next2DEvent(Next2DEvent.ADDED_TO_STAGE));
1331
+ }
1332
+ // update
1333
+ this._$addedStage = true;
1334
+ }
1335
+ }
1336
+ /**
1337
+ * @return {void}
1338
+ * @method
1339
+ * @private
1340
+ */
1341
+ _$prepareActions() {
1342
+ this._$nextFrame();
1343
+ }
1344
+ /**
1345
+ * @return {boolean}
1346
+ * @method
1347
+ * @private
1348
+ */
1349
+ _$nextFrame() {
1350
+ // added event
1351
+ this._$executeAddedEvent();
1352
+ this._$isNext = false;
1353
+ if (!this._$posted && $rendererWorker) {
1354
+ // @ts-ignore
1355
+ this._$postProperty();
1356
+ }
1357
+ return false;
1358
+ }
1359
+ /**
1360
+ * @param {array} [filters=null]
1361
+ * @return {boolean}
1362
+ * @private
1363
+ */
1364
+ _$canApply(filters = null) {
1365
+ if (filters) {
1366
+ for (let idx = 0; idx < filters.length; ++idx) {
1367
+ if (filters[idx]._$canApply()) {
1368
+ return true;
1369
+ }
1370
+ }
1371
+ }
1372
+ return false;
1373
+ }
1374
+ /**
1375
+ * @param {number} width
1376
+ * @param {number} height
1377
+ * @param {Float32Array} matrix
1378
+ * @param {array} [filters=null]
1379
+ * @param {boolean} [can_apply=false]
1380
+ * @param {number} [position_x=0]
1381
+ * @param {number} [position_y=0]
1382
+ * @return {boolean}
1383
+ * @private
1384
+ */
1385
+ _$isFilterUpdated(width, height, matrix, filters = null, can_apply = false, position_x = 0, position_y = 0) {
1386
+ // cache flag
1387
+ if (this._$isUpdated()) {
1388
+ return true;
1389
+ }
1390
+ // check filter data
1391
+ if (can_apply && filters) {
1392
+ for (let idx = 0; idx < filters.length; ++idx) {
1393
+ if (!filters[idx]._$isUpdated()) {
1394
+ continue;
1395
+ }
1396
+ return true;
1397
+ }
1398
+ }
1399
+ // check status
1400
+ const player = $currentPlayer();
1401
+ const cache = player.cacheStore.get([this._$instanceId, "f"]);
1402
+ switch (true) {
1403
+ case cache === null:
1404
+ case cache.filterState !== can_apply:
1405
+ case cache.layerWidth !== $Math.ceil(width):
1406
+ case cache.layerHeight !== $Math.ceil(height):
1407
+ case cache.matrix !==
1408
+ matrix[0] + "_" + matrix[1] + "_" + matrix[2] + "_" + matrix[3] + "_" +
1409
+ position_x + "_" + position_y:
1410
+ return true;
1411
+ default:
1412
+ break;
1413
+ }
1414
+ return false;
1415
+ }
1416
+ /**
1417
+ * @param {CanvasToWebGLContext} context
1418
+ * @param {array} filters
1419
+ * @param {WebGLTexture} target_texture
1420
+ * @param {Float32Array} matrix
1421
+ * @param {number} width
1422
+ * @param {number} height
1423
+ * @return {WebGLTexture}
1424
+ * @private
1425
+ */
1426
+ _$applyFilter(context, filters, target_texture, matrix, width, height) {
1427
+ const xScale = +$Math.sqrt(matrix[0] * matrix[0]
1428
+ + matrix[1] * matrix[1]);
1429
+ const yScale = +$Math.sqrt(matrix[2] * matrix[2]
1430
+ + matrix[3] * matrix[3]);
1431
+ const radianX = $Math.atan2(matrix[1], matrix[0]);
1432
+ const radianY = $Math.atan2(-matrix[2], matrix[3]);
1433
+ const parentMatrix = $getFloat32Array6($Math.cos(radianX), $Math.sin(radianX), -$Math.sin(radianY), $Math.cos(radianY), width / 2, height / 2);
1434
+ const baseMatrix = $getFloat32Array6(1, 0, 0, 1, -target_texture.width / 2, -target_texture.height / 2);
1435
+ const multiMatrix = $multiplicationMatrix(parentMatrix, baseMatrix);
1436
+ $poolFloat32Array6(parentMatrix);
1437
+ $poolFloat32Array6(baseMatrix);
1438
+ const manager = context.frameBuffer;
1439
+ const currentAttachment = manager.currentAttachment;
1440
+ const attachment = manager
1441
+ .createCacheAttachment(width, height);
1442
+ context._$bind(attachment);
1443
+ context.reset();
1444
+ context.setTransform(multiMatrix[0], multiMatrix[1], multiMatrix[2], multiMatrix[3], multiMatrix[4], multiMatrix[5]);
1445
+ $poolFloat32Array6(multiMatrix);
1446
+ context.drawImage(target_texture, 0, 0, target_texture.width, target_texture.height);
1447
+ // init
1448
+ context._$offsetX = 0;
1449
+ context._$offsetY = 0;
1450
+ const filterMatrix = $getFloat32Array6(xScale, 0, 0, yScale, 0, 0);
1451
+ let texture = null;
1452
+ for (let idx = 0; idx < filters.length; ++idx) {
1453
+ texture = filters[idx]._$applyFilter(context, filterMatrix);
1454
+ }
1455
+ $poolFloat32Array6(filterMatrix);
1456
+ if (!texture) {
1457
+ return target_texture;
1458
+ }
1459
+ const offsetX = context._$offsetX;
1460
+ const offsetY = context._$offsetY;
1461
+ // reset
1462
+ context._$offsetX = 0;
1463
+ context._$offsetY = 0;
1464
+ // set offset
1465
+ texture._$offsetX = offsetX;
1466
+ texture._$offsetY = offsetY;
1467
+ // cache texture
1468
+ texture.matrix =
1469
+ matrix[0] + "_" + matrix[1] + "_"
1470
+ + matrix[2] + "_" + matrix[3];
1471
+ texture.filterState = true;
1472
+ texture.layerWidth = width;
1473
+ texture.layerHeight = height;
1474
+ context._$bind(currentAttachment);
1475
+ manager.releaseAttachment(attachment, false);
1476
+ return texture;
1477
+ }
1478
+ /**
1479
+ * @param {Float32Array} matrix
1480
+ * @return {boolean}
1481
+ * @method
1482
+ * @private
1483
+ */
1484
+ _$shouldClip(matrix) {
1485
+ const bounds = "_$getBounds" in this && typeof this._$getBounds === "function"
1486
+ ? this._$getBounds(matrix)
1487
+ : $getBoundsObject();
1488
+ const width = $Math.abs(bounds.xMax - bounds.xMin);
1489
+ const height = $Math.abs(bounds.yMax - bounds.yMin);
1490
+ $poolBoundsObject(bounds);
1491
+ // size 0
1492
+ return !(!width || !height);
1493
+ }
1494
+ /**
1495
+ * @param {CanvasToWebGLContext} context
1496
+ * @param {Float32Array} matrix
1497
+ * @return {Float32Array|boolean|null}
1498
+ * @method
1499
+ * @private
1500
+ */
1501
+ _$startClip(context, matrix) {
1502
+ let clipMatrix = null;
1503
+ // ネストしてない初回のマスクだけ実行
1504
+ // ネストしてる場合は初回に作られたbufferを流用
1505
+ if (!context.cacheAttachment) {
1506
+ let multiMatrix = matrix;
1507
+ const rawMatrix = this._$transform._$rawMatrix();
1508
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
1509
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
1510
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
1511
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1512
+ }
1513
+ const baseBounds = "_$getBounds" in this && typeof this._$getBounds === "function"
1514
+ ? this._$getBounds()
1515
+ : $getBoundsObject();
1516
+ const bounds = $boundsMatrix(baseBounds, multiMatrix);
1517
+ $poolBoundsObject(baseBounds);
1518
+ clipMatrix = context._$startClip(matrix, bounds);
1519
+ $poolBoundsObject(bounds);
1520
+ if (multiMatrix !== matrix) {
1521
+ $poolFloat32Array6(multiMatrix);
1522
+ }
1523
+ if (!clipMatrix) {
1524
+ return false;
1525
+ }
1526
+ }
1527
+ // start clip
1528
+ context._$enterClip();
1529
+ // mask start
1530
+ context._$beginClipDef();
1531
+ let containerClip = false;
1532
+ if ("_$children" in this) {
1533
+ containerClip = true;
1534
+ context._$updateContainerClipFlag(true);
1535
+ }
1536
+ // @ts-ignore
1537
+ this._$clip(context, clipMatrix || matrix);
1538
+ this._$updated = false;
1539
+ // container clip
1540
+ if (containerClip) {
1541
+ // update flag
1542
+ context._$updateContainerClipFlag(false);
1543
+ // execute clip
1544
+ context._$drawContainerClip();
1545
+ }
1546
+ // mask end
1547
+ context._$endClipDef();
1548
+ return clipMatrix;
1549
+ }
1550
+ /**
1551
+ * @return {void}
1552
+ * @method
1553
+ * @private
1554
+ */
1555
+ _$removeWorkerInstance() {
1556
+ if ($rendererWorker) {
1557
+ $rendererWorker.postMessage({
1558
+ "command": "remove",
1559
+ "instanceId": this._$instanceId
1560
+ });
1561
+ }
1562
+ }
1563
+ /**
1564
+ * @return {object}
1565
+ * @method
1566
+ * @private
1567
+ */
1568
+ _$createMessage() {
1569
+ const message = {
1570
+ "command": "setProperty",
1571
+ "instanceId": this._$instanceId,
1572
+ "parentId": this._$parent ? this._$parent._$instanceId : -1,
1573
+ "visible": this._$visible
1574
+ };
1575
+ if (this._$placeId > -1) {
1576
+ message.depth = this._$placeId;
1577
+ }
1578
+ if (this._$clipDepth) {
1579
+ message.clipDepth = this._$clipDepth;
1580
+ }
1581
+ if (this._$isMask) {
1582
+ message.isMask = this._$isMask;
1583
+ }
1584
+ const mask = this._$mask;
1585
+ if (mask) {
1586
+ message.maskId = mask._$instanceId;
1587
+ let maskMatrix = $MATRIX_ARRAY_IDENTITY;
1588
+ let parent = mask._$parent;
1589
+ while (parent) {
1590
+ maskMatrix = $multiplicationMatrix(parent._$transform._$rawMatrix(), maskMatrix);
1591
+ parent = parent._$parent;
1592
+ }
1593
+ message.maskMatrix = maskMatrix;
1594
+ }
1595
+ if (this._$visible) {
1596
+ const transform = this._$transform;
1597
+ const matrix = transform._$rawMatrix();
1598
+ if (matrix[0] !== 1) {
1599
+ message.a = matrix[0];
1600
+ }
1601
+ if (matrix[1] !== 0) {
1602
+ message.b = matrix[1];
1603
+ }
1604
+ if (matrix[2] !== 0) {
1605
+ message.c = matrix[2];
1606
+ }
1607
+ if (matrix[3] !== 1) {
1608
+ message.d = matrix[3];
1609
+ }
1610
+ if (matrix[4] !== 0) {
1611
+ message.tx = matrix[4];
1612
+ }
1613
+ if (matrix[5] !== 0) {
1614
+ message.ty = matrix[5];
1615
+ }
1616
+ const colorTransform = transform._$rawColorTransform();
1617
+ if (colorTransform[0] !== 1) {
1618
+ message.f0 = colorTransform[0];
1619
+ }
1620
+ if (colorTransform[1] !== 1) {
1621
+ message.f1 = colorTransform[1];
1622
+ }
1623
+ if (colorTransform[2] !== 1) {
1624
+ message.f2 = colorTransform[2];
1625
+ }
1626
+ if (colorTransform[3] !== 1) {
1627
+ message.f3 = colorTransform[3];
1628
+ }
1629
+ if (colorTransform[4] !== 0) {
1630
+ message.f4 = colorTransform[4];
1631
+ }
1632
+ if (colorTransform[5] !== 0) {
1633
+ message.f5 = colorTransform[5];
1634
+ }
1635
+ if (colorTransform[6] !== 0) {
1636
+ message.f6 = colorTransform[6];
1637
+ }
1638
+ if (colorTransform[7] !== 0) {
1639
+ message.f7 = colorTransform[7];
1640
+ }
1641
+ const filters = this._$filters || this.filters;
1642
+ if (filters && filters.length) {
1643
+ const parameters = $getArray();
1644
+ for (let idx = 0; idx < filters.length; ++idx) {
1645
+ parameters.push(filters[idx]._$toArray());
1646
+ }
1647
+ message.filters = parameters;
1648
+ }
1649
+ const blendMode = this._$blendMode || this.blendMode;
1650
+ if (blendMode !== "normal") {
1651
+ message.blendMode = blendMode;
1652
+ }
1653
+ const scale9Grid = this._$scale9Grid;
1654
+ if (scale9Grid && this._$isUpdated()) {
1655
+ const baseMatrix = this
1656
+ ._$parent
1657
+ ._$transform
1658
+ .concatenatedMatrix;
1659
+ message.matrixBase = baseMatrix._$matrix.slice();
1660
+ $poolMatrix(baseMatrix);
1661
+ message.grid = {
1662
+ "x": scale9Grid.x,
1663
+ "y": scale9Grid.y,
1664
+ "w": scale9Grid.width,
1665
+ "h": scale9Grid.height
1666
+ };
1667
+ }
1668
+ }
1669
+ return message;
1670
+ }
1671
+ }