@next2d/display 2.13.1 → 3.0.1

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.
Files changed (27) hide show
  1. package/README.md +372 -5
  2. package/package.json +9 -9
  3. package/src/BitmapData.d.ts +1 -1
  4. package/src/BitmapData.js +1 -16
  5. package/src/DisplayObject/service/DisplayObjectApplyChangesService.js +4 -3
  6. package/src/DisplayObject/service/DisplayObjectGenerateHashService.js +57 -11
  7. package/src/DisplayObject.js +2 -1
  8. package/src/DisplayObjectContainer/usecase/DisplayObjectContainerGenerateRenderQueueUseCase.js +147 -4
  9. package/src/DisplayObjectContainer/usecase/DisplayObjectContainerGetLayerBoundsUseCase.d.ts +14 -0
  10. package/src/DisplayObjectContainer/usecase/DisplayObjectContainerGetLayerBoundsUseCase.js +65 -0
  11. package/src/Graphics/service/GraphicsToNumberArrayService.js +25 -1
  12. package/src/Shape/usecase/ShapeCalcLayerBoundsUseCase.d.ts +12 -0
  13. package/src/Shape/usecase/ShapeCalcLayerBoundsUseCase.js +32 -0
  14. package/src/Shape/usecase/ShapeGenerateRenderQueueUseCase.js +28 -16
  15. package/src/Shape/usecase/ShapeLoadAsyncUseCase.d.ts +12 -0
  16. package/src/Shape/usecase/ShapeLoadAsyncUseCase.js +21 -0
  17. package/src/Shape.d.ts +10 -0
  18. package/src/Shape.js +13 -0
  19. package/src/Sprite.d.ts +2 -5
  20. package/src/Sprite.js +2 -5
  21. package/src/Stage.js +3 -0
  22. package/src/TextField/usecase/TextFieldCalcLayerBoundsUseCase.d.ts +12 -0
  23. package/src/TextField/usecase/TextFieldCalcLayerBoundsUseCase.js +32 -0
  24. package/src/TextField/usecase/TextFieldGenerateRenderQueueUseCase.js +23 -12
  25. package/src/Video/usecase/VideoCalcLayerBoundsUseCase.d.ts +12 -0
  26. package/src/Video/usecase/VideoCalcLayerBoundsUseCase.js +32 -0
  27. package/src/Video/usecase/VideoGenerateRenderQueueUseCase.js +12 -1
@@ -6,8 +6,12 @@ import { execute as textFieldGenerateRenderQueueUseCase } from "../../TextField/
6
6
  import { execute as videoGenerateRenderQueueUseCase } from "../../Video/usecase/VideoGenerateRenderQueueUseCase";
7
7
  import { execute as displayObjectIsMaskReflectedInDisplayUseCase } from "../../DisplayObject/usecase/DisplayObjectIsMaskReflectedInDisplayUseCase";
8
8
  import { execute as displayObjectContainerGenerateClipQueueUseCase } from "../../DisplayObjectContainer/usecase/DisplayObjectContainerGenerateClipQueueUseCase";
9
+ import { execute as displayObjectBlendToNumberService } from "../../DisplayObject/service/DisplayObjectBlendToNumberService";
10
+ import { execute as displayObjectContainerGetLayerBoundsUseCase } from "./DisplayObjectContainerGetLayerBoundsUseCase";
11
+ import { execute as displayObjectContainerCalcBoundsMatrixUseCase } from "../../DisplayObjectContainer/usecase/DisplayObjectContainerCalcBoundsMatrixUseCase";
9
12
  import { renderQueue } from "@next2d/render-queue";
10
- import { $clamp, $RENDERER_CONTAINER_TYPE } from "../../DisplayObjectUtil";
13
+ import { $cacheStore } from "@next2d/cache";
14
+ import { $clamp, $getBoundsArray, $poolBoundsArray, $RENDERER_CONTAINER_TYPE, $getFloat32Array8, $getFloat32Array6 } from "../../DisplayObjectUtil";
11
15
  import { ColorTransform, Matrix } from "@next2d/geom";
12
16
  /**
13
17
  * @description renderer workerに渡すコンテナの描画データを生成
@@ -30,7 +34,11 @@ export const execute = (display_object_container, image_bitmaps, matrix, color_t
30
34
  }
31
35
  // transformed ColorTransform(tColorTransform)
32
36
  const rawColor = displayObjectGetRawColorTransformUseCase(display_object_container);
33
- const tColorTransform = rawColor
37
+ let tColorTransform = rawColor
38
+ && (rawColor[0] !== 1 || rawColor[1] !== 1
39
+ || rawColor[2] !== 1 || rawColor[3] !== 1
40
+ || rawColor[4] !== 0 || rawColor[5] !== 0
41
+ || rawColor[6] !== 0 || rawColor[7] !== 0)
34
42
  ? ColorTransform.multiply(color_transform, rawColor)
35
43
  : color_transform;
36
44
  const alpha = $clamp(tColorTransform[3] + tColorTransform[7] / 255, 0, 1, 0);
@@ -51,7 +59,10 @@ export const execute = (display_object_container, image_bitmaps, matrix, color_t
51
59
  }
52
60
  // transformed matrix(tMatrix)
53
61
  const rawMatrix = displayObjectGetRawMatrixUseCase(display_object_container);
54
- const tMatrix = rawMatrix
62
+ let tMatrix = rawMatrix
63
+ && (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
64
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
65
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0)
55
66
  ? Matrix.multiply(matrix, rawMatrix)
56
67
  : matrix;
57
68
  // size zero
@@ -67,6 +78,133 @@ export const execute = (display_object_container, image_bitmaps, matrix, color_t
67
78
  return;
68
79
  }
69
80
  renderQueue.push(1, $RENDERER_CONTAINER_TYPE);
81
+ // blendMode
82
+ const blendMode = display_object_container.blendMode;
83
+ renderQueue.push(displayObjectBlendToNumberService(blendMode));
84
+ // filters
85
+ const filters = display_object_container.filters;
86
+ if (filters) {
87
+ const filterKey = $cacheStore.generateFilterKeys(tMatrix[0], tMatrix[1], tMatrix[2], tMatrix[3]);
88
+ const filterCache = $cacheStore.get(`${display_object_container.instanceId}`, `${filterKey}`);
89
+ let updated = false;
90
+ const params = [];
91
+ const bounds = $getBoundsArray(0, 0, 0, 0);
92
+ for (let idx = 0; idx < filters.length; idx++) {
93
+ const filter = filters[idx];
94
+ if (!filter || !filter.canApplyFilter()) {
95
+ continue;
96
+ }
97
+ // フィルターが更新されたかをチェック
98
+ if (filter.$updated) {
99
+ updated = true;
100
+ }
101
+ filter.$updated = false;
102
+ filter.getBounds(bounds);
103
+ const buffer = filter.toNumberArray();
104
+ for (let idx = 0; idx < buffer.length; idx += 4096) {
105
+ params.push(...buffer.subarray(idx, idx + 4096));
106
+ }
107
+ }
108
+ const useFilfer = params.length > 0;
109
+ if (useFilfer) {
110
+ // 子の変更があった場合は親のフラグが立っているので更新
111
+ if (!updated) {
112
+ updated = display_object_container.changed;
113
+ }
114
+ const layerBounds = displayObjectContainerGetLayerBoundsUseCase(display_object_container, matrix);
115
+ if (filterCache) {
116
+ // キャッシュがあって、変更がなければキャッシュを使用
117
+ if (!updated) {
118
+ renderQueue.push(1, Math.ceil(Math.abs(layerBounds[2] - layerBounds[0])), Math.ceil(Math.abs(layerBounds[3] - layerBounds[1])), 1, 1, display_object_container.instanceId, filterKey, bounds[0], bounds[1], bounds[2], bounds[3], tMatrix[0], tMatrix[1], tMatrix[2], tMatrix[3], layerBounds[0], layerBounds[1], tColorTransform[0], tColorTransform[1], tColorTransform[2], tColorTransform[3], tColorTransform[4], tColorTransform[5], tColorTransform[6], tColorTransform[7]);
119
+ $poolBoundsArray(layerBounds);
120
+ $poolBoundsArray(bounds);
121
+ if (tColorTransform !== color_transform) {
122
+ ColorTransform.release(tColorTransform);
123
+ }
124
+ if (tMatrix !== matrix) {
125
+ Matrix.release(tMatrix);
126
+ }
127
+ return;
128
+ }
129
+ // どこかで変更があったので、キャッシュを削除
130
+ $cacheStore.removeById(`${display_object_container.instanceId}`);
131
+ }
132
+ renderQueue.push(1, Math.ceil(Math.abs(layerBounds[2] - layerBounds[0])), Math.ceil(Math.abs(layerBounds[3] - layerBounds[1])), 1, 0, display_object_container.instanceId, filterKey, bounds[0], bounds[1], bounds[2], bounds[3], tMatrix[0], tMatrix[1], tMatrix[2], tMatrix[3], layerBounds[0], layerBounds[1], tColorTransform[0], tColorTransform[1], tColorTransform[2], tColorTransform[3], tColorTransform[4], tColorTransform[5], tColorTransform[6], tColorTransform[7], params.length);
133
+ renderQueue.set(new Float32Array(params));
134
+ const fa0 = tMatrix[0];
135
+ const fa1 = tMatrix[1];
136
+ const fa2 = tMatrix[2];
137
+ const fa3 = tMatrix[3];
138
+ const faTx = tMatrix[4] - layerBounds[0];
139
+ const faTy = tMatrix[5] - layerBounds[1];
140
+ if (tMatrix !== matrix) {
141
+ Matrix.release(tMatrix);
142
+ }
143
+ tMatrix = $getFloat32Array6(fa0, fa1, fa2, fa3, faTx, faTy);
144
+ if (tColorTransform !== color_transform) {
145
+ ColorTransform.release(tColorTransform);
146
+ }
147
+ tColorTransform = $getFloat32Array8(1, 1, 1, 1, 0, 0, 0, 0);
148
+ $poolBoundsArray(layerBounds);
149
+ $cacheStore.set(`${display_object_container.instanceId}`, `${filterKey}`, true);
150
+ }
151
+ else {
152
+ if (blendMode === "normal") {
153
+ renderQueue.push(0);
154
+ }
155
+ else {
156
+ // ブレンドモードのみのLayerモード
157
+ const layerBounds = displayObjectContainerCalcBoundsMatrixUseCase(display_object_container, matrix);
158
+ const layerXMin = layerBounds[0];
159
+ const layerYMin = layerBounds[1];
160
+ renderQueue.push(1, Math.ceil(Math.abs(layerBounds[2] - layerXMin)), Math.ceil(Math.abs(layerBounds[3] - layerYMin)), 0, // not use filter,
161
+ tMatrix[0], tMatrix[1], tMatrix[2], tMatrix[3], layerXMin, layerYMin, tColorTransform[0], tColorTransform[1], tColorTransform[2], tColorTransform[3], tColorTransform[4], tColorTransform[5], tColorTransform[6], tColorTransform[7]);
162
+ const a0 = tMatrix[0];
163
+ const a1 = tMatrix[1];
164
+ const a2 = tMatrix[2];
165
+ const a3 = tMatrix[3];
166
+ const adjustedTx1 = tMatrix[4] - layerXMin;
167
+ const adjustedTy1 = tMatrix[5] - layerYMin;
168
+ if (tMatrix !== matrix) {
169
+ Matrix.release(tMatrix);
170
+ }
171
+ tMatrix = $getFloat32Array6(a0, a1, a2, a3, adjustedTx1, adjustedTy1);
172
+ $poolBoundsArray(layerBounds);
173
+ if (tColorTransform !== color_transform) {
174
+ ColorTransform.release(tColorTransform);
175
+ }
176
+ tColorTransform = $getFloat32Array8(1, 1, 1, 1, 0, 0, 0, 0);
177
+ }
178
+ }
179
+ $poolBoundsArray(bounds);
180
+ }
181
+ else {
182
+ if (blendMode === "normal") {
183
+ renderQueue.push(0);
184
+ }
185
+ else {
186
+ const layerBounds = displayObjectContainerCalcBoundsMatrixUseCase(display_object_container, matrix);
187
+ const layerXMin2 = layerBounds[0];
188
+ const layerYMin2 = layerBounds[1];
189
+ renderQueue.push(1, Math.ceil(Math.abs(layerBounds[2] - layerXMin2)), Math.ceil(Math.abs(layerBounds[3] - layerYMin2)), 0, // not use filter,
190
+ tMatrix[0], tMatrix[1], tMatrix[2], tMatrix[3], layerXMin2, layerYMin2, tColorTransform[0], tColorTransform[1], tColorTransform[2], tColorTransform[3], tColorTransform[4], tColorTransform[5], tColorTransform[6], tColorTransform[7]);
191
+ const b0 = tMatrix[0];
192
+ const b1 = tMatrix[1];
193
+ const b2 = tMatrix[2];
194
+ const b3 = tMatrix[3];
195
+ const adjustedTx2 = tMatrix[4] - layerXMin2;
196
+ const adjustedTy2 = tMatrix[5] - layerYMin2;
197
+ if (tMatrix !== matrix) {
198
+ Matrix.release(tMatrix);
199
+ }
200
+ tMatrix = $getFloat32Array6(b0, b1, b2, b3, adjustedTx2, adjustedTy2);
201
+ $poolBoundsArray(layerBounds);
202
+ if (tColorTransform !== color_transform) {
203
+ ColorTransform.release(tColorTransform);
204
+ }
205
+ tColorTransform = $getFloat32Array8(1, 1, 1, 1, 0, 0, 0, 0);
206
+ }
207
+ }
70
208
  // mask
71
209
  const maskDisplayObject = display_object_container.mask;
72
210
  if (maskDisplayObject) {
@@ -93,20 +231,25 @@ export const execute = (display_object_container, image_bitmaps, matrix, color_t
93
231
  else {
94
232
  renderQueue.push(0);
95
233
  }
234
+ // children
96
235
  renderQueue.push(children.length);
97
236
  let clipDepth = 0;
98
237
  let canRenderMask = true;
99
238
  for (let idx = 0; idx < children.length; ++idx) {
100
239
  const child = children[idx];
240
+ renderQueue.push(child.placeId, child.clipDepth);
241
+ // マスクオブジェクトは描画しない(hidden=0)
101
242
  if (child.isMask) {
243
+ renderQueue.push(0);
244
+ child.changed = false;
102
245
  continue;
103
246
  }
104
- renderQueue.push(child.placeId, child.clipDepth);
105
247
  if (clipDepth && child.placeId > clipDepth) {
106
248
  clipDepth = 0;
107
249
  canRenderMask = true;
108
250
  }
109
251
  if (!canRenderMask) {
252
+ renderQueue.push(0);
110
253
  child.changed = false;
111
254
  continue;
112
255
  }
@@ -0,0 +1,14 @@
1
+ import type { DisplayObjectContainer } from "../../DisplayObjectContainer";
2
+ /**
3
+ * @description DisplayObjectContainerのレイヤー境界を取得します。
4
+ * 子孫のフィルター適用後のboundsを考慮した境界を返却します。
5
+ * Get the layer bounds of DisplayObjectContainer.
6
+ * Returns bounds considering filter-expanded bounds of descendants.
7
+ *
8
+ * @param {DisplayObjectContainer} display_object_container
9
+ * @param {Float32Array | null} matrix
10
+ * @return {Float32Array}
11
+ * @method
12
+ * @public
13
+ */
14
+ export declare const execute: <P extends DisplayObjectContainer>(display_object_container: P, matrix?: Float32Array | null) => Float32Array;
@@ -0,0 +1,65 @@
1
+ import { Matrix } from "@next2d/geom";
2
+ import { execute as displayObjectGetRawMatrixUseCase } from "../../DisplayObject/usecase/DisplayObjectGetRawMatrixUseCase";
3
+ import { execute as shapeCalcLayerBoundsUseCase } from "../../Shape/usecase/ShapeCalcLayerBoundsUseCase";
4
+ import { execute as videoCalcLayerBoundsUseCase } from "../../Video/usecase/VideoCalcLayerBoundsUseCase";
5
+ import { execute as textFieldCalcLayerBoundsUseCase } from "../../TextField/usecase/TextFieldCalcLayerBoundsUseCase";
6
+ import { $getBoundsArray, $poolBoundsArray } from "../../DisplayObjectUtil";
7
+ /**
8
+ * @description DisplayObjectContainerのレイヤー境界を取得します。
9
+ * 子孫のフィルター適用後のboundsを考慮した境界を返却します。
10
+ * Get the layer bounds of DisplayObjectContainer.
11
+ * Returns bounds considering filter-expanded bounds of descendants.
12
+ *
13
+ * @param {DisplayObjectContainer} display_object_container
14
+ * @param {Float32Array | null} matrix
15
+ * @return {Float32Array}
16
+ * @method
17
+ * @public
18
+ */
19
+ export const execute = (display_object_container, matrix = null) => {
20
+ const children = display_object_container.children;
21
+ if (!children.length) {
22
+ return $getBoundsArray(0, 0, 0, 0);
23
+ }
24
+ const rawMatrix = displayObjectGetRawMatrixUseCase(display_object_container);
25
+ const tMatrix = rawMatrix
26
+ ? matrix
27
+ ? Matrix.multiply(matrix, rawMatrix)
28
+ : rawMatrix
29
+ : matrix;
30
+ const no = Number.MAX_VALUE;
31
+ let xMin = no;
32
+ let xMax = -no;
33
+ let yMin = no;
34
+ let yMax = -no;
35
+ for (let idx = 0; idx < children.length; idx++) {
36
+ const child = children[idx];
37
+ if (!child || !child.visible) {
38
+ continue;
39
+ }
40
+ let bounds = null;
41
+ switch (true) {
42
+ case child.isContainerEnabled:
43
+ bounds = execute(child, tMatrix);
44
+ break;
45
+ case child.isShape:
46
+ bounds = shapeCalcLayerBoundsUseCase(child, tMatrix);
47
+ break;
48
+ case child.isText:
49
+ bounds = textFieldCalcLayerBoundsUseCase(child, tMatrix);
50
+ break;
51
+ case child.isVideo:
52
+ bounds = videoCalcLayerBoundsUseCase(child, tMatrix);
53
+ break;
54
+ }
55
+ if (!bounds) {
56
+ continue;
57
+ }
58
+ xMin = Math.min(xMin, bounds[0]);
59
+ yMin = Math.min(yMin, bounds[1]);
60
+ xMax = Math.max(xMax, bounds[2]);
61
+ yMax = Math.max(yMax, bounds[3]);
62
+ $poolBoundsArray(bounds);
63
+ }
64
+ return $getBoundsArray(xMin, yMin, xMax, yMax);
65
+ };
@@ -48,6 +48,10 @@ export const execute = (recodes) => {
48
48
  case "square":
49
49
  array.push(2);
50
50
  break;
51
+ default:
52
+ // 無効な値の場合はデフォルトで"none"(0)を使用
53
+ array.push(0);
54
+ break;
51
55
  }
52
56
  const lineJoin = recodes[idx++];
53
57
  switch (lineJoin) {
@@ -60,6 +64,10 @@ export const execute = (recodes) => {
60
64
  case "round":
61
65
  array.push(2);
62
66
  break;
67
+ default:
68
+ // 無効な値の場合はデフォルトで"round"(2)を使用
69
+ array.push(2);
70
+ break;
63
71
  }
64
72
  array.push(recodes[idx++], // MITER LIMIT
65
73
  recodes[idx++], recodes[idx++], recodes[idx++], recodes[idx++]);
@@ -114,6 +122,10 @@ export const execute = (recodes) => {
114
122
  case "square":
115
123
  array.push(2);
116
124
  break;
125
+ default:
126
+ // 無効な値の場合はデフォルトで"none"(0)を使用
127
+ array.push(0);
128
+ break;
117
129
  }
118
130
  const lineJoin = recodes[idx++];
119
131
  switch (lineJoin) {
@@ -126,6 +138,10 @@ export const execute = (recodes) => {
126
138
  case "round":
127
139
  array.push(2);
128
140
  break;
141
+ default:
142
+ // 無効な値の場合はデフォルトで"round"(2)を使用
143
+ array.push(2);
144
+ break;
129
145
  }
130
146
  // miterLimit
131
147
  array.push(recodes[idx++]);
@@ -196,6 +212,10 @@ export const execute = (recodes) => {
196
212
  case "square":
197
213
  array.push(2);
198
214
  break;
215
+ default:
216
+ // 無効な値の場合はデフォルトで"none"(0)を使用
217
+ array.push(0);
218
+ break;
199
219
  }
200
220
  const lineJoin = recodes[idx++];
201
221
  switch (lineJoin) {
@@ -208,6 +228,10 @@ export const execute = (recodes) => {
208
228
  case "round":
209
229
  array.push(2);
210
230
  break;
231
+ default:
232
+ // 無効な値の場合はデフォルトで"round"(2)を使用
233
+ array.push(2);
234
+ break;
211
235
  }
212
236
  // MITER LIMIT
213
237
  array.push(recodes[idx++]);
@@ -223,7 +247,7 @@ export const execute = (recodes) => {
223
247
  }
224
248
  const matrix = recodes[idx++];
225
249
  if (matrix) {
226
- array.push(...matrix);
250
+ array.push(...matrix.rawData);
227
251
  }
228
252
  else {
229
253
  array.push(1, 0, 0, 1, 0, 0);
@@ -0,0 +1,12 @@
1
+ import type { Shape } from "../../Shape";
2
+ /**
3
+ * @description Shapeのフィルター適用後の描画範囲を計算します。
4
+ * Calculate the drawing area of Shape after applying filters.
5
+ *
6
+ * @param {Shape} shape
7
+ * @param {Float32Array | null} [matrix=null]
8
+ * @return {Float32Array}
9
+ * @method
10
+ * @protected
11
+ */
12
+ export declare const execute: (shape: Shape, matrix?: Float32Array | null) => Float32Array;
@@ -0,0 +1,32 @@
1
+ import { execute as shapeCalcBoundsMatrixUseCase } from "./ShapeCalcBoundsMatrixUseCase";
2
+ import { $getBoundsArray, $poolBoundsArray } from "../../DisplayObjectUtil";
3
+ /**
4
+ * @description Shapeのフィルター適用後の描画範囲を計算します。
5
+ * Calculate the drawing area of Shape after applying filters.
6
+ *
7
+ * @param {Shape} shape
8
+ * @param {Float32Array | null} [matrix=null]
9
+ * @return {Float32Array}
10
+ * @method
11
+ * @protected
12
+ */
13
+ export const execute = (shape, matrix = null) => {
14
+ const bounds = shapeCalcBoundsMatrixUseCase(shape, matrix);
15
+ const filters = shape.filters;
16
+ if (filters) {
17
+ const filterBounds = $getBoundsArray(0, 0, 0, 0);
18
+ for (let idx = 0; idx < filters.length; idx++) {
19
+ const filter = filters[idx];
20
+ if (!filter || !filter.canApplyFilter()) {
21
+ continue;
22
+ }
23
+ filter.getBounds(filterBounds);
24
+ }
25
+ bounds[0] += filterBounds[0];
26
+ bounds[1] += filterBounds[1];
27
+ bounds[2] += filterBounds[2];
28
+ bounds[3] += filterBounds[3];
29
+ $poolBoundsArray(filterBounds);
30
+ }
31
+ return bounds;
32
+ };
@@ -35,6 +35,10 @@ export const execute = (shape, matrix, color_transform, renderer_width, renderer
35
35
  // transformed ColorTransform(tColorTransform)
36
36
  const rawColor = displayObjectGetRawColorTransformUseCase(shape);
37
37
  const tColorTransform = rawColor
38
+ && (rawColor[0] !== 1 || rawColor[1] !== 1
39
+ || rawColor[2] !== 1 || rawColor[3] !== 1
40
+ || rawColor[4] !== 0 || rawColor[5] !== 0
41
+ || rawColor[6] !== 0 || rawColor[7] !== 0)
38
42
  ? ColorTransform.multiply(color_transform, rawColor)
39
43
  : color_transform;
40
44
  const alpha = $clamp(tColorTransform[3] + tColorTransform[7] / 255, 0, 1, 0);
@@ -48,6 +52,9 @@ export const execute = (shape, matrix, color_transform, renderer_width, renderer
48
52
  // transformed matrix(tMatrix)
49
53
  const rawMatrix = displayObjectGetRawMatrixUseCase(shape);
50
54
  const tMatrix = rawMatrix
55
+ && (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
56
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
57
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0)
51
58
  ? Matrix.multiply(matrix, rawMatrix)
52
59
  : matrix;
53
60
  const bounds = displayObjectCalcBoundsMatrixService(graphics.xMin, graphics.yMin, graphics.xMax, graphics.yMax, tMatrix);
@@ -71,7 +78,6 @@ export const execute = (shape, matrix, color_transform, renderer_width, renderer
71
78
  if (tMatrix !== matrix) {
72
79
  Matrix.release(tMatrix);
73
80
  }
74
- $poolBoundsArray(bounds);
75
81
  renderQueue.push(0);
76
82
  return;
77
83
  default:
@@ -87,7 +93,6 @@ export const execute = (shape, matrix, color_transform, renderer_width, renderer
87
93
  if (tMatrix !== matrix) {
88
94
  Matrix.release(tMatrix);
89
95
  }
90
- $poolBoundsArray(bounds);
91
96
  renderQueue.push(0);
92
97
  return;
93
98
  }
@@ -102,29 +107,32 @@ export const execute = (shape, matrix, color_transform, renderer_width, renderer
102
107
  }
103
108
  else {
104
109
  shape.uniqueKey = shape.isBitmap
105
- ? `${shape.instanceId}`
110
+ ? `${displayObjectGenerateHashService(new Float32Array(shape.$bitmapBuffer.buffer))}`
106
111
  : `${displayObjectGenerateHashService(graphics.buffer)}`;
107
112
  }
108
113
  }
109
- const xScale = Math.round(Math.sqrt(tMatrix[0] * tMatrix[0]
110
- + tMatrix[1] * tMatrix[1]) * 100) / 100;
111
- const yScale = Math.round(Math.sqrt(tMatrix[2] * tMatrix[2]
112
- + tMatrix[3] * tMatrix[3]) * 100) / 100;
114
+ const xScale = Math.sqrt(tMatrix[0] * tMatrix[0]
115
+ + tMatrix[1] * tMatrix[1]);
116
+ const yScale = Math.sqrt(tMatrix[2] * tMatrix[2]
117
+ + tMatrix[3] * tMatrix[3]);
118
+ const xScaleRounded = Math.round(xScale * 100) / 100;
119
+ const yScaleRounded = Math.round(yScale * 100) / 100;
113
120
  if (!shape.isBitmap
114
121
  && !shape.cacheKey
115
- || shape.cacheParams[0] !== xScale
116
- || shape.cacheParams[1] !== yScale
122
+ || shape.cacheParams[0] !== xScaleRounded
123
+ || shape.cacheParams[1] !== yScaleRounded
117
124
  || shape.cacheParams[2] !== tColorTransform[7]) {
118
- shape.cacheKey = $cacheStore.generateKeys(xScale, yScale, tColorTransform[7]);
119
- shape.cacheParams[0] = xScale;
120
- shape.cacheParams[1] = yScale;
125
+ shape.cacheKey = $cacheStore.generateKeys(xScaleRounded, yScaleRounded, tColorTransform[7]);
126
+ shape.cacheParams[0] = xScaleRounded;
127
+ shape.cacheParams[1] = yScaleRounded;
121
128
  shape.cacheParams[2] = tColorTransform[7];
122
129
  }
123
130
  const cacheKey = shape.isBitmap
124
131
  ? 0
125
132
  : shape.cacheKey;
126
133
  // rennder on
127
- renderQueue.push(1, $RENDERER_SHAPE_TYPE, tMatrix[0], tMatrix[1], tMatrix[2], tMatrix[3], tMatrix[4], tMatrix[5], tColorTransform[0], tColorTransform[1], tColorTransform[2], tColorTransform[3], tColorTransform[4], tColorTransform[5], tColorTransform[6], tColorTransform[7], xMin, yMin, xMax, yMax, graphics.xMin, graphics.yMin, graphics.xMax, graphics.yMax, +isGridEnabled, +isDrawable, +shape.isBitmap, +shape.uniqueKey, cacheKey);
134
+ renderQueue.pushShapeBuffer(1, $RENDERER_SHAPE_TYPE, tMatrix[0], tMatrix[1], tMatrix[2], tMatrix[3], tMatrix[4], tMatrix[5], tColorTransform[0], tColorTransform[1], tColorTransform[2], tColorTransform[3], tColorTransform[4], tColorTransform[5], tColorTransform[6], tColorTransform[7], xMin, yMin, xMax, yMax, graphics.xMin, graphics.yMin, graphics.xMax, graphics.yMax, +isGridEnabled, +isDrawable, +shape.isBitmap, +shape.uniqueKey, cacheKey, xScale, yScale, shape.instanceId // フィルターキャッシュ用のユニークキー
135
+ );
128
136
  if (shape.$cache && !shape.$cache.has(shape.uniqueKey)) {
129
137
  shape.$cache = null;
130
138
  }
@@ -200,12 +208,13 @@ export const execute = (shape, matrix, color_transform, renderer_width, renderer
200
208
  renderQueue.push(1);
201
209
  }
202
210
  renderQueue.push(displayObjectBlendToNumberService(shape.blendMode));
203
- if (shape.filters?.length) {
211
+ const filters = shape.filters;
212
+ if (filters) {
204
213
  let updated = false;
205
214
  const params = [];
206
215
  const bounds = $getBoundsArray(0, 0, 0, 0);
207
- for (let idx = 0; idx < shape.filters.length; idx++) {
208
- const filter = shape.filters[idx];
216
+ for (let idx = 0; idx < filters.length; idx++) {
217
+ const filter = filters[idx];
209
218
  if (!filter || !filter.canApplyFilter()) {
210
219
  continue;
211
220
  }
@@ -225,6 +234,9 @@ export const execute = (shape, matrix, color_transform, renderer_width, renderer
225
234
  renderQueue.push(+useFilfer, +updated, bounds[0], bounds[1], bounds[2], bounds[3], params.length);
226
235
  renderQueue.set(new Float32Array(params));
227
236
  }
237
+ else {
238
+ renderQueue.push(0);
239
+ }
228
240
  $poolBoundsArray(bounds);
229
241
  }
230
242
  else {
@@ -0,0 +1,12 @@
1
+ import type { Shape } from "../../Shape";
2
+ /**
3
+ * @description 形状読み込みユースケース
4
+ * Shape Load Use Case
5
+ *
6
+ * @param {Shape} shape
7
+ * @param {string} url
8
+ * @return {Promise<void>}
9
+ * @method
10
+ * @public
11
+ */
12
+ export declare const execute: (shape: Shape, url: string) => Promise<void>;
@@ -0,0 +1,21 @@
1
+ import { Event } from "@next2d/events";
2
+ /**
3
+ * @description 形状読み込みユースケース
4
+ * Shape Load Use Case
5
+ *
6
+ * @param {Shape} shape
7
+ * @param {string} url
8
+ * @return {Promise<void>}
9
+ * @method
10
+ * @public
11
+ */
12
+ export const execute = (shape, url) => {
13
+ return new Promise((resolve) => {
14
+ const onComplete = () => {
15
+ shape.removeEventListener(Event.COMPLETE, onComplete);
16
+ resolve();
17
+ };
18
+ shape.addEventListener(Event.COMPLETE, onComplete);
19
+ shape.src = url;
20
+ });
21
+ };
package/src/Shape.d.ts CHANGED
@@ -110,6 +110,16 @@ export declare class Shape extends DisplayObject {
110
110
  */
111
111
  get src(): string;
112
112
  set src(src: string);
113
+ /**
114
+ * @description 指定されたURLから画像を非同期で読み込み、Graphicsを生成します
115
+ * Asynchronously loads images from the specified URL and generates Graphics.
116
+ *
117
+ * @param {string} url
118
+ * @return {Promise<void>}
119
+ * @method
120
+ * @public
121
+ */
122
+ load(url: string): Promise<void>;
113
123
  /**
114
124
  * @description ビットマップデータを返します
115
125
  * Returns the bitmap data.
package/src/Shape.js CHANGED
@@ -5,6 +5,7 @@ import { execute as shapeClearBitmapBufferService } from "./Shape/usecase/ShapeC
5
5
  import { execute as shapeSetBitmapBufferUseCase } from "./Shape/usecase/ShapeSetBitmapBufferUseCase";
6
6
  import { execute as shapeLoadSrcUseCase } from "./Shape/usecase/ShapeLoadSrcUseCase";
7
7
  import { execute as shapeBuildFromCharacterUseCase } from "./Shape/usecase/ShapeBuildFromCharacterUseCase";
8
+ import { execute as shapeLoadAsyncUseCase } from "./Shape/usecase/ShapeLoadAsyncUseCase";
8
9
  import { $graphicMap, $getArray } from "./DisplayObjectUtil";
9
10
  /**
10
11
  * @description Shape クラスは、ベクターグラフィックスを表示するための表示オブジェクトです。
@@ -177,6 +178,18 @@ export class Shape extends DisplayObject {
177
178
  this._$src = src;
178
179
  shapeLoadSrcUseCase(this, src);
179
180
  }
181
+ /**
182
+ * @description 指定されたURLから画像を非同期で読み込み、Graphicsを生成します
183
+ * Asynchronously loads images from the specified URL and generates Graphics.
184
+ *
185
+ * @param {string} url
186
+ * @return {Promise<void>}
187
+ * @method
188
+ * @public
189
+ */
190
+ load(url) {
191
+ return shapeLoadAsyncUseCase(this, url);
192
+ }
180
193
  /**
181
194
  * @description ビットマップデータを返します
182
195
  * Returns the bitmap data.
package/src/Sprite.d.ts CHANGED
@@ -3,11 +3,8 @@ import type { Rectangle } from "@next2d/geom";
3
3
  import type { SoundTransform } from "@next2d/media";
4
4
  import { DisplayObjectContainer } from "./DisplayObjectContainer";
5
5
  /**
6
- * @description Sprite クラスは、表示リストの基本的要素です。
7
- * グラフィックを表示でき、子を持つこともできる表示リストノードです。
8
- *
9
- * The Sprite class is a basic display list building block:
10
- * a display list node that can display graphics and can also contain children.
6
+ * @description Sprite クラスは、表示リストの基本的要素です。子を持つこともできる表示リストノードです。
7
+ * The Sprite class is the basic display list building block: a display list node that can
11
8
  *
12
9
  * @class
13
10
  * @memberOf next2d.display
package/src/Sprite.js CHANGED
@@ -2,11 +2,8 @@ import { DisplayObjectContainer } from "./DisplayObjectContainer";
2
2
  import { execute as spriteStartDragService } from "./Sprite/service/SpriteStartDragService";
3
3
  import { execute as spriteStopDragService } from "./Sprite/service/SpriteStopDragService";
4
4
  /**
5
- * @description Sprite クラスは、表示リストの基本的要素です。
6
- * グラフィックを表示でき、子を持つこともできる表示リストノードです。
7
- *
8
- * The Sprite class is a basic display list building block:
9
- * a display list node that can display graphics and can also contain children.
5
+ * @description Sprite クラスは、表示リストの基本的要素です。子を持つこともできる表示リストノードです。
6
+ * The Sprite class is the basic display list building block: a display list node that can
10
7
  *
11
8
  * @class
12
9
  * @memberOf next2d.display
package/src/Stage.js CHANGED
@@ -190,8 +190,11 @@ export class Stage extends DisplayObjectContainer {
190
190
  */
191
191
  addChild(display_object) {
192
192
  $stageAssignedMap.add(display_object.instanceId);
193
+ // fixed logic
194
+ $rootMap.set(this, display_object);
193
195
  super.addChild(display_object);
194
196
  // fixed logic for root map
197
+ $rootMap.delete(this);
195
198
  $rootMap.set(display_object, display_object);
196
199
  return display_object;
197
200
  }
@@ -0,0 +1,12 @@
1
+ import type { TextField } from "@next2d/text";
2
+ /**
3
+ * @description TextFieldのフィルター適用後の描画範囲を計算します。
4
+ * Calculate the drawing area of TextField after applying filters.
5
+ *
6
+ * @param {TextField} text_field
7
+ * @param {Float32Array | null} [matrix=null]
8
+ * @return {Float32Array}
9
+ * @method
10
+ * @protected
11
+ */
12
+ export declare const execute: (text_field: TextField, matrix?: Float32Array | null) => Float32Array;