@babylonjs/gui 9.14.0 → 9.16.0

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 (106) hide show
  1. package/2D/advancedDynamicTexture.d.ts +2 -2
  2. package/2D/advancedDynamicTexture.js +2 -2
  3. package/2D/advancedDynamicTexture.js.map +1 -1
  4. package/2D/controls/checkbox.pure.js +164 -153
  5. package/2D/controls/checkbox.pure.js.map +1 -1
  6. package/2D/controls/colorpicker.pure.js +1300 -1289
  7. package/2D/controls/colorpicker.pure.js.map +1 -1
  8. package/2D/controls/container.pure.js +597 -582
  9. package/2D/controls/container.pure.js.map +1 -1
  10. package/2D/controls/control.pure.js +2474 -2434
  11. package/2D/controls/control.pure.js.map +1 -1
  12. package/2D/controls/displayGrid.pure.js +201 -190
  13. package/2D/controls/displayGrid.pure.js.map +1 -1
  14. package/2D/controls/ellipse.pure.js +96 -85
  15. package/2D/controls/ellipse.pure.js.map +1 -1
  16. package/2D/controls/grid.pure.js +511 -500
  17. package/2D/controls/grid.pure.js.map +1 -1
  18. package/2D/controls/image.pure.js +888 -877
  19. package/2D/controls/image.pure.js.map +1 -1
  20. package/2D/controls/inputText.pure.js +988 -973
  21. package/2D/controls/inputText.pure.js.map +1 -1
  22. package/2D/controls/inputTextArea.pure.js +955 -944
  23. package/2D/controls/inputTextArea.pure.js.map +1 -1
  24. package/2D/controls/line.pure.js +237 -226
  25. package/2D/controls/line.pure.js.map +1 -1
  26. package/2D/controls/multiLine.pure.js +233 -222
  27. package/2D/controls/multiLine.pure.js.map +1 -1
  28. package/2D/controls/radioButton.pure.js +182 -169
  29. package/2D/controls/radioButton.pure.js.map +1 -1
  30. package/2D/controls/rectangle.pure.js +211 -200
  31. package/2D/controls/rectangle.pure.js.map +1 -1
  32. package/2D/controls/scrollViewers/scrollViewer.pure.js +579 -567
  33. package/2D/controls/scrollViewers/scrollViewer.pure.js.map +1 -1
  34. package/2D/controls/scrollViewers/scrollViewerWindow.d.ts +1 -1
  35. package/2D/controls/scrollViewers/scrollViewerWindow.js +2 -2
  36. package/2D/controls/scrollViewers/scrollViewerWindow.js.map +1 -1
  37. package/2D/controls/selector.d.ts +2 -2
  38. package/2D/controls/selector.js +8 -8
  39. package/2D/controls/selector.js.map +1 -1
  40. package/2D/controls/sliders/baseSlider.d.ts +1 -1
  41. package/2D/controls/sliders/baseSlider.js +292 -281
  42. package/2D/controls/sliders/baseSlider.js.map +1 -1
  43. package/2D/controls/sliders/imageBasedSlider.pure.js +158 -147
  44. package/2D/controls/sliders/imageBasedSlider.pure.js.map +1 -1
  45. package/2D/controls/sliders/imageScrollBar.js +237 -223
  46. package/2D/controls/sliders/imageScrollBar.js.map +1 -1
  47. package/2D/controls/sliders/scrollBar.pure.js +169 -158
  48. package/2D/controls/sliders/scrollBar.pure.js.map +1 -1
  49. package/2D/controls/sliders/slider.pure.js +251 -240
  50. package/2D/controls/sliders/slider.pure.js.map +1 -1
  51. package/2D/controls/stackPanel.pure.js +236 -221
  52. package/2D/controls/stackPanel.pure.js.map +1 -1
  53. package/2D/controls/textBlock.pure.js +637 -626
  54. package/2D/controls/textBlock.pure.js.map +1 -1
  55. package/2D/math2D.d.ts +1 -1
  56. package/2D/math2D.js +1 -1
  57. package/2D/math2D.js.map +1 -1
  58. package/2D/measure.js +1 -1
  59. package/2D/measure.js.map +1 -1
  60. package/3D/controls/MRTK3/touchHolographicButton.d.ts +4 -4
  61. package/3D/controls/MRTK3/touchHolographicButton.js +10 -10
  62. package/3D/controls/MRTK3/touchHolographicButton.js.map +1 -1
  63. package/3D/controls/holographicBackplate.d.ts +1 -1
  64. package/3D/controls/holographicBackplate.js +1 -1
  65. package/3D/controls/holographicBackplate.js.map +1 -1
  66. package/3D/controls/holographicButton.d.ts +1 -1
  67. package/3D/controls/holographicButton.js +4 -4
  68. package/3D/controls/holographicButton.js.map +1 -1
  69. package/3D/controls/holographicSlate.js +4 -4
  70. package/3D/controls/holographicSlate.js.map +1 -1
  71. package/3D/controls/slider3D.d.ts +3 -3
  72. package/3D/controls/slider3D.js +3 -3
  73. package/3D/controls/slider3D.js.map +1 -1
  74. package/3D/controls/touchHolographicButton.d.ts +2 -2
  75. package/3D/controls/touchHolographicButton.js +5 -5
  76. package/3D/controls/touchHolographicButton.js.map +1 -1
  77. package/3D/controls/touchHolographicMenu.js +1 -1
  78. package/3D/controls/touchHolographicMenu.js.map +1 -1
  79. package/3D/gizmos/gizmoHandle.d.ts +1 -1
  80. package/3D/gizmos/gizmoHandle.js +1 -1
  81. package/3D/gizmos/gizmoHandle.js.map +1 -1
  82. package/3D/materials/fluent/fluentMaterial.pure.d.ts +4 -4
  83. package/3D/materials/fluent/fluentMaterial.pure.js +322 -270
  84. package/3D/materials/fluent/fluentMaterial.pure.js.map +1 -1
  85. package/3D/materials/fluentBackplate/fluentBackplateMaterial.pure.js +510 -451
  86. package/3D/materials/fluentBackplate/fluentBackplateMaterial.pure.js.map +1 -1
  87. package/3D/materials/fluentButton/fluentButtonMaterial.pure.js +612 -526
  88. package/3D/materials/fluentButton/fluentButtonMaterial.pure.js.map +1 -1
  89. package/3D/materials/fluentMaterial.d.ts +1 -1
  90. package/3D/materials/fluentMaterial.js +1 -1
  91. package/3D/materials/fluentMaterial.js.map +1 -1
  92. package/3D/materials/handle/handleMaterial.pure.js +3 -1
  93. package/3D/materials/handle/handleMaterial.pure.js.map +1 -1
  94. package/3D/materials/mrdl/mrdlBackglowMaterial.pure.js +313 -271
  95. package/3D/materials/mrdl/mrdlBackglowMaterial.pure.js.map +1 -1
  96. package/3D/materials/mrdl/mrdlBackplateMaterial.pure.js +462 -402
  97. package/3D/materials/mrdl/mrdlBackplateMaterial.pure.js.map +1 -1
  98. package/3D/materials/mrdl/mrdlFrontplateMaterial.pure.js +583 -498
  99. package/3D/materials/mrdl/mrdlFrontplateMaterial.pure.js.map +1 -1
  100. package/3D/materials/mrdl/mrdlInnerquadMaterial.pure.js +226 -200
  101. package/3D/materials/mrdl/mrdlInnerquadMaterial.pure.js.map +1 -1
  102. package/3D/materials/mrdl/mrdlSliderBarMaterial.pure.js +961 -822
  103. package/3D/materials/mrdl/mrdlSliderBarMaterial.pure.js.map +1 -1
  104. package/3D/materials/mrdl/mrdlSliderThumbMaterial.pure.js +961 -822
  105. package/3D/materials/mrdl/mrdlSliderThumbMaterial.pure.js.map +1 -1
  106. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { __decorate } from "@babylonjs/core/tslib.es6.js";
1
+ import { __esDecorate, __runInitializers } from "@babylonjs/core/tslib.es6.js";
2
2
  import { Observable } from "@babylonjs/core/Misc/observable.js";
3
3
  import { Tools } from "@babylonjs/core/Misc/tools.pure.js";
4
4
  import { Control } from "./control.pure.js";
@@ -8,910 +8,921 @@ import { EngineStore } from "@babylonjs/core/Engines/engineStore.js";
8
8
  /**
9
9
  * Class used to create 2D images
10
10
  */
11
- export class Image extends Control {
12
- /**
13
- * Gets a boolean indicating that the content is loaded
14
- */
15
- get isLoaded() {
16
- return this._loaded;
17
- }
18
- isReady() {
19
- return this.isLoaded;
20
- }
21
- /**
22
- * Gets or sets a boolean indicating if pointers should only be validated on pixels with alpha > 0.
23
- * Beware using this as this will consume more memory as the image has to be stored twice
24
- */
25
- get detectPointerOnOpaqueOnly() {
26
- return this._detectPointerOnOpaqueOnly;
27
- }
28
- set detectPointerOnOpaqueOnly(value) {
29
- if (this._detectPointerOnOpaqueOnly === value) {
30
- return;
31
- }
32
- this._detectPointerOnOpaqueOnly = value;
33
- }
34
- /**
35
- * Gets or sets the left value for slicing (9-patch)
36
- */
37
- get sliceLeft() {
38
- return this._sliceLeft;
39
- }
40
- set sliceLeft(value) {
41
- if (this._sliceLeft === value) {
42
- return;
43
- }
44
- this._sliceLeft = value;
45
- this._markAsDirty();
46
- }
47
- /**
48
- * Gets or sets the right value for slicing (9-patch)
49
- */
50
- get sliceRight() {
51
- return this._sliceRight;
52
- }
53
- set sliceRight(value) {
54
- if (this._sliceRight === value) {
55
- return;
56
- }
57
- this._sliceRight = value;
58
- this._markAsDirty();
59
- }
60
- /**
61
- * Gets or sets the top value for slicing (9-patch)
62
- */
63
- get sliceTop() {
64
- return this._sliceTop;
65
- }
66
- set sliceTop(value) {
67
- if (this._sliceTop === value) {
68
- return;
69
- }
70
- this._sliceTop = value;
71
- this._markAsDirty();
72
- }
73
- /**
74
- * Gets or sets the bottom value for slicing (9-patch)
75
- */
76
- get sliceBottom() {
77
- return this._sliceBottom;
78
- }
79
- set sliceBottom(value) {
80
- if (this._sliceBottom === value) {
81
- return;
82
- }
83
- this._sliceBottom = value;
84
- this._markAsDirty();
85
- }
86
- /**
87
- * Gets or sets the left coordinate in the source image
88
- */
89
- get sourceLeft() {
90
- return this._sourceLeft;
91
- }
92
- set sourceLeft(value) {
93
- if (this._sourceLeft === value) {
94
- return;
95
- }
96
- this._sourceLeft = value;
97
- this._markAsDirty();
98
- }
99
- /**
100
- * Gets or sets the top coordinate in the source image
101
- */
102
- get sourceTop() {
103
- return this._sourceTop;
104
- }
105
- set sourceTop(value) {
106
- if (this._sourceTop === value) {
107
- return;
108
- }
109
- this._sourceTop = value;
110
- this._markAsDirty();
111
- }
112
- /**
113
- * Gets or sets the width to capture in the source image
114
- */
115
- get sourceWidth() {
116
- return this._sourceWidth;
117
- }
118
- set sourceWidth(value) {
119
- if (this._sourceWidth === value) {
120
- return;
121
- }
122
- this._sourceWidth = value;
123
- this._markAsDirty();
124
- }
125
- /**
126
- * Gets or sets the height to capture in the source image
127
- */
128
- get sourceHeight() {
129
- return this._sourceHeight;
130
- }
131
- set sourceHeight(value) {
132
- if (this._sourceHeight === value) {
133
- return;
134
- }
135
- this._sourceHeight = value;
136
- this._markAsDirty();
137
- }
138
- /**
139
- * Gets the image width
140
- */
141
- get imageWidth() {
142
- return this._imageWidth;
143
- }
144
- /**
145
- * Gets the image height
146
- */
147
- get imageHeight() {
148
- return this._imageHeight;
149
- }
150
- /**
151
- * Gets or sets a boolean indicating if nine patch slices (left, top, right, bottom) should be read from image data
152
- */
153
- get populateNinePatchSlicesFromImage() {
154
- return this._populateNinePatchSlicesFromImage;
155
- }
156
- set populateNinePatchSlicesFromImage(value) {
157
- if (this._populateNinePatchSlicesFromImage === value) {
158
- return;
159
- }
160
- this._populateNinePatchSlicesFromImage = value;
161
- if (this._populateNinePatchSlicesFromImage && this._loaded) {
162
- this._extractNinePatchSliceDataFromImage();
163
- }
164
- }
165
- /** Indicates if the format of the image is SVG */
166
- get isSVG() {
167
- return this._isSVG;
168
- }
169
- /** Gets the status of the SVG attributes computation (sourceLeft, sourceTop, sourceWidth, sourceHeight) */
170
- get svgAttributesComputationCompleted() {
171
- return this._svgAttributesComputationCompleted;
172
- }
173
- /**
174
- * Gets or sets a boolean indicating if the image can force its container to adapt its size
175
- * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#image
176
- */
177
- get autoScale() {
178
- return this._autoScale;
179
- }
180
- set autoScale(value) {
181
- if (this._autoScale === value) {
182
- return;
183
- }
184
- this._autoScale = value;
185
- if (value && this._loaded) {
186
- this.synchronizeSizeWithContent();
187
- }
188
- }
189
- /** Gets or sets the stretching mode used by the image */
190
- get stretch() {
191
- return this._stretch;
192
- }
193
- set stretch(value) {
194
- if (this._stretch === value) {
195
- return;
196
- }
197
- this._stretch = value;
198
- this._markAsDirty();
199
- }
200
- /**
201
- * @internal
202
- */
203
- _rotate90(n, preserveProperties = false) {
204
- const width = this._domImage.width;
205
- const height = this._domImage.height;
206
- // Should abstract platform instead of using LastCreatedEngine
207
- const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;
208
- if (!engine) {
209
- throw new Error("Invalid engine. Unable to create a canvas.");
210
- }
211
- const canvas = engine.createCanvas(height, width);
212
- const context = canvas.getContext("2d");
213
- context.translate(canvas.width / 2, canvas.height / 2);
214
- context.rotate((n * Math.PI) / 2);
215
- context.drawImage(this._domImage, 0, 0, width, height, -width / 2, -height / 2, width, height);
216
- const dataUrl = canvas.toDataURL("image/jpg");
217
- const rotatedImage = new Image(this.name + "rotated", dataUrl);
218
- if (preserveProperties) {
219
- rotatedImage._stretch = this._stretch;
220
- rotatedImage._autoScale = this._autoScale;
221
- rotatedImage._cellId = this._cellId;
222
- rotatedImage._cellWidth = n % 1 ? this._cellHeight : this._cellWidth;
223
- rotatedImage._cellHeight = n % 1 ? this._cellWidth : this._cellHeight;
224
- }
225
- this._handleRotationForSVGImage(this, rotatedImage, n);
226
- this._imageDataCache.data = null;
227
- return rotatedImage;
228
- }
229
- _handleRotationForSVGImage(srcImage, dstImage, n) {
230
- if (!srcImage._isSVG) {
231
- return;
232
- }
233
- if (srcImage._svgAttributesComputationCompleted) {
234
- this._rotate90SourceProperties(srcImage, dstImage, n);
235
- this._markAsDirty();
236
- }
237
- else {
238
- srcImage.onSVGAttributesComputedObservable.addOnce(() => {
239
- this._rotate90SourceProperties(srcImage, dstImage, n);
11
+ let Image = (() => {
12
+ var _a;
13
+ let _classSuper = Control;
14
+ let _instanceExtraInitializers = [];
15
+ let _get_detectPointerOnOpaqueOnly_decorators;
16
+ let _get_sliceLeft_decorators;
17
+ let _get_sliceRight_decorators;
18
+ let _get_sliceTop_decorators;
19
+ let _get_sliceBottom_decorators;
20
+ let _get_sourceLeft_decorators;
21
+ let _get_sourceTop_decorators;
22
+ let _get_sourceWidth_decorators;
23
+ let _get_sourceHeight_decorators;
24
+ let _get_populateNinePatchSlicesFromImage_decorators;
25
+ let _get_autoScale_decorators;
26
+ let _get_stretch_decorators;
27
+ let _get_source_decorators;
28
+ let _get_cellWidth_decorators;
29
+ let _get_cellHeight_decorators;
30
+ let _get_cellId_decorators;
31
+ return _a = class Image extends _classSuper {
32
+ /**
33
+ * Gets a boolean indicating that the content is loaded
34
+ */
35
+ get isLoaded() {
36
+ return this._loaded;
37
+ }
38
+ isReady() {
39
+ return this.isLoaded;
40
+ }
41
+ /**
42
+ * Gets or sets a boolean indicating if pointers should only be validated on pixels with alpha > 0.
43
+ * Beware using this as this will consume more memory as the image has to be stored twice
44
+ */
45
+ get detectPointerOnOpaqueOnly() {
46
+ return this._detectPointerOnOpaqueOnly;
47
+ }
48
+ set detectPointerOnOpaqueOnly(value) {
49
+ if (this._detectPointerOnOpaqueOnly === value) {
50
+ return;
51
+ }
52
+ this._detectPointerOnOpaqueOnly = value;
53
+ }
54
+ /**
55
+ * Gets or sets the left value for slicing (9-patch)
56
+ */
57
+ get sliceLeft() {
58
+ return this._sliceLeft;
59
+ }
60
+ set sliceLeft(value) {
61
+ if (this._sliceLeft === value) {
62
+ return;
63
+ }
64
+ this._sliceLeft = value;
240
65
  this._markAsDirty();
241
- });
242
- }
243
- }
244
- _rotate90SourceProperties(srcImage, dstImage, n) {
245
- let srcLeft = srcImage.sourceLeft, srcTop = srcImage.sourceTop, srcWidth = srcImage.domImage.width, srcHeight = srcImage.domImage.height;
246
- let dstLeft = srcLeft, dstTop = srcTop, dstWidth = srcImage.sourceWidth, dstHeight = srcImage.sourceHeight;
247
- if (n != 0) {
248
- const mult = n < 0 ? -1 : 1;
249
- n = n % 4;
250
- for (let i = 0; i < Math.abs(n); ++i) {
251
- dstLeft = -(srcTop - srcHeight / 2) * mult + srcHeight / 2;
252
- dstTop = (srcLeft - srcWidth / 2) * mult + srcWidth / 2;
253
- [dstWidth, dstHeight] = [dstHeight, dstWidth];
254
- if (n < 0) {
255
- dstTop -= dstHeight;
66
+ }
67
+ /**
68
+ * Gets or sets the right value for slicing (9-patch)
69
+ */
70
+ get sliceRight() {
71
+ return this._sliceRight;
72
+ }
73
+ set sliceRight(value) {
74
+ if (this._sliceRight === value) {
75
+ return;
76
+ }
77
+ this._sliceRight = value;
78
+ this._markAsDirty();
79
+ }
80
+ /**
81
+ * Gets or sets the top value for slicing (9-patch)
82
+ */
83
+ get sliceTop() {
84
+ return this._sliceTop;
85
+ }
86
+ set sliceTop(value) {
87
+ if (this._sliceTop === value) {
88
+ return;
89
+ }
90
+ this._sliceTop = value;
91
+ this._markAsDirty();
92
+ }
93
+ /**
94
+ * Gets or sets the bottom value for slicing (9-patch)
95
+ */
96
+ get sliceBottom() {
97
+ return this._sliceBottom;
98
+ }
99
+ set sliceBottom(value) {
100
+ if (this._sliceBottom === value) {
101
+ return;
102
+ }
103
+ this._sliceBottom = value;
104
+ this._markAsDirty();
105
+ }
106
+ /**
107
+ * Gets or sets the left coordinate in the source image
108
+ */
109
+ get sourceLeft() {
110
+ return this._sourceLeft;
111
+ }
112
+ set sourceLeft(value) {
113
+ if (this._sourceLeft === value) {
114
+ return;
115
+ }
116
+ this._sourceLeft = value;
117
+ this._markAsDirty();
118
+ }
119
+ /**
120
+ * Gets or sets the top coordinate in the source image
121
+ */
122
+ get sourceTop() {
123
+ return this._sourceTop;
124
+ }
125
+ set sourceTop(value) {
126
+ if (this._sourceTop === value) {
127
+ return;
128
+ }
129
+ this._sourceTop = value;
130
+ this._markAsDirty();
131
+ }
132
+ /**
133
+ * Gets or sets the width to capture in the source image
134
+ */
135
+ get sourceWidth() {
136
+ return this._sourceWidth;
137
+ }
138
+ set sourceWidth(value) {
139
+ if (this._sourceWidth === value) {
140
+ return;
141
+ }
142
+ this._sourceWidth = value;
143
+ this._markAsDirty();
144
+ }
145
+ /**
146
+ * Gets or sets the height to capture in the source image
147
+ */
148
+ get sourceHeight() {
149
+ return this._sourceHeight;
150
+ }
151
+ set sourceHeight(value) {
152
+ if (this._sourceHeight === value) {
153
+ return;
154
+ }
155
+ this._sourceHeight = value;
156
+ this._markAsDirty();
157
+ }
158
+ /**
159
+ * Gets the image width
160
+ */
161
+ get imageWidth() {
162
+ return this._imageWidth;
163
+ }
164
+ /**
165
+ * Gets the image height
166
+ */
167
+ get imageHeight() {
168
+ return this._imageHeight;
169
+ }
170
+ /**
171
+ * Gets or sets a boolean indicating if nine patch slices (left, top, right, bottom) should be read from image data
172
+ */
173
+ get populateNinePatchSlicesFromImage() {
174
+ return this._populateNinePatchSlicesFromImage;
175
+ }
176
+ set populateNinePatchSlicesFromImage(value) {
177
+ if (this._populateNinePatchSlicesFromImage === value) {
178
+ return;
179
+ }
180
+ this._populateNinePatchSlicesFromImage = value;
181
+ if (this._populateNinePatchSlicesFromImage && this._loaded) {
182
+ this._extractNinePatchSliceDataFromImage();
183
+ }
184
+ }
185
+ /** Indicates if the format of the image is SVG */
186
+ get isSVG() {
187
+ return this._isSVG;
188
+ }
189
+ /** Gets the status of the SVG attributes computation (sourceLeft, sourceTop, sourceWidth, sourceHeight) */
190
+ get svgAttributesComputationCompleted() {
191
+ return this._svgAttributesComputationCompleted;
192
+ }
193
+ /**
194
+ * Gets or sets a boolean indicating if the image can force its container to adapt its size
195
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#image
196
+ */
197
+ get autoScale() {
198
+ return this._autoScale;
199
+ }
200
+ set autoScale(value) {
201
+ if (this._autoScale === value) {
202
+ return;
203
+ }
204
+ this._autoScale = value;
205
+ if (value && this._loaded) {
206
+ this.synchronizeSizeWithContent();
207
+ }
208
+ }
209
+ /** Gets or sets the stretching mode used by the image */
210
+ get stretch() {
211
+ return this._stretch;
212
+ }
213
+ set stretch(value) {
214
+ if (this._stretch === value) {
215
+ return;
216
+ }
217
+ this._stretch = value;
218
+ this._markAsDirty();
219
+ }
220
+ /**
221
+ * @internal
222
+ */
223
+ _rotate90(n, preserveProperties = false) {
224
+ const width = this._domImage.width;
225
+ const height = this._domImage.height;
226
+ // Should abstract platform instead of using LastCreatedEngine
227
+ const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;
228
+ if (!engine) {
229
+ throw new Error("Invalid engine. Unable to create a canvas.");
230
+ }
231
+ const canvas = engine.createCanvas(height, width);
232
+ const context = canvas.getContext("2d");
233
+ context.translate(canvas.width / 2, canvas.height / 2);
234
+ context.rotate((n * Math.PI) / 2);
235
+ context.drawImage(this._domImage, 0, 0, width, height, -width / 2, -height / 2, width, height);
236
+ const dataUrl = canvas.toDataURL("image/jpg");
237
+ const rotatedImage = new _a(this.name + "rotated", dataUrl);
238
+ if (preserveProperties) {
239
+ rotatedImage._stretch = this._stretch;
240
+ rotatedImage._autoScale = this._autoScale;
241
+ rotatedImage._cellId = this._cellId;
242
+ rotatedImage._cellWidth = n % 1 ? this._cellHeight : this._cellWidth;
243
+ rotatedImage._cellHeight = n % 1 ? this._cellWidth : this._cellHeight;
244
+ }
245
+ this._handleRotationForSVGImage(this, rotatedImage, n);
246
+ this._imageDataCache.data = null;
247
+ return rotatedImage;
248
+ }
249
+ _handleRotationForSVGImage(srcImage, dstImage, n) {
250
+ if (!srcImage._isSVG) {
251
+ return;
252
+ }
253
+ if (srcImage._svgAttributesComputationCompleted) {
254
+ this._rotate90SourceProperties(srcImage, dstImage, n);
255
+ this._markAsDirty();
256
256
  }
257
257
  else {
258
- dstLeft -= dstWidth;
258
+ srcImage.onSVGAttributesComputedObservable.addOnce(() => {
259
+ this._rotate90SourceProperties(srcImage, dstImage, n);
260
+ this._markAsDirty();
261
+ });
259
262
  }
260
- srcLeft = dstLeft;
261
- srcTop = dstTop;
262
- [srcWidth, srcHeight] = [srcHeight, srcWidth];
263
263
  }
264
- }
265
- dstImage.sourceLeft = dstLeft;
266
- dstImage.sourceTop = dstTop;
267
- dstImage.sourceWidth = dstWidth;
268
- dstImage.sourceHeight = dstHeight;
269
- }
270
- _extractNinePatchSliceDataFromImage() {
271
- const width = this._domImage.width;
272
- const height = this._domImage.height;
273
- if (!this._workingCanvas) {
274
- const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;
275
- if (!engine) {
276
- throw new Error("Invalid engine. Unable to create a canvas.");
277
- }
278
- this._workingCanvas = engine.createCanvas(width, height);
279
- }
280
- const canvas = this._workingCanvas;
281
- const context = canvas.getContext("2d");
282
- context.drawImage(this._domImage, 0, 0, width, height);
283
- const imageData = context.getImageData(0, 0, width, height);
284
- // Left and right
285
- this._sliceLeft = -1;
286
- this._sliceRight = -1;
287
- for (let x = 0; x < width; x++) {
288
- const alpha = imageData.data[x * 4 + 3];
289
- if (alpha > 127 && this._sliceLeft === -1) {
290
- this._sliceLeft = x;
291
- continue;
292
- }
293
- if (alpha < 127 && this._sliceLeft > -1) {
294
- this._sliceRight = x;
295
- break;
296
- }
297
- }
298
- // top and bottom
299
- this._sliceTop = -1;
300
- this._sliceBottom = -1;
301
- for (let y = 0; y < height; y++) {
302
- const alpha = imageData.data[y * width * 4 + 3];
303
- if (alpha > 127 && this._sliceTop === -1) {
304
- this._sliceTop = y;
305
- continue;
306
- }
307
- if (alpha < 127 && this._sliceTop > -1) {
308
- this._sliceBottom = y;
309
- break;
310
- }
311
- }
312
- }
313
- /**
314
- * Gets or sets the internal DOM image used to render the control
315
- */
316
- set domImage(value) {
317
- this._domImage = value;
318
- this._loaded = false;
319
- this._imageDataCache.data = null;
320
- if (this._domImage.width) {
321
- this._onImageLoaded();
322
- }
323
- else {
324
- this._domImage.onload = () => {
325
- this._onImageLoaded();
326
- };
327
- }
328
- }
329
- get domImage() {
330
- return this._domImage;
331
- }
332
- _onImageLoaded() {
333
- this._imageDataCache.data = null;
334
- this._imageWidth = this._domImage.width;
335
- this._imageHeight = this._domImage.height;
336
- this._loaded = true;
337
- if (this._populateNinePatchSlicesFromImage) {
338
- this._extractNinePatchSliceDataFromImage();
339
- }
340
- if (this._autoScale) {
341
- this.synchronizeSizeWithContent();
342
- }
343
- this.onImageLoadedObservable.notifyObservers(this);
344
- this._markAsDirty();
345
- }
346
- /**
347
- * Gets the image source url
348
- */
349
- get source() {
350
- return this._source;
351
- }
352
- /**
353
- * Resets the internal Image Element cache. Can reduce memory usage.
354
- */
355
- static ResetImageCache() {
356
- Image.SourceImgCache.clear();
357
- }
358
- _removeCacheUsage(source) {
359
- const value = source && Image.SourceImgCache.get(source);
360
- if (value) {
361
- value.timesUsed -= 1;
362
- // Remove from DOM
363
- const htmlElement = value.img;
364
- if (htmlElement.parentNode) {
365
- htmlElement.parentNode.removeChild(htmlElement);
366
- }
367
- // Since the image isn't being used anymore, we can clean it from the cache
368
- if (value.timesUsed === 0) {
369
- Image.SourceImgCache.delete(source);
370
- }
371
- }
372
- }
373
- /**
374
- * Gets or sets image source url
375
- */
376
- set source(value) {
377
- if (this._urlRewriter && value) {
378
- value = this._urlRewriter(value);
379
- }
380
- if (this._source === value) {
381
- return;
382
- }
383
- this._removeCacheUsage(this._source);
384
- this._loaded = false;
385
- this._source = value;
386
- this._imageDataCache.data = null;
387
- if (value) {
388
- value = this._svgCheck(value);
389
- }
390
- // Should abstract platform instead of using LastCreatedEngine
391
- const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;
392
- // If no engine, skip all other DOM operations.
393
- if (!engine) {
394
- return;
395
- }
396
- if (value && Image.SourceImgCache.has(value)) {
397
- const cachedData = Image.SourceImgCache.get(value);
398
- this._domImage = cachedData.img;
399
- cachedData.timesUsed += 1;
400
- if (cachedData.loaded) {
401
- this._onImageLoaded();
402
- }
403
- else {
404
- cachedData.waitingForLoadCallback.push(this._onImageLoaded.bind(this));
405
- }
406
- return;
407
- }
408
- this._domImage = engine.createCanvasImage();
409
- // need to add to enforce rendering
410
- const imgElement = this._domImage;
411
- let addedToDom = false;
412
- if (imgElement.style && this._source?.endsWith(".svg")) {
413
- imgElement.style.visibility = "hidden";
414
- imgElement.style.position = "absolute";
415
- imgElement.style.top = "0";
416
- engine.getRenderingCanvas()?.parentNode?.appendChild(imgElement);
417
- addedToDom = true;
418
- }
419
- if (value) {
420
- Image.SourceImgCache.set(value, { img: this._domImage, timesUsed: 1, loaded: false, waitingForLoadCallback: [this._onImageLoaded.bind(this)] });
421
- }
422
- this._domImage.onload = () => {
423
- if (value) {
424
- const cachedData = Image.SourceImgCache.get(value);
425
- if (cachedData) {
426
- cachedData.loaded = true;
427
- for (const waitingCallback of cachedData.waitingForLoadCallback) {
428
- waitingCallback();
264
+ _rotate90SourceProperties(srcImage, dstImage, n) {
265
+ let srcLeft = srcImage.sourceLeft, srcTop = srcImage.sourceTop, srcWidth = srcImage.domImage.width, srcHeight = srcImage.domImage.height;
266
+ let dstLeft = srcLeft, dstTop = srcTop, dstWidth = srcImage.sourceWidth, dstHeight = srcImage.sourceHeight;
267
+ if (n != 0) {
268
+ const mult = n < 0 ? -1 : 1;
269
+ n = n % 4;
270
+ for (let i = 0; i < Math.abs(n); ++i) {
271
+ dstLeft = -(srcTop - srcHeight / 2) * mult + srcHeight / 2;
272
+ dstTop = (srcLeft - srcWidth / 2) * mult + srcWidth / 2;
273
+ [dstWidth, dstHeight] = [dstHeight, dstWidth];
274
+ if (n < 0) {
275
+ dstTop -= dstHeight;
276
+ }
277
+ else {
278
+ dstLeft -= dstWidth;
279
+ }
280
+ srcLeft = dstLeft;
281
+ srcTop = dstTop;
282
+ [srcWidth, srcHeight] = [srcHeight, srcWidth];
283
+ }
284
+ }
285
+ dstImage.sourceLeft = dstLeft;
286
+ dstImage.sourceTop = dstTop;
287
+ dstImage.sourceWidth = dstWidth;
288
+ dstImage.sourceHeight = dstHeight;
289
+ }
290
+ _extractNinePatchSliceDataFromImage() {
291
+ const width = this._domImage.width;
292
+ const height = this._domImage.height;
293
+ if (!this._workingCanvas) {
294
+ const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;
295
+ if (!engine) {
296
+ throw new Error("Invalid engine. Unable to create a canvas.");
297
+ }
298
+ this._workingCanvas = engine.createCanvas(width, height);
299
+ }
300
+ const canvas = this._workingCanvas;
301
+ const context = canvas.getContext("2d");
302
+ context.drawImage(this._domImage, 0, 0, width, height);
303
+ const imageData = context.getImageData(0, 0, width, height);
304
+ // Left and right
305
+ this._sliceLeft = -1;
306
+ this._sliceRight = -1;
307
+ for (let x = 0; x < width; x++) {
308
+ const alpha = imageData.data[x * 4 + 3];
309
+ if (alpha > 127 && this._sliceLeft === -1) {
310
+ this._sliceLeft = x;
311
+ continue;
312
+ }
313
+ if (alpha < 127 && this._sliceLeft > -1) {
314
+ this._sliceRight = x;
315
+ break;
316
+ }
317
+ }
318
+ // top and bottom
319
+ this._sliceTop = -1;
320
+ this._sliceBottom = -1;
321
+ for (let y = 0; y < height; y++) {
322
+ const alpha = imageData.data[y * width * 4 + 3];
323
+ if (alpha > 127 && this._sliceTop === -1) {
324
+ this._sliceTop = y;
325
+ continue;
326
+ }
327
+ if (alpha < 127 && this._sliceTop > -1) {
328
+ this._sliceBottom = y;
329
+ break;
330
+ }
331
+ }
332
+ }
333
+ /**
334
+ * Gets or sets the internal DOM image used to render the control
335
+ */
336
+ set domImage(value) {
337
+ this._domImage = value;
338
+ this._loaded = false;
339
+ this._imageDataCache.data = null;
340
+ if (this._domImage.width) {
341
+ this._onImageLoaded();
342
+ }
343
+ else {
344
+ this._domImage.onload = () => {
345
+ this._onImageLoaded();
346
+ };
347
+ }
348
+ }
349
+ get domImage() {
350
+ return this._domImage;
351
+ }
352
+ _onImageLoaded() {
353
+ this._imageDataCache.data = null;
354
+ this._imageWidth = this._domImage.width;
355
+ this._imageHeight = this._domImage.height;
356
+ this._loaded = true;
357
+ if (this._populateNinePatchSlicesFromImage) {
358
+ this._extractNinePatchSliceDataFromImage();
359
+ }
360
+ if (this._autoScale) {
361
+ this.synchronizeSizeWithContent();
362
+ }
363
+ this.onImageLoadedObservable.notifyObservers(this);
364
+ this._markAsDirty();
365
+ }
366
+ /**
367
+ * Gets the image source url
368
+ */
369
+ get source() {
370
+ return this._source;
371
+ }
372
+ /**
373
+ * Resets the internal Image Element cache. Can reduce memory usage.
374
+ */
375
+ static ResetImageCache() {
376
+ _a.SourceImgCache.clear();
377
+ }
378
+ _removeCacheUsage(source) {
379
+ const value = source && _a.SourceImgCache.get(source);
380
+ if (value) {
381
+ value.timesUsed -= 1;
382
+ // Remove from DOM
383
+ const htmlElement = value.img;
384
+ if (htmlElement.parentNode) {
385
+ htmlElement.parentNode.removeChild(htmlElement);
386
+ }
387
+ // Since the image isn't being used anymore, we can clean it from the cache
388
+ if (value.timesUsed === 0) {
389
+ _a.SourceImgCache.delete(source);
390
+ }
391
+ }
392
+ }
393
+ /**
394
+ * Gets or sets image source url
395
+ */
396
+ set source(value) {
397
+ if (this._urlRewriter && value) {
398
+ value = this._urlRewriter(value);
399
+ }
400
+ if (this._source === value) {
401
+ return;
402
+ }
403
+ this._removeCacheUsage(this._source);
404
+ this._loaded = false;
405
+ this._source = value;
406
+ this._imageDataCache.data = null;
407
+ if (value) {
408
+ value = this._svgCheck(value);
409
+ }
410
+ // Should abstract platform instead of using LastCreatedEngine
411
+ const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;
412
+ // If no engine, skip all other DOM operations.
413
+ if (!engine) {
414
+ return;
415
+ }
416
+ if (value && _a.SourceImgCache.has(value)) {
417
+ const cachedData = _a.SourceImgCache.get(value);
418
+ this._domImage = cachedData.img;
419
+ cachedData.timesUsed += 1;
420
+ if (cachedData.loaded) {
421
+ this._onImageLoaded();
422
+ }
423
+ else {
424
+ cachedData.waitingForLoadCallback.push(this._onImageLoaded.bind(this));
429
425
  }
430
- cachedData.waitingForLoadCallback.length = 0;
431
- addedToDom && imgElement.remove();
432
426
  return;
433
427
  }
428
+ this._domImage = engine.createCanvasImage();
429
+ // need to add to enforce rendering
430
+ const imgElement = this._domImage;
431
+ let addedToDom = false;
432
+ if (imgElement.style && this._source?.endsWith(".svg")) {
433
+ imgElement.style.visibility = "hidden";
434
+ imgElement.style.position = "absolute";
435
+ imgElement.style.top = "0";
436
+ engine.getRenderingCanvas()?.parentNode?.appendChild(imgElement);
437
+ addedToDom = true;
438
+ }
439
+ if (value) {
440
+ _a.SourceImgCache.set(value, { img: this._domImage, timesUsed: 1, loaded: false, waitingForLoadCallback: [this._onImageLoaded.bind(this)] });
441
+ }
442
+ this._domImage.onload = () => {
443
+ if (value) {
444
+ const cachedData = _a.SourceImgCache.get(value);
445
+ if (cachedData) {
446
+ cachedData.loaded = true;
447
+ for (const waitingCallback of cachedData.waitingForLoadCallback) {
448
+ waitingCallback();
449
+ }
450
+ cachedData.waitingForLoadCallback.length = 0;
451
+ addedToDom && imgElement.remove();
452
+ return;
453
+ }
454
+ }
455
+ this._onImageLoaded();
456
+ addedToDom && imgElement.remove();
457
+ };
458
+ if (value) {
459
+ Tools.SetCorsBehavior(value, this._domImage);
460
+ Tools.SetReferrerPolicyBehavior(this.referrerPolicy, this._domImage);
461
+ this._domImage.src = value;
462
+ }
434
463
  }
435
- this._onImageLoaded();
436
- addedToDom && imgElement.remove();
437
- };
438
- if (value) {
439
- Tools.SetCorsBehavior(value, this._domImage);
440
- Tools.SetReferrerPolicyBehavior(this.referrerPolicy, this._domImage);
441
- this._domImage.src = value;
442
- }
443
- }
444
- _sanitizeSVG(svgString) {
445
- if (svgString.indexOf("<svg") === -1) {
446
- return svgString; // Not an SVG, return as is
447
- }
448
- const parser = new DOMParser();
449
- const doc = parser.parseFromString(svgString, "image/svg+xml");
450
- const dangerousTags = ["script", "iframe", "foreignObject", "object", "embed", "link", "style"];
451
- const dangerousAttrs = [/^on/i, /^xlink:href$/, /^href$/];
452
- // Remove dangerous elements
453
- dangerousTags.forEach((tag) => {
454
- const elements = doc.getElementsByTagName(tag);
455
- for (let i = elements.length - 1; i >= 0; i--) {
456
- elements[i].remove();
457
- }
458
- });
459
- // Recursively sanitize attributes
460
- function sanitizeElement(el) {
461
- if (el.attributes) {
462
- for (let i = el.attributes.length - 1; i >= 0; i--) {
463
- const attr = el.attributes[i];
464
- const name = attr.name;
465
- const value = attr.value;
466
- // Remove dangerous attributes
467
- if (dangerousAttrs.some((regex) => regex.test(name))) {
468
- el.removeAttribute(name);
464
+ _sanitizeSVG(svgString) {
465
+ if (svgString.indexOf("<svg") === -1) {
466
+ return svgString; // Not an SVG, return as is
467
+ }
468
+ const parser = new DOMParser();
469
+ const doc = parser.parseFromString(svgString, "image/svg+xml");
470
+ const dangerousTags = ["script", "iframe", "foreignObject", "object", "embed", "link", "style"];
471
+ const dangerousAttrs = [/^on/i, /^xlink:href$/, /^href$/];
472
+ // Remove dangerous elements
473
+ dangerousTags.forEach((tag) => {
474
+ const elements = doc.getElementsByTagName(tag);
475
+ for (let i = elements.length - 1; i >= 0; i--) {
476
+ elements[i].remove();
477
+ }
478
+ });
479
+ // Recursively sanitize attributes
480
+ function sanitizeElement(el) {
481
+ if (el.attributes) {
482
+ for (let i = el.attributes.length - 1; i >= 0; i--) {
483
+ const attr = el.attributes[i];
484
+ const name = attr.name;
485
+ const value = attr.value;
486
+ // Remove dangerous attributes
487
+ if (dangerousAttrs.some((regex) => regex.test(name))) {
488
+ el.removeAttribute(name);
489
+ }
490
+ // Remove javascript: links
491
+ if (typeof value === "string" && value.trim().toLowerCase().startsWith("javascript:")) {
492
+ el.removeAttribute(name);
493
+ }
494
+ }
469
495
  }
470
- // Remove javascript: links
471
- if (typeof value === "string" && value.trim().toLowerCase().startsWith("javascript:")) {
472
- el.removeAttribute(name);
496
+ // Recursively sanitize children
497
+ for (let i = 0; i < el.children.length; i++) {
498
+ sanitizeElement(el.children[i]);
473
499
  }
474
500
  }
501
+ sanitizeElement(doc.documentElement);
502
+ return new XMLSerializer().serializeToString(doc);
475
503
  }
476
- // Recursively sanitize children
477
- for (let i = 0; i < el.children.length; i++) {
478
- sanitizeElement(el.children[i]);
504
+ /**
505
+ * Checks for svg document with icon id present
506
+ * @param value the source svg
507
+ * @returns the svg
508
+ */
509
+ _svgCheck(value) {
510
+ // Skip SVG processing if no window/document or SVG support
511
+ if (typeof window === "undefined" || typeof document === "undefined" || !window.SVGSVGElement) {
512
+ return value;
513
+ }
514
+ if (window.SVGSVGElement && value.search(/(\.svg|\.svg?[?|#].*)$/gi) !== -1 && value.indexOf("#") === value.lastIndexOf("#")) {
515
+ this._isSVG = true;
516
+ value = this._sanitizeSVG(value);
517
+ const svgsrc = value.split("#")[0];
518
+ const elemid = value.split("#")[1];
519
+ // check if object alr exist in document
520
+ const svgExist = document.body.querySelector('object[data="' + svgsrc + '"]');
521
+ if (svgExist) {
522
+ const svgDoc = svgExist.contentDocument;
523
+ // get viewbox width and height, get svg document width and height in px
524
+ if (svgDoc && svgDoc.documentElement) {
525
+ const vb = svgDoc.documentElement.getAttribute("viewBox");
526
+ const docwidth = Number(svgDoc.documentElement.getAttribute("width"));
527
+ const docheight = Number(svgDoc.documentElement.getAttribute("height"));
528
+ const elem = svgDoc.getElementById(elemid);
529
+ if (elem && vb && docwidth && docheight) {
530
+ this._getSVGAttribs(svgExist, elemid);
531
+ return value;
532
+ }
533
+ }
534
+ // wait for object to load
535
+ svgExist.addEventListener("load", () => {
536
+ this._getSVGAttribs(svgExist, elemid);
537
+ });
538
+ }
539
+ else {
540
+ // create document object
541
+ const svgImage = document.createElement("object");
542
+ svgImage.data = svgsrc;
543
+ svgImage.type = "image/svg+xml";
544
+ svgImage.width = "0%";
545
+ svgImage.height = "0%";
546
+ document.body.appendChild(svgImage);
547
+ // when the object has loaded, get the element attribs
548
+ svgImage.onload = () => {
549
+ const svgobj = document.body.querySelector('object[data="' + svgsrc + '"]');
550
+ if (svgobj) {
551
+ this._getSVGAttribs(svgobj, elemid);
552
+ }
553
+ };
554
+ }
555
+ return svgsrc;
556
+ }
557
+ else {
558
+ return value;
559
+ }
479
560
  }
480
- }
481
- sanitizeElement(doc.documentElement);
482
- return new XMLSerializer().serializeToString(doc);
483
- }
484
- /**
485
- * Checks for svg document with icon id present
486
- * @param value the source svg
487
- * @returns the svg
488
- */
489
- _svgCheck(value) {
490
- // Skip SVG processing if no window/document or SVG support
491
- if (typeof window === "undefined" || typeof document === "undefined" || !window.SVGSVGElement) {
492
- return value;
493
- }
494
- if (window.SVGSVGElement && value.search(/(\.svg|\.svg?[?|#].*)$/gi) !== -1 && value.indexOf("#") === value.lastIndexOf("#")) {
495
- this._isSVG = true;
496
- value = this._sanitizeSVG(value);
497
- const svgsrc = value.split("#")[0];
498
- const elemid = value.split("#")[1];
499
- // check if object alr exist in document
500
- const svgExist = document.body.querySelector('object[data="' + svgsrc + '"]');
501
- if (svgExist) {
502
- const svgDoc = svgExist.contentDocument;
561
+ /**
562
+ * Sets sourceLeft, sourceTop, sourceWidth, sourceHeight automatically
563
+ * given external svg file and icon id
564
+ * @param svgsrc
565
+ * @param elemid
566
+ */
567
+ _getSVGAttribs(svgsrc, elemid) {
568
+ const svgDoc = svgsrc.contentDocument;
503
569
  // get viewbox width and height, get svg document width and height in px
504
570
  if (svgDoc && svgDoc.documentElement) {
505
571
  const vb = svgDoc.documentElement.getAttribute("viewBox");
506
572
  const docwidth = Number(svgDoc.documentElement.getAttribute("width"));
507
573
  const docheight = Number(svgDoc.documentElement.getAttribute("height"));
574
+ // get element bbox and matrix transform
508
575
  const elem = svgDoc.getElementById(elemid);
509
- if (elem && vb && docwidth && docheight) {
510
- this._getSVGAttribs(svgExist, elemid);
511
- return value;
576
+ if (vb && docwidth && docheight && elem) {
577
+ const vbWidth = Number(vb.split(" ")[2]);
578
+ const vbHeight = Number(vb.split(" ")[3]);
579
+ const elemBbox = elem.getBBox();
580
+ let elemMatrixA = 1;
581
+ let elemMatrixD = 1;
582
+ let elemMatrixE = 0;
583
+ let elemMatrixF = 0;
584
+ const consolidatedTransform = elem.transform?.baseVal.consolidate();
585
+ if (consolidatedTransform) {
586
+ const mainMatrix = consolidatedTransform.matrix;
587
+ elemMatrixA = mainMatrix.a;
588
+ elemMatrixD = mainMatrix.d;
589
+ elemMatrixE = mainMatrix.e;
590
+ elemMatrixF = mainMatrix.f;
591
+ }
592
+ // compute source coordinates and dimensions
593
+ this.sourceLeft = ((elemMatrixA * elemBbox.x + elemMatrixE) * docwidth) / vbWidth;
594
+ this.sourceTop = ((elemMatrixD * elemBbox.y + elemMatrixF) * docheight) / vbHeight;
595
+ this.sourceWidth = elemBbox.width * elemMatrixA * (docwidth / vbWidth);
596
+ this.sourceHeight = elemBbox.height * elemMatrixD * (docheight / vbHeight);
597
+ this._svgAttributesComputationCompleted = true;
598
+ this.onSVGAttributesComputedObservable.notifyObservers(this);
512
599
  }
513
600
  }
514
- // wait for object to load
515
- svgExist.addEventListener("load", () => {
516
- this._getSVGAttribs(svgExist, elemid);
517
- });
518
601
  }
519
- else {
520
- // create document object
521
- const svgImage = document.createElement("object");
522
- svgImage.data = svgsrc;
523
- svgImage.type = "image/svg+xml";
524
- svgImage.width = "0%";
525
- svgImage.height = "0%";
526
- document.body.appendChild(svgImage);
527
- // when the object has loaded, get the element attribs
528
- svgImage.onload = () => {
529
- const svgobj = document.body.querySelector('object[data="' + svgsrc + '"]');
530
- if (svgobj) {
531
- this._getSVGAttribs(svgobj, elemid);
602
+ /**
603
+ * Gets or sets the cell width to use when animation sheet is enabled
604
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#image
605
+ */
606
+ get cellWidth() {
607
+ return this._cellWidth;
608
+ }
609
+ set cellWidth(value) {
610
+ if (this._cellWidth === value) {
611
+ return;
612
+ }
613
+ this._cellWidth = value;
614
+ this._markAsDirty();
615
+ }
616
+ /**
617
+ * Gets or sets the cell height to use when animation sheet is enabled
618
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#image
619
+ */
620
+ get cellHeight() {
621
+ return this._cellHeight;
622
+ }
623
+ set cellHeight(value) {
624
+ if (this._cellHeight === value) {
625
+ return;
626
+ }
627
+ this._cellHeight = value;
628
+ this._markAsDirty();
629
+ }
630
+ /**
631
+ * Gets or sets the cell id to use (this will turn on the animation sheet mode)
632
+ * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#image
633
+ */
634
+ get cellId() {
635
+ return this._cellId;
636
+ }
637
+ set cellId(value) {
638
+ if (this._cellId === value) {
639
+ return;
640
+ }
641
+ this._cellId = value;
642
+ this._markAsDirty();
643
+ }
644
+ /**
645
+ * Creates a new Image
646
+ * @param name defines the control name
647
+ * @param url defines the image url
648
+ */
649
+ constructor(name, url = null) {
650
+ super(name);
651
+ this.name = (__runInitializers(this, _instanceExtraInitializers), name);
652
+ this._workingCanvas = null;
653
+ this._loaded = false;
654
+ this._stretch = _a.STRETCH_FILL;
655
+ this._source = null;
656
+ this._autoScale = false;
657
+ this._sourceLeft = 0;
658
+ this._sourceTop = 0;
659
+ this._sourceWidth = 0;
660
+ this._sourceHeight = 0;
661
+ this._svgAttributesComputationCompleted = false;
662
+ this._isSVG = false;
663
+ this._cellWidth = 0;
664
+ this._cellHeight = 0;
665
+ this._cellId = -1;
666
+ this._populateNinePatchSlicesFromImage = false;
667
+ this._imageDataCache = { data: null, key: "" };
668
+ /**
669
+ * Observable notified when the content is loaded
670
+ */
671
+ this.onImageLoadedObservable = new Observable();
672
+ /**
673
+ * Observable notified when _sourceLeft, _sourceTop, _sourceWidth and _sourceHeight are computed
674
+ */
675
+ this.onSVGAttributesComputedObservable = new Observable();
676
+ this.source = url;
677
+ }
678
+ /**
679
+ * Tests if a given coordinates belong to the current control
680
+ * @param x defines x coordinate to test
681
+ * @param y defines y coordinate to test
682
+ * @returns true if the coordinates are inside the control
683
+ */
684
+ contains(x, y) {
685
+ if (!super.contains(x, y)) {
686
+ return false;
687
+ }
688
+ if (!this._detectPointerOnOpaqueOnly || !this._workingCanvas) {
689
+ return true;
690
+ }
691
+ const width = this._currentMeasure.width | 0;
692
+ const height = this._currentMeasure.height | 0;
693
+ const key = width + "_" + height;
694
+ let imageData = this._imageDataCache.data;
695
+ if (!imageData || this._imageDataCache.key !== key) {
696
+ const canvas = this._workingCanvas;
697
+ const context = canvas.getContext("2d");
698
+ this._imageDataCache.data = imageData = context.getImageData(0, 0, width, height).data;
699
+ this._imageDataCache.key = key;
700
+ }
701
+ x = (x - this._currentMeasure.left) | 0;
702
+ y = (y - this._currentMeasure.top) | 0;
703
+ const pickedPixel = imageData[(x + y * width) * 4 + 3];
704
+ return pickedPixel > 0;
705
+ }
706
+ _getTypeName() {
707
+ return "Image";
708
+ }
709
+ /** Force the control to synchronize with its content */
710
+ synchronizeSizeWithContent() {
711
+ if (!this._loaded) {
712
+ return;
713
+ }
714
+ this.width = this._domImage.width + "px";
715
+ this.height = this._domImage.height + "px";
716
+ }
717
+ _processMeasures(parentMeasure, context) {
718
+ if (this._loaded) {
719
+ switch (this._stretch) {
720
+ case _a.STRETCH_NONE:
721
+ break;
722
+ case _a.STRETCH_FILL:
723
+ break;
724
+ case _a.STRETCH_UNIFORM:
725
+ break;
726
+ case _a.STRETCH_NINE_PATCH:
727
+ break;
728
+ case _a.STRETCH_EXTEND:
729
+ if (this._autoScale) {
730
+ this.synchronizeSizeWithContent();
731
+ }
732
+ if (this.parent && this.parent.parent) {
733
+ // Will update root size if root is not the top root
734
+ this.parent.adaptWidthToChildren = true;
735
+ this.parent.adaptHeightToChildren = true;
736
+ }
737
+ break;
532
738
  }
533
- };
739
+ }
740
+ super._processMeasures(parentMeasure, context);
534
741
  }
535
- return svgsrc;
536
- }
537
- else {
538
- return value;
539
- }
540
- }
541
- /**
542
- * Sets sourceLeft, sourceTop, sourceWidth, sourceHeight automatically
543
- * given external svg file and icon id
544
- * @param svgsrc
545
- * @param elemid
546
- */
547
- _getSVGAttribs(svgsrc, elemid) {
548
- const svgDoc = svgsrc.contentDocument;
549
- // get viewbox width and height, get svg document width and height in px
550
- if (svgDoc && svgDoc.documentElement) {
551
- const vb = svgDoc.documentElement.getAttribute("viewBox");
552
- const docwidth = Number(svgDoc.documentElement.getAttribute("width"));
553
- const docheight = Number(svgDoc.documentElement.getAttribute("height"));
554
- // get element bbox and matrix transform
555
- const elem = svgDoc.getElementById(elemid);
556
- if (vb && docwidth && docheight && elem) {
557
- const vbWidth = Number(vb.split(" ")[2]);
558
- const vbHeight = Number(vb.split(" ")[3]);
559
- const elemBbox = elem.getBBox();
560
- let elemMatrixA = 1;
561
- let elemMatrixD = 1;
562
- let elemMatrixE = 0;
563
- let elemMatrixF = 0;
564
- const consolidatedTransform = elem.transform?.baseVal.consolidate();
565
- if (consolidatedTransform) {
566
- const mainMatrix = consolidatedTransform.matrix;
567
- elemMatrixA = mainMatrix.a;
568
- elemMatrixD = mainMatrix.d;
569
- elemMatrixE = mainMatrix.e;
570
- elemMatrixF = mainMatrix.f;
571
- }
572
- // compute source coordinates and dimensions
573
- this.sourceLeft = ((elemMatrixA * elemBbox.x + elemMatrixE) * docwidth) / vbWidth;
574
- this.sourceTop = ((elemMatrixD * elemBbox.y + elemMatrixF) * docheight) / vbHeight;
575
- this.sourceWidth = elemBbox.width * elemMatrixA * (docwidth / vbWidth);
576
- this.sourceHeight = elemBbox.height * elemMatrixD * (docheight / vbHeight);
577
- this._svgAttributesComputationCompleted = true;
578
- this.onSVGAttributesComputedObservable.notifyObservers(this);
579
- }
580
- }
581
- }
582
- /**
583
- * Gets or sets the cell width to use when animation sheet is enabled
584
- * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#image
585
- */
586
- get cellWidth() {
587
- return this._cellWidth;
588
- }
589
- set cellWidth(value) {
590
- if (this._cellWidth === value) {
591
- return;
592
- }
593
- this._cellWidth = value;
594
- this._markAsDirty();
595
- }
596
- /**
597
- * Gets or sets the cell height to use when animation sheet is enabled
598
- * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#image
599
- */
600
- get cellHeight() {
601
- return this._cellHeight;
602
- }
603
- set cellHeight(value) {
604
- if (this._cellHeight === value) {
605
- return;
606
- }
607
- this._cellHeight = value;
608
- this._markAsDirty();
609
- }
610
- /**
611
- * Gets or sets the cell id to use (this will turn on the animation sheet mode)
612
- * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#image
613
- */
614
- get cellId() {
615
- return this._cellId;
616
- }
617
- set cellId(value) {
618
- if (this._cellId === value) {
619
- return;
620
- }
621
- this._cellId = value;
622
- this._markAsDirty();
623
- }
624
- /**
625
- * Creates a new Image
626
- * @param name defines the control name
627
- * @param url defines the image url
628
- */
629
- constructor(name, url = null) {
630
- super(name);
631
- this.name = name;
632
- this._workingCanvas = null;
633
- this._loaded = false;
634
- this._stretch = Image.STRETCH_FILL;
635
- this._source = null;
636
- this._autoScale = false;
637
- this._sourceLeft = 0;
638
- this._sourceTop = 0;
639
- this._sourceWidth = 0;
640
- this._sourceHeight = 0;
641
- this._svgAttributesComputationCompleted = false;
642
- this._isSVG = false;
643
- this._cellWidth = 0;
644
- this._cellHeight = 0;
645
- this._cellId = -1;
646
- this._populateNinePatchSlicesFromImage = false;
647
- this._imageDataCache = { data: null, key: "" };
648
- /**
649
- * Observable notified when the content is loaded
650
- */
651
- this.onImageLoadedObservable = new Observable();
652
- /**
653
- * Observable notified when _sourceLeft, _sourceTop, _sourceWidth and _sourceHeight are computed
654
- */
655
- this.onSVGAttributesComputedObservable = new Observable();
656
- this.source = url;
657
- }
658
- /**
659
- * Tests if a given coordinates belong to the current control
660
- * @param x defines x coordinate to test
661
- * @param y defines y coordinate to test
662
- * @returns true if the coordinates are inside the control
663
- */
664
- contains(x, y) {
665
- if (!super.contains(x, y)) {
666
- return false;
667
- }
668
- if (!this._detectPointerOnOpaqueOnly || !this._workingCanvas) {
669
- return true;
670
- }
671
- const width = this._currentMeasure.width | 0;
672
- const height = this._currentMeasure.height | 0;
673
- const key = width + "_" + height;
674
- let imageData = this._imageDataCache.data;
675
- if (!imageData || this._imageDataCache.key !== key) {
676
- const canvas = this._workingCanvas;
677
- const context = canvas.getContext("2d");
678
- this._imageDataCache.data = imageData = context.getImageData(0, 0, width, height).data;
679
- this._imageDataCache.key = key;
680
- }
681
- x = (x - this._currentMeasure.left) | 0;
682
- y = (y - this._currentMeasure.top) | 0;
683
- const pickedPixel = imageData[(x + y * width) * 4 + 3];
684
- return pickedPixel > 0;
685
- }
686
- _getTypeName() {
687
- return "Image";
688
- }
689
- /** Force the control to synchronize with its content */
690
- synchronizeSizeWithContent() {
691
- if (!this._loaded) {
692
- return;
693
- }
694
- this.width = this._domImage.width + "px";
695
- this.height = this._domImage.height + "px";
696
- }
697
- _processMeasures(parentMeasure, context) {
698
- if (this._loaded) {
699
- switch (this._stretch) {
700
- case Image.STRETCH_NONE:
701
- break;
702
- case Image.STRETCH_FILL:
703
- break;
704
- case Image.STRETCH_UNIFORM:
705
- break;
706
- case Image.STRETCH_NINE_PATCH:
707
- break;
708
- case Image.STRETCH_EXTEND:
709
- if (this._autoScale) {
710
- this.synchronizeSizeWithContent();
742
+ _prepareWorkingCanvasForOpaqueDetection() {
743
+ if (!this._detectPointerOnOpaqueOnly) {
744
+ return;
745
+ }
746
+ const width = this._currentMeasure.width;
747
+ const height = this._currentMeasure.height;
748
+ if (!this._workingCanvas) {
749
+ const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;
750
+ if (!engine) {
751
+ throw new Error("Invalid engine. Unable to create a canvas.");
711
752
  }
712
- if (this.parent && this.parent.parent) {
713
- // Will update root size if root is not the top root
714
- this.parent.adaptWidthToChildren = true;
715
- this.parent.adaptHeightToChildren = true;
753
+ this._workingCanvas = engine.createCanvas(width, height);
754
+ }
755
+ const canvas = this._workingCanvas;
756
+ const context = canvas.getContext("2d");
757
+ context.clearRect(0, 0, width, height);
758
+ }
759
+ _drawImage(context, sx, sy, sw, sh, tx, ty, tw, th) {
760
+ context.drawImage(this._domImage, sx, sy, sw, sh, tx, ty, tw, th);
761
+ if (!this._detectPointerOnOpaqueOnly) {
762
+ return;
763
+ }
764
+ const transform = context.getTransform();
765
+ const canvas = this._workingCanvas;
766
+ const workingCanvasContext = canvas.getContext("2d");
767
+ workingCanvasContext.save();
768
+ const ttx = tx - this._currentMeasure.left;
769
+ const tty = ty - this._currentMeasure.top;
770
+ workingCanvasContext.setTransform(transform.a, transform.b, transform.c, transform.d, (ttx + tw) / 2, (tty + th) / 2);
771
+ workingCanvasContext.translate(-(ttx + tw) / 2, -(tty + th) / 2);
772
+ workingCanvasContext.drawImage(this._domImage, sx, sy, sw, sh, ttx, tty, tw, th);
773
+ workingCanvasContext.restore();
774
+ }
775
+ _draw(context) {
776
+ context.save();
777
+ if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
778
+ context.shadowColor = this.shadowColor;
779
+ context.shadowBlur = this.shadowBlur;
780
+ context.shadowOffsetX = this.shadowOffsetX * this._host.idealRatio;
781
+ context.shadowOffsetY = this.shadowOffsetY * this._host.idealRatio;
782
+ }
783
+ let x, y, width, height;
784
+ if (this.cellId == -1) {
785
+ x = this._sourceLeft;
786
+ y = this._sourceTop;
787
+ width = this._sourceWidth ? this._sourceWidth : this._imageWidth;
788
+ height = this._sourceHeight ? this._sourceHeight : this._imageHeight;
789
+ }
790
+ else {
791
+ const rowCount = this._domImage.naturalWidth / this.cellWidth;
792
+ const column = (this.cellId / rowCount) >> 0;
793
+ const row = this.cellId % rowCount;
794
+ x = this.cellWidth * row;
795
+ y = this.cellHeight * column;
796
+ width = this.cellWidth;
797
+ height = this.cellHeight;
798
+ }
799
+ this._prepareWorkingCanvasForOpaqueDetection();
800
+ this._applyStates(context);
801
+ if (this._loaded) {
802
+ switch (this._stretch) {
803
+ case _a.STRETCH_NONE:
804
+ this._drawImage(context, x, y, width, height, this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
805
+ break;
806
+ case _a.STRETCH_FILL:
807
+ this._drawImage(context, x, y, width, height, this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
808
+ break;
809
+ case _a.STRETCH_UNIFORM: {
810
+ const hRatio = this._currentMeasure.width / width;
811
+ const vRatio = this._currentMeasure.height / height;
812
+ const ratio = Math.min(hRatio, vRatio);
813
+ const centerX = (this._currentMeasure.width - width * ratio) / 2;
814
+ const centerY = (this._currentMeasure.height - height * ratio) / 2;
815
+ this._drawImage(context, x, y, width, height, this._currentMeasure.left + centerX, this._currentMeasure.top + centerY, width * ratio, height * ratio);
816
+ break;
817
+ }
818
+ case _a.STRETCH_EXTEND:
819
+ this._drawImage(context, x, y, width, height, this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
820
+ break;
821
+ case _a.STRETCH_NINE_PATCH:
822
+ this._renderNinePatch(context, x, y, width, height);
823
+ break;
716
824
  }
717
- break;
825
+ }
826
+ context.restore();
718
827
  }
719
- }
720
- super._processMeasures(parentMeasure, context);
721
- }
722
- _prepareWorkingCanvasForOpaqueDetection() {
723
- if (!this._detectPointerOnOpaqueOnly) {
724
- return;
725
- }
726
- const width = this._currentMeasure.width;
727
- const height = this._currentMeasure.height;
728
- if (!this._workingCanvas) {
729
- const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;
730
- if (!engine) {
731
- throw new Error("Invalid engine. Unable to create a canvas.");
732
- }
733
- this._workingCanvas = engine.createCanvas(width, height);
734
- }
735
- const canvas = this._workingCanvas;
736
- const context = canvas.getContext("2d");
737
- context.clearRect(0, 0, width, height);
738
- }
739
- _drawImage(context, sx, sy, sw, sh, tx, ty, tw, th) {
740
- context.drawImage(this._domImage, sx, sy, sw, sh, tx, ty, tw, th);
741
- if (!this._detectPointerOnOpaqueOnly) {
742
- return;
743
- }
744
- const transform = context.getTransform();
745
- const canvas = this._workingCanvas;
746
- const workingCanvasContext = canvas.getContext("2d");
747
- workingCanvasContext.save();
748
- const ttx = tx - this._currentMeasure.left;
749
- const tty = ty - this._currentMeasure.top;
750
- workingCanvasContext.setTransform(transform.a, transform.b, transform.c, transform.d, (ttx + tw) / 2, (tty + th) / 2);
751
- workingCanvasContext.translate(-(ttx + tw) / 2, -(tty + th) / 2);
752
- workingCanvasContext.drawImage(this._domImage, sx, sy, sw, sh, ttx, tty, tw, th);
753
- workingCanvasContext.restore();
754
- }
755
- _draw(context) {
756
- context.save();
757
- if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
758
- context.shadowColor = this.shadowColor;
759
- context.shadowBlur = this.shadowBlur;
760
- context.shadowOffsetX = this.shadowOffsetX * this._host.idealRatio;
761
- context.shadowOffsetY = this.shadowOffsetY * this._host.idealRatio;
762
- }
763
- let x, y, width, height;
764
- if (this.cellId == -1) {
765
- x = this._sourceLeft;
766
- y = this._sourceTop;
767
- width = this._sourceWidth ? this._sourceWidth : this._imageWidth;
768
- height = this._sourceHeight ? this._sourceHeight : this._imageHeight;
769
- }
770
- else {
771
- const rowCount = this._domImage.naturalWidth / this.cellWidth;
772
- const column = (this.cellId / rowCount) >> 0;
773
- const row = this.cellId % rowCount;
774
- x = this.cellWidth * row;
775
- y = this.cellHeight * column;
776
- width = this.cellWidth;
777
- height = this.cellHeight;
778
- }
779
- this._prepareWorkingCanvasForOpaqueDetection();
780
- this._applyStates(context);
781
- if (this._loaded) {
782
- switch (this._stretch) {
783
- case Image.STRETCH_NONE:
784
- this._drawImage(context, x, y, width, height, this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
785
- break;
786
- case Image.STRETCH_FILL:
787
- this._drawImage(context, x, y, width, height, this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
788
- break;
789
- case Image.STRETCH_UNIFORM: {
790
- const hRatio = this._currentMeasure.width / width;
791
- const vRatio = this._currentMeasure.height / height;
792
- const ratio = Math.min(hRatio, vRatio);
793
- const centerX = (this._currentMeasure.width - width * ratio) / 2;
794
- const centerY = (this._currentMeasure.height - height * ratio) / 2;
795
- this._drawImage(context, x, y, width, height, this._currentMeasure.left + centerX, this._currentMeasure.top + centerY, width * ratio, height * ratio);
796
- break;
797
- }
798
- case Image.STRETCH_EXTEND:
799
- this._drawImage(context, x, y, width, height, this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
800
- break;
801
- case Image.STRETCH_NINE_PATCH:
802
- this._renderNinePatch(context, x, y, width, height);
803
- break;
804
- }
805
- }
806
- context.restore();
807
- }
808
- _renderNinePatch(context, sx, sy, sw, sh) {
809
- const idealRatio = this.host.idealRatio;
810
- const leftWidth = this._sliceLeft;
811
- const topHeight = this._sliceTop;
812
- const bottomHeight = sh - this._sliceBottom;
813
- const rightWidth = sw - this._sliceRight;
814
- const centerWidth = this._sliceRight - this._sliceLeft;
815
- const centerHeight = this._sliceBottom - this._sliceTop;
816
- const leftWidthAdjusted = Math.round(leftWidth * idealRatio);
817
- const topHeightAdjusted = Math.round(topHeight * idealRatio);
818
- const bottomHeightAdjusted = Math.round(bottomHeight * idealRatio);
819
- const rightWidthAdjusted = Math.round(rightWidth * idealRatio);
820
- const targetCenterWidth = Math.round(this._currentMeasure.width) - rightWidthAdjusted - leftWidthAdjusted + 2;
821
- const targetCenterHeight = Math.round(this._currentMeasure.height) - bottomHeightAdjusted - topHeightAdjusted + 2;
822
- const centerLeftOffset = Math.round(this._currentMeasure.left) + leftWidthAdjusted - 1;
823
- const centerTopOffset = Math.round(this._currentMeasure.top) + topHeightAdjusted - 1;
824
- const rightOffset = Math.round(this._currentMeasure.left + this._currentMeasure.width) - rightWidthAdjusted;
825
- const bottomOffset = Math.round(this._currentMeasure.top + this._currentMeasure.height) - bottomHeightAdjusted;
826
- //Top Left
827
- this._drawImage(context, sx, sy, leftWidth, topHeight, this._currentMeasure.left, this._currentMeasure.top, leftWidthAdjusted, topHeightAdjusted);
828
- //Top
829
- this._drawImage(context, sx + this._sliceLeft, sy, centerWidth, topHeight, centerLeftOffset + 1, this._currentMeasure.top, targetCenterWidth - 2, topHeightAdjusted);
830
- //Top Right
831
- this._drawImage(context, sx + this._sliceRight, sy, rightWidth, topHeight, rightOffset, this._currentMeasure.top, rightWidthAdjusted, topHeightAdjusted);
832
- //Left
833
- this._drawImage(context, sx, sy + this._sliceTop, leftWidth, centerHeight, this._currentMeasure.left, centerTopOffset + 1, leftWidthAdjusted, targetCenterHeight - 2);
834
- // Center
835
- this._drawImage(context, sx + this._sliceLeft, sy + this._sliceTop, centerWidth, centerHeight, centerLeftOffset + 1, centerTopOffset + 1, targetCenterWidth - 2, targetCenterHeight - 2);
836
- //Right
837
- this._drawImage(context, sx + this._sliceRight, sy + this._sliceTop, rightWidth, centerHeight, rightOffset, centerTopOffset + 1, rightWidthAdjusted, targetCenterHeight - 2);
838
- //Bottom Left
839
- this._drawImage(context, sx, sy + this._sliceBottom, leftWidth, bottomHeight, this._currentMeasure.left, bottomOffset, leftWidthAdjusted, bottomHeightAdjusted);
840
- //Bottom
841
- this._drawImage(context, sx + this.sliceLeft, sy + this._sliceBottom, centerWidth, bottomHeight, centerLeftOffset + 1, bottomOffset, targetCenterWidth - 2, bottomHeightAdjusted);
842
- //Bottom Right
843
- this._drawImage(context, sx + this._sliceRight, sy + this._sliceBottom, rightWidth, bottomHeight, rightOffset, bottomOffset, rightWidthAdjusted, bottomHeightAdjusted);
844
- }
845
- dispose() {
846
- super.dispose();
847
- this.onImageLoadedObservable.clear();
848
- this.onSVGAttributesComputedObservable.clear();
849
- this._removeCacheUsage(this._source);
850
- }
851
- }
852
- /**
853
- * Cache of images to avoid loading the same image multiple times
854
- */
855
- Image.SourceImgCache = new Map();
856
- // Static
857
- /** STRETCH_NONE */
858
- Image.STRETCH_NONE = 0;
859
- /** STRETCH_FILL */
860
- Image.STRETCH_FILL = 1;
861
- /** STRETCH_UNIFORM */
862
- Image.STRETCH_UNIFORM = 2;
863
- /** STRETCH_EXTEND */
864
- Image.STRETCH_EXTEND = 3;
865
- /** NINE_PATCH */
866
- Image.STRETCH_NINE_PATCH = 4;
867
- __decorate([
868
- serialize()
869
- ], Image.prototype, "detectPointerOnOpaqueOnly", null);
870
- __decorate([
871
- serialize()
872
- ], Image.prototype, "sliceLeft", null);
873
- __decorate([
874
- serialize()
875
- ], Image.prototype, "sliceRight", null);
876
- __decorate([
877
- serialize()
878
- ], Image.prototype, "sliceTop", null);
879
- __decorate([
880
- serialize()
881
- ], Image.prototype, "sliceBottom", null);
882
- __decorate([
883
- serialize()
884
- ], Image.prototype, "sourceLeft", null);
885
- __decorate([
886
- serialize()
887
- ], Image.prototype, "sourceTop", null);
888
- __decorate([
889
- serialize()
890
- ], Image.prototype, "sourceWidth", null);
891
- __decorate([
892
- serialize()
893
- ], Image.prototype, "sourceHeight", null);
894
- __decorate([
895
- serialize()
896
- ], Image.prototype, "populateNinePatchSlicesFromImage", null);
897
- __decorate([
898
- serialize()
899
- ], Image.prototype, "autoScale", null);
900
- __decorate([
901
- serialize()
902
- ], Image.prototype, "stretch", null);
903
- __decorate([
904
- serialize()
905
- ], Image.prototype, "source", null);
906
- __decorate([
907
- serialize()
908
- ], Image.prototype, "cellWidth", null);
909
- __decorate([
910
- serialize()
911
- ], Image.prototype, "cellHeight", null);
912
- __decorate([
913
- serialize()
914
- ], Image.prototype, "cellId", null);
828
+ _renderNinePatch(context, sx, sy, sw, sh) {
829
+ const idealRatio = this.host.idealRatio;
830
+ const leftWidth = this._sliceLeft;
831
+ const topHeight = this._sliceTop;
832
+ const bottomHeight = sh - this._sliceBottom;
833
+ const rightWidth = sw - this._sliceRight;
834
+ const centerWidth = this._sliceRight - this._sliceLeft;
835
+ const centerHeight = this._sliceBottom - this._sliceTop;
836
+ const leftWidthAdjusted = Math.round(leftWidth * idealRatio);
837
+ const topHeightAdjusted = Math.round(topHeight * idealRatio);
838
+ const bottomHeightAdjusted = Math.round(bottomHeight * idealRatio);
839
+ const rightWidthAdjusted = Math.round(rightWidth * idealRatio);
840
+ const targetCenterWidth = Math.round(this._currentMeasure.width) - rightWidthAdjusted - leftWidthAdjusted + 2;
841
+ const targetCenterHeight = Math.round(this._currentMeasure.height) - bottomHeightAdjusted - topHeightAdjusted + 2;
842
+ const centerLeftOffset = Math.round(this._currentMeasure.left) + leftWidthAdjusted - 1;
843
+ const centerTopOffset = Math.round(this._currentMeasure.top) + topHeightAdjusted - 1;
844
+ const rightOffset = Math.round(this._currentMeasure.left + this._currentMeasure.width) - rightWidthAdjusted;
845
+ const bottomOffset = Math.round(this._currentMeasure.top + this._currentMeasure.height) - bottomHeightAdjusted;
846
+ //Top Left
847
+ this._drawImage(context, sx, sy, leftWidth, topHeight, this._currentMeasure.left, this._currentMeasure.top, leftWidthAdjusted, topHeightAdjusted);
848
+ //Top
849
+ this._drawImage(context, sx + this._sliceLeft, sy, centerWidth, topHeight, centerLeftOffset + 1, this._currentMeasure.top, targetCenterWidth - 2, topHeightAdjusted);
850
+ //Top Right
851
+ this._drawImage(context, sx + this._sliceRight, sy, rightWidth, topHeight, rightOffset, this._currentMeasure.top, rightWidthAdjusted, topHeightAdjusted);
852
+ //Left
853
+ this._drawImage(context, sx, sy + this._sliceTop, leftWidth, centerHeight, this._currentMeasure.left, centerTopOffset + 1, leftWidthAdjusted, targetCenterHeight - 2);
854
+ // Center
855
+ this._drawImage(context, sx + this._sliceLeft, sy + this._sliceTop, centerWidth, centerHeight, centerLeftOffset + 1, centerTopOffset + 1, targetCenterWidth - 2, targetCenterHeight - 2);
856
+ //Right
857
+ this._drawImage(context, sx + this._sliceRight, sy + this._sliceTop, rightWidth, centerHeight, rightOffset, centerTopOffset + 1, rightWidthAdjusted, targetCenterHeight - 2);
858
+ //Bottom Left
859
+ this._drawImage(context, sx, sy + this._sliceBottom, leftWidth, bottomHeight, this._currentMeasure.left, bottomOffset, leftWidthAdjusted, bottomHeightAdjusted);
860
+ //Bottom
861
+ this._drawImage(context, sx + this.sliceLeft, sy + this._sliceBottom, centerWidth, bottomHeight, centerLeftOffset + 1, bottomOffset, targetCenterWidth - 2, bottomHeightAdjusted);
862
+ //Bottom Right
863
+ this._drawImage(context, sx + this._sliceRight, sy + this._sliceBottom, rightWidth, bottomHeight, rightOffset, bottomOffset, rightWidthAdjusted, bottomHeightAdjusted);
864
+ }
865
+ dispose() {
866
+ super.dispose();
867
+ this.onImageLoadedObservable.clear();
868
+ this.onSVGAttributesComputedObservable.clear();
869
+ this._removeCacheUsage(this._source);
870
+ }
871
+ },
872
+ (() => {
873
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
874
+ _get_detectPointerOnOpaqueOnly_decorators = [serialize()];
875
+ _get_sliceLeft_decorators = [serialize()];
876
+ _get_sliceRight_decorators = [serialize()];
877
+ _get_sliceTop_decorators = [serialize()];
878
+ _get_sliceBottom_decorators = [serialize()];
879
+ _get_sourceLeft_decorators = [serialize()];
880
+ _get_sourceTop_decorators = [serialize()];
881
+ _get_sourceWidth_decorators = [serialize()];
882
+ _get_sourceHeight_decorators = [serialize()];
883
+ _get_populateNinePatchSlicesFromImage_decorators = [serialize()];
884
+ _get_autoScale_decorators = [serialize()];
885
+ _get_stretch_decorators = [serialize()];
886
+ _get_source_decorators = [serialize()];
887
+ _get_cellWidth_decorators = [serialize()];
888
+ _get_cellHeight_decorators = [serialize()];
889
+ _get_cellId_decorators = [serialize()];
890
+ __esDecorate(_a, null, _get_detectPointerOnOpaqueOnly_decorators, { kind: "getter", name: "detectPointerOnOpaqueOnly", static: false, private: false, access: { has: obj => "detectPointerOnOpaqueOnly" in obj, get: obj => obj.detectPointerOnOpaqueOnly }, metadata: _metadata }, null, _instanceExtraInitializers);
891
+ __esDecorate(_a, null, _get_sliceLeft_decorators, { kind: "getter", name: "sliceLeft", static: false, private: false, access: { has: obj => "sliceLeft" in obj, get: obj => obj.sliceLeft }, metadata: _metadata }, null, _instanceExtraInitializers);
892
+ __esDecorate(_a, null, _get_sliceRight_decorators, { kind: "getter", name: "sliceRight", static: false, private: false, access: { has: obj => "sliceRight" in obj, get: obj => obj.sliceRight }, metadata: _metadata }, null, _instanceExtraInitializers);
893
+ __esDecorate(_a, null, _get_sliceTop_decorators, { kind: "getter", name: "sliceTop", static: false, private: false, access: { has: obj => "sliceTop" in obj, get: obj => obj.sliceTop }, metadata: _metadata }, null, _instanceExtraInitializers);
894
+ __esDecorate(_a, null, _get_sliceBottom_decorators, { kind: "getter", name: "sliceBottom", static: false, private: false, access: { has: obj => "sliceBottom" in obj, get: obj => obj.sliceBottom }, metadata: _metadata }, null, _instanceExtraInitializers);
895
+ __esDecorate(_a, null, _get_sourceLeft_decorators, { kind: "getter", name: "sourceLeft", static: false, private: false, access: { has: obj => "sourceLeft" in obj, get: obj => obj.sourceLeft }, metadata: _metadata }, null, _instanceExtraInitializers);
896
+ __esDecorate(_a, null, _get_sourceTop_decorators, { kind: "getter", name: "sourceTop", static: false, private: false, access: { has: obj => "sourceTop" in obj, get: obj => obj.sourceTop }, metadata: _metadata }, null, _instanceExtraInitializers);
897
+ __esDecorate(_a, null, _get_sourceWidth_decorators, { kind: "getter", name: "sourceWidth", static: false, private: false, access: { has: obj => "sourceWidth" in obj, get: obj => obj.sourceWidth }, metadata: _metadata }, null, _instanceExtraInitializers);
898
+ __esDecorate(_a, null, _get_sourceHeight_decorators, { kind: "getter", name: "sourceHeight", static: false, private: false, access: { has: obj => "sourceHeight" in obj, get: obj => obj.sourceHeight }, metadata: _metadata }, null, _instanceExtraInitializers);
899
+ __esDecorate(_a, null, _get_populateNinePatchSlicesFromImage_decorators, { kind: "getter", name: "populateNinePatchSlicesFromImage", static: false, private: false, access: { has: obj => "populateNinePatchSlicesFromImage" in obj, get: obj => obj.populateNinePatchSlicesFromImage }, metadata: _metadata }, null, _instanceExtraInitializers);
900
+ __esDecorate(_a, null, _get_autoScale_decorators, { kind: "getter", name: "autoScale", static: false, private: false, access: { has: obj => "autoScale" in obj, get: obj => obj.autoScale }, metadata: _metadata }, null, _instanceExtraInitializers);
901
+ __esDecorate(_a, null, _get_stretch_decorators, { kind: "getter", name: "stretch", static: false, private: false, access: { has: obj => "stretch" in obj, get: obj => obj.stretch }, metadata: _metadata }, null, _instanceExtraInitializers);
902
+ __esDecorate(_a, null, _get_source_decorators, { kind: "getter", name: "source", static: false, private: false, access: { has: obj => "source" in obj, get: obj => obj.source }, metadata: _metadata }, null, _instanceExtraInitializers);
903
+ __esDecorate(_a, null, _get_cellWidth_decorators, { kind: "getter", name: "cellWidth", static: false, private: false, access: { has: obj => "cellWidth" in obj, get: obj => obj.cellWidth }, metadata: _metadata }, null, _instanceExtraInitializers);
904
+ __esDecorate(_a, null, _get_cellHeight_decorators, { kind: "getter", name: "cellHeight", static: false, private: false, access: { has: obj => "cellHeight" in obj, get: obj => obj.cellHeight }, metadata: _metadata }, null, _instanceExtraInitializers);
905
+ __esDecorate(_a, null, _get_cellId_decorators, { kind: "getter", name: "cellId", static: false, private: false, access: { has: obj => "cellId" in obj, get: obj => obj.cellId }, metadata: _metadata }, null, _instanceExtraInitializers);
906
+ if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
907
+ })(),
908
+ /**
909
+ * Cache of images to avoid loading the same image multiple times
910
+ */
911
+ _a.SourceImgCache = new Map(),
912
+ // Static
913
+ /** STRETCH_NONE */
914
+ _a.STRETCH_NONE = 0,
915
+ /** STRETCH_FILL */
916
+ _a.STRETCH_FILL = 1,
917
+ /** STRETCH_UNIFORM */
918
+ _a.STRETCH_UNIFORM = 2,
919
+ /** STRETCH_EXTEND */
920
+ _a.STRETCH_EXTEND = 3,
921
+ /** NINE_PATCH */
922
+ _a.STRETCH_NINE_PATCH = 4,
923
+ _a;
924
+ })();
925
+ export { Image };
915
926
  let _Registered = false;
916
927
  /**
917
928
  * Registers the Image class with the type store for serialization support.