@babylonjs/core 7.51.2 → 7.52.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 (195) hide show
  1. package/Audio/Interfaces/IAudioEngineOptions.d.ts +2 -0
  2. package/Audio/Interfaces/IAudioEngineOptions.js.map +1 -1
  3. package/AudioV2/abstractAudio/abstractAudioBus.d.ts +22 -0
  4. package/AudioV2/abstractAudio/abstractAudioBus.js +35 -0
  5. package/AudioV2/abstractAudio/abstractAudioBus.js.map +1 -0
  6. package/AudioV2/abstractAudio/abstractAudioNode.d.ts +99 -0
  7. package/AudioV2/abstractAudio/abstractAudioNode.js +149 -0
  8. package/AudioV2/abstractAudio/abstractAudioNode.js.map +1 -0
  9. package/AudioV2/abstractAudio/abstractSound.d.ts +152 -0
  10. package/AudioV2/abstractAudio/abstractSound.js +202 -0
  11. package/AudioV2/abstractAudio/abstractSound.js.map +1 -0
  12. package/AudioV2/abstractAudio/abstractSoundInstance.d.ts +34 -0
  13. package/AudioV2/abstractAudio/abstractSoundInstance.js +35 -0
  14. package/AudioV2/abstractAudio/abstractSoundInstance.js.map +1 -0
  15. package/AudioV2/abstractAudio/audioBus.d.ts +48 -0
  16. package/AudioV2/abstractAudio/audioBus.js +53 -0
  17. package/AudioV2/abstractAudio/audioBus.js.map +1 -0
  18. package/AudioV2/abstractAudio/audioEngineV2.d.ts +193 -0
  19. package/AudioV2/abstractAudio/audioEngineV2.js +155 -0
  20. package/AudioV2/abstractAudio/audioEngineV2.js.map +1 -0
  21. package/AudioV2/abstractAudio/index.d.ts +10 -0
  22. package/AudioV2/abstractAudio/index.js +12 -0
  23. package/AudioV2/abstractAudio/index.js.map +1 -0
  24. package/AudioV2/abstractAudio/mainAudioBus.d.ts +22 -0
  25. package/AudioV2/abstractAudio/mainAudioBus.js +18 -0
  26. package/AudioV2/abstractAudio/mainAudioBus.js.map +1 -0
  27. package/AudioV2/abstractAudio/mainAudioOut.d.ts +13 -0
  28. package/AudioV2/abstractAudio/mainAudioOut.js +15 -0
  29. package/AudioV2/abstractAudio/mainAudioOut.js.map +1 -0
  30. package/AudioV2/abstractAudio/staticSound.d.ts +134 -0
  31. package/AudioV2/abstractAudio/staticSound.js +113 -0
  32. package/AudioV2/abstractAudio/staticSound.js.map +1 -0
  33. package/AudioV2/abstractAudio/staticSoundBuffer.d.ts +46 -0
  34. package/AudioV2/abstractAudio/staticSoundBuffer.js +17 -0
  35. package/AudioV2/abstractAudio/staticSoundBuffer.js.map +1 -0
  36. package/AudioV2/abstractAudio/staticSoundInstance.d.ts +15 -0
  37. package/AudioV2/abstractAudio/staticSoundInstance.js +5 -0
  38. package/AudioV2/abstractAudio/staticSoundInstance.js.map +1 -0
  39. package/AudioV2/abstractAudio/streamingSound.d.ts +77 -0
  40. package/AudioV2/abstractAudio/streamingSound.js +109 -0
  41. package/AudioV2/abstractAudio/streamingSound.js.map +1 -0
  42. package/AudioV2/abstractAudio/streamingSoundInstance.d.ts +25 -0
  43. package/AudioV2/abstractAudio/streamingSoundInstance.js +29 -0
  44. package/AudioV2/abstractAudio/streamingSoundInstance.js.map +1 -0
  45. package/AudioV2/abstractAudio/subNodes/abstractAudioSubGraph.d.ts +53 -0
  46. package/AudioV2/abstractAudio/subNodes/abstractAudioSubGraph.js +97 -0
  47. package/AudioV2/abstractAudio/subNodes/abstractAudioSubGraph.js.map +1 -0
  48. package/AudioV2/abstractAudio/subNodes/abstractAudioSubNode.d.ts +13 -0
  49. package/AudioV2/abstractAudio/subNodes/abstractAudioSubNode.js +33 -0
  50. package/AudioV2/abstractAudio/subNodes/abstractAudioSubNode.js.map +1 -0
  51. package/AudioV2/abstractAudio/subNodes/audioSubNode.d.ts +6 -0
  52. package/AudioV2/abstractAudio/subNodes/audioSubNode.js +8 -0
  53. package/AudioV2/abstractAudio/subNodes/audioSubNode.js.map +1 -0
  54. package/AudioV2/abstractAudio/subNodes/spatialAudioSubNode.d.ts +31 -0
  55. package/AudioV2/abstractAudio/subNodes/spatialAudioSubNode.js +46 -0
  56. package/AudioV2/abstractAudio/subNodes/spatialAudioSubNode.js.map +1 -0
  57. package/AudioV2/abstractAudio/subNodes/stereoAudioSubNode.d.ts +19 -0
  58. package/AudioV2/abstractAudio/subNodes/stereoAudioSubNode.js +27 -0
  59. package/AudioV2/abstractAudio/subNodes/stereoAudioSubNode.js.map +1 -0
  60. package/AudioV2/abstractAudio/subNodes/volumeAudioSubNode.d.ts +28 -0
  61. package/AudioV2/abstractAudio/subNodes/volumeAudioSubNode.js +24 -0
  62. package/AudioV2/abstractAudio/subNodes/volumeAudioSubNode.js.map +1 -0
  63. package/AudioV2/abstractAudio/subProperties/abstractSpatialAudio.d.ts +187 -0
  64. package/AudioV2/abstractAudio/subProperties/abstractSpatialAudio.js +41 -0
  65. package/AudioV2/abstractAudio/subProperties/abstractSpatialAudio.js.map +1 -0
  66. package/AudioV2/abstractAudio/subProperties/abstractSpatialAudioListener.d.ts +59 -0
  67. package/AudioV2/abstractAudio/subProperties/abstractSpatialAudioListener.js +21 -0
  68. package/AudioV2/abstractAudio/subProperties/abstractSpatialAudioListener.js.map +1 -0
  69. package/AudioV2/abstractAudio/subProperties/abstractStereoAudio.d.ts +38 -0
  70. package/AudioV2/abstractAudio/subProperties/abstractStereoAudio.js +18 -0
  71. package/AudioV2/abstractAudio/subProperties/abstractStereoAudio.js.map +1 -0
  72. package/AudioV2/abstractAudio/subProperties/index.d.ts +3 -0
  73. package/AudioV2/abstractAudio/subProperties/index.js +4 -0
  74. package/AudioV2/abstractAudio/subProperties/index.js.map +1 -0
  75. package/AudioV2/abstractAudio/subProperties/spatialAudio.d.ts +49 -0
  76. package/AudioV2/abstractAudio/subProperties/spatialAudio.js +129 -0
  77. package/AudioV2/abstractAudio/subProperties/spatialAudio.js.map +1 -0
  78. package/AudioV2/abstractAudio/subProperties/spatialAudioListener.d.ts +9 -0
  79. package/AudioV2/abstractAudio/subProperties/spatialAudioListener.js +22 -0
  80. package/AudioV2/abstractAudio/subProperties/spatialAudioListener.js.map +1 -0
  81. package/AudioV2/abstractAudio/subProperties/stereoAudio.d.ts +11 -0
  82. package/AudioV2/abstractAudio/subProperties/stereoAudio.js +18 -0
  83. package/AudioV2/abstractAudio/subProperties/stereoAudio.js.map +1 -0
  84. package/AudioV2/audioUtils.d.ts +3 -0
  85. package/AudioV2/audioUtils.js +6 -0
  86. package/AudioV2/audioUtils.js.map +1 -0
  87. package/AudioV2/index.d.ts +3 -0
  88. package/AudioV2/index.js +5 -0
  89. package/AudioV2/index.js.map +1 -0
  90. package/AudioV2/soundState.d.ts +29 -0
  91. package/AudioV2/soundState.js +31 -0
  92. package/AudioV2/soundState.js.map +1 -0
  93. package/AudioV2/webAudio/index.d.ts +5 -0
  94. package/AudioV2/webAudio/index.js +6 -0
  95. package/AudioV2/webAudio/index.js.map +1 -0
  96. package/AudioV2/webAudio/subNodes/spatialWebAudioSubNode.d.ts +59 -0
  97. package/AudioV2/webAudio/subNodes/spatialWebAudioSubNode.js +156 -0
  98. package/AudioV2/webAudio/subNodes/spatialWebAudioSubNode.js.map +1 -0
  99. package/AudioV2/webAudio/subNodes/stereoWebAudioSubNode.d.ts +24 -0
  100. package/AudioV2/webAudio/subNodes/stereoWebAudioSubNode.js +55 -0
  101. package/AudioV2/webAudio/subNodes/stereoWebAudioSubNode.js.map +1 -0
  102. package/AudioV2/webAudio/subNodes/volumeWebAudioSubNode.d.ts +24 -0
  103. package/AudioV2/webAudio/subNodes/volumeWebAudioSubNode.js +55 -0
  104. package/AudioV2/webAudio/subNodes/volumeWebAudioSubNode.js.map +1 -0
  105. package/AudioV2/webAudio/subNodes/webAudioBaseSubGraph.d.ts +26 -0
  106. package/AudioV2/webAudio/subNodes/webAudioBaseSubGraph.js +54 -0
  107. package/AudioV2/webAudio/subNodes/webAudioBaseSubGraph.js.map +1 -0
  108. package/AudioV2/webAudio/subNodes/webAudioBusAndSoundSubGraph.d.ts +21 -0
  109. package/AudioV2/webAudio/subNodes/webAudioBusAndSoundSubGraph.js +112 -0
  110. package/AudioV2/webAudio/subNodes/webAudioBusAndSoundSubGraph.js.map +1 -0
  111. package/AudioV2/webAudio/subProperties/spatialWebAudio.d.ts +10 -0
  112. package/AudioV2/webAudio/subProperties/spatialWebAudio.js +26 -0
  113. package/AudioV2/webAudio/subProperties/spatialWebAudio.js.map +1 -0
  114. package/AudioV2/webAudio/subProperties/spatialWebAudioListener.d.ts +4 -0
  115. package/AudioV2/webAudio/subProperties/spatialWebAudioListener.js +108 -0
  116. package/AudioV2/webAudio/subProperties/spatialWebAudioListener.js.map +1 -0
  117. package/AudioV2/webAudio/webAudioBus.d.ts +35 -0
  118. package/AudioV2/webAudio/webAudioBus.js +63 -0
  119. package/AudioV2/webAudio/webAudioBus.js.map +1 -0
  120. package/AudioV2/webAudio/webAudioEngine.d.ts +110 -0
  121. package/AudioV2/webAudio/webAudioEngine.js +227 -0
  122. package/AudioV2/webAudio/webAudioEngine.js.map +1 -0
  123. package/AudioV2/webAudio/webAudioMainBus.d.ts +29 -0
  124. package/AudioV2/webAudio/webAudioMainBus.js +64 -0
  125. package/AudioV2/webAudio/webAudioMainBus.js.map +1 -0
  126. package/AudioV2/webAudio/webAudioMainOut.d.ts +20 -0
  127. package/AudioV2/webAudio/webAudioMainOut.js +35 -0
  128. package/AudioV2/webAudio/webAudioMainOut.js.map +1 -0
  129. package/AudioV2/webAudio/webAudioNode.d.ts +24 -0
  130. package/AudioV2/webAudio/webAudioNode.js +2 -0
  131. package/AudioV2/webAudio/webAudioNode.js.map +1 -0
  132. package/AudioV2/webAudio/webAudioStaticSound.d.ts +106 -0
  133. package/AudioV2/webAudio/webAudioStaticSound.js +368 -0
  134. package/AudioV2/webAudio/webAudioStaticSound.js.map +1 -0
  135. package/AudioV2/webAudio/webAudioStreamingSound.d.ts +94 -0
  136. package/AudioV2/webAudio/webAudioStreamingSound.js +358 -0
  137. package/AudioV2/webAudio/webAudioStreamingSound.js.map +1 -0
  138. package/Engines/ICanvas.d.ts +96 -1
  139. package/Engines/ICanvas.js.map +1 -1
  140. package/Engines/Native/nativeInterfaces.d.ts +7 -1
  141. package/Engines/Native/nativeInterfaces.js.map +1 -1
  142. package/Engines/WebGPU/webgpuTextureManager.js +3 -3
  143. package/Engines/WebGPU/webgpuTextureManager.js.map +1 -1
  144. package/Engines/abstractEngine.d.ts +11 -1
  145. package/Engines/abstractEngine.js +12 -2
  146. package/Engines/abstractEngine.js.map +1 -1
  147. package/Engines/engine.common.js +0 -4
  148. package/Engines/engine.common.js.map +1 -1
  149. package/Engines/engine.d.ts +0 -1
  150. package/Engines/engine.js +0 -1
  151. package/Engines/engine.js.map +1 -1
  152. package/Engines/nativeEngine.d.ts +7 -1
  153. package/Engines/nativeEngine.js +12 -0
  154. package/Engines/nativeEngine.js.map +1 -1
  155. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.d.ts +5 -1
  156. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.js +16 -5
  157. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.js.map +1 -1
  158. package/Layers/effectLayer.d.ts +5 -0
  159. package/Layers/effectLayer.js +7 -0
  160. package/Layers/effectLayer.js.map +1 -1
  161. package/Lights/Shadows/cascadedShadowGenerator.js +33 -20
  162. package/Lights/Shadows/cascadedShadowGenerator.js.map +1 -1
  163. package/Loading/sceneLoader.d.ts +25 -11
  164. package/Loading/sceneLoader.js +28 -11
  165. package/Loading/sceneLoader.js.map +1 -1
  166. package/Materials/Textures/hdrCubeTexture.js +4 -1
  167. package/Materials/Textures/hdrCubeTexture.js.map +1 -1
  168. package/Materials/material.js +1 -0
  169. package/Materials/material.js.map +1 -1
  170. package/Meshes/csg2.d.ts +2 -2
  171. package/Meshes/csg2.js +2 -2
  172. package/Meshes/csg2.js.map +1 -1
  173. package/Meshes/geometry.js +7 -15
  174. package/Meshes/geometry.js.map +1 -1
  175. package/Meshes/instancedMesh.d.ts +5 -0
  176. package/Meshes/instancedMesh.js +6 -0
  177. package/Meshes/instancedMesh.js.map +1 -1
  178. package/Misc/environmentTextureTools.js +2 -2
  179. package/Misc/environmentTextureTools.js.map +1 -1
  180. package/Rendering/IBLShadows/iblShadowsPluginMaterial.js +26 -18
  181. package/Rendering/IBLShadows/iblShadowsPluginMaterial.js.map +1 -1
  182. package/Shaders/ShadersInclude/shadowMapFragment.js +1 -0
  183. package/Shaders/ShadersInclude/shadowMapFragment.js.map +1 -1
  184. package/Shaders/iblCdfDebug.fragment.js +2 -2
  185. package/Shaders/iblCdfDebug.fragment.js.map +1 -1
  186. package/ShadersWGSL/ShadersInclude/shadowMapFragment.js +1 -0
  187. package/ShadersWGSL/ShadersInclude/shadowMapFragment.js.map +1 -1
  188. package/ShadersWGSL/iblCdfDebug.fragment.js +2 -2
  189. package/ShadersWGSL/iblCdfDebug.fragment.js.map +1 -1
  190. package/index.d.ts +1 -0
  191. package/index.js +1 -0
  192. package/index.js.map +1 -1
  193. package/package.json +1 -1
  194. package/scene.js +8 -0
  195. package/scene.js.map +1 -1
@@ -0,0 +1,358 @@
1
+ import { Logger } from "../../Misc/logger.js";
2
+ import { Tools } from "../../Misc/tools.js";
3
+ import { StreamingSound } from "../abstractAudio/streamingSound.js";
4
+ import { _StreamingSoundInstance } from "../abstractAudio/streamingSoundInstance.js";
5
+ import { _StereoAudio } from "../abstractAudio/subProperties/stereoAudio.js";
6
+ import { _CleanUrl } from "../audioUtils.js";
7
+ import { _WebAudioBusAndSoundSubGraph } from "./subNodes/webAudioBusAndSoundSubGraph.js";
8
+ import { _SpatialWebAudio } from "./subProperties/spatialWebAudio.js";
9
+ /** @internal */
10
+ export class _WebAudioStreamingSound extends StreamingSound {
11
+ /** @internal */
12
+ constructor(name, engine, options) {
13
+ super(name, engine, options);
14
+ this._spatial = null;
15
+ this._stereo = null;
16
+ this._options = {
17
+ autoplay: options.autoplay ?? false,
18
+ loop: options.loop ?? false,
19
+ maxInstances: options.maxInstances ?? Infinity,
20
+ preloadCount: options.preloadCount ?? 1,
21
+ startOffset: options.startOffset ?? 0,
22
+ };
23
+ this._subGraph = new _WebAudioStreamingSound._SubGraph(this);
24
+ }
25
+ /** @internal */
26
+ async init(source, options) {
27
+ const audioContext = this.engine.audioContext;
28
+ if (!(audioContext instanceof AudioContext)) {
29
+ throw new Error("Unsupported audio context type.");
30
+ }
31
+ this.audioContext = audioContext;
32
+ this.source = source;
33
+ if (options.outBus) {
34
+ this.outBus = options.outBus;
35
+ }
36
+ else {
37
+ await this.engine.isReadyPromise;
38
+ this.outBus = this.engine.defaultMainBus;
39
+ }
40
+ await this._subGraph.init(options);
41
+ if (this.preloadCount) {
42
+ await this.preloadInstances(this.preloadCount);
43
+ }
44
+ if (options.autoplay) {
45
+ this.play(options);
46
+ }
47
+ this.engine.addNode(this);
48
+ }
49
+ /** @internal */
50
+ get inNode() {
51
+ return this._subGraph.inNode;
52
+ }
53
+ /** @internal */
54
+ get outNode() {
55
+ return this._subGraph.outNode;
56
+ }
57
+ /** @internal */
58
+ get spatial() {
59
+ return this._spatial ?? (this._spatial = new _SpatialWebAudio(this._subGraph, this._spatialAutoUpdate));
60
+ }
61
+ /** @internal */
62
+ get stereo() {
63
+ return this._stereo ?? (this._stereo = new _StereoAudio(this._subGraph));
64
+ }
65
+ /** @internal */
66
+ dispose() {
67
+ super.dispose();
68
+ this._spatial = null;
69
+ this._stereo = null;
70
+ this._subGraph.dispose();
71
+ this.engine.removeNode(this);
72
+ }
73
+ /** @internal */
74
+ getClassName() {
75
+ return "_WebAudioStreamingSound";
76
+ }
77
+ _createInstance() {
78
+ return new _WebAudioStreamingSoundInstance(this, this._options);
79
+ }
80
+ _connect(node) {
81
+ const connected = super._connect(node);
82
+ if (!connected) {
83
+ return false;
84
+ }
85
+ // If the wrapped node is not available now, it will be connected later by the subgraph.
86
+ if (node.inNode) {
87
+ this.outNode?.connect(node.inNode);
88
+ }
89
+ return true;
90
+ }
91
+ _disconnect(node) {
92
+ const disconnected = super._disconnect(node);
93
+ if (!disconnected) {
94
+ return false;
95
+ }
96
+ if (node.inNode) {
97
+ this.outNode?.disconnect(node.inNode);
98
+ }
99
+ return true;
100
+ }
101
+ }
102
+ _WebAudioStreamingSound._SubGraph = class extends _WebAudioBusAndSoundSubGraph {
103
+ get _downstreamNodes() {
104
+ return this._owner._downstreamNodes ?? null;
105
+ }
106
+ get _upstreamNodes() {
107
+ return this._owner._upstreamNodes ?? null;
108
+ }
109
+ };
110
+ /** @internal */
111
+ class _WebAudioStreamingSoundInstance extends _StreamingSoundInstance {
112
+ constructor(sound, options) {
113
+ super(sound);
114
+ this._currentTimeChangedWhilePaused = false;
115
+ this._enginePlayTime = Infinity;
116
+ this._enginePauseTime = 0;
117
+ this._isReady = false;
118
+ this._isReadyPromise = new Promise((resolve, reject) => {
119
+ this._resolveIsReadyPromise = resolve;
120
+ this._rejectIsReadyPromise = reject;
121
+ });
122
+ this._onCanPlayThrough = () => {
123
+ this._isReady = true;
124
+ this._resolveIsReadyPromise(this._mediaElement);
125
+ this.onReadyObservable.notifyObservers(this);
126
+ };
127
+ this._onEnded = () => {
128
+ this.onEndedObservable.notifyObservers(this);
129
+ this.dispose();
130
+ };
131
+ this._onError = (reason) => {
132
+ this._setState(4 /* SoundState.FailedToStart */);
133
+ this.onErrorObservable.notifyObservers(reason);
134
+ this._rejectIsReadyPromise(reason);
135
+ this.dispose();
136
+ };
137
+ this._onEngineStateChanged = () => {
138
+ if (this.engine.state !== "running") {
139
+ return;
140
+ }
141
+ if (this._options.loop && this.state === 2 /* SoundState.Starting */) {
142
+ this.play();
143
+ }
144
+ this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);
145
+ };
146
+ this._onUserGesture = () => {
147
+ this.play();
148
+ };
149
+ this._options = options;
150
+ this._volumeNode = new GainNode(sound.audioContext);
151
+ if (typeof sound.source === "string") {
152
+ this._initFromUrl(sound.source);
153
+ }
154
+ else if (Array.isArray(sound.source)) {
155
+ this._initFromUrls(sound.source);
156
+ }
157
+ else if (sound.source instanceof HTMLMediaElement) {
158
+ this._initFromMediaElement(sound.source);
159
+ }
160
+ }
161
+ /** @internal */
162
+ get currentTime() {
163
+ if (this._state === 1 /* SoundState.Stopped */) {
164
+ return 0;
165
+ }
166
+ const timeSinceLastStart = this._state === 5 /* SoundState.Paused */ ? 0 : this.engine.currentTime - this._enginePlayTime;
167
+ return this._enginePauseTime + timeSinceLastStart + this._options.startOffset;
168
+ }
169
+ set currentTime(value) {
170
+ const restart = this._state === 2 /* SoundState.Starting */ || this._state === 3 /* SoundState.Started */;
171
+ if (restart) {
172
+ this._mediaElement.pause();
173
+ this._setState(1 /* SoundState.Stopped */);
174
+ }
175
+ this._options.startOffset = value;
176
+ if (restart) {
177
+ this.play({ startOffset: value });
178
+ }
179
+ else if (this._state === 5 /* SoundState.Paused */) {
180
+ this._currentTimeChangedWhilePaused = true;
181
+ }
182
+ }
183
+ get outNode() {
184
+ return this._volumeNode;
185
+ }
186
+ /** @internal */
187
+ get startTime() {
188
+ if (this._state === 1 /* SoundState.Stopped */) {
189
+ return 0;
190
+ }
191
+ return this._enginePlayTime;
192
+ }
193
+ /** @internal */
194
+ dispose() {
195
+ super.dispose();
196
+ this.stop();
197
+ this._sourceNode?.disconnect(this._volumeNode);
198
+ this._sourceNode = null;
199
+ this._mediaElement.removeEventListener("error", this._onError);
200
+ this._mediaElement.removeEventListener("ended", this._onEnded);
201
+ this._mediaElement.removeEventListener("canplaythrough", this._onCanPlayThrough);
202
+ for (const source of Array.from(this._mediaElement.children)) {
203
+ this._mediaElement.removeChild(source);
204
+ }
205
+ this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);
206
+ this.engine.userGestureObservable.removeCallback(this._onUserGesture);
207
+ }
208
+ /** @internal */
209
+ play(options = {}) {
210
+ if (this._state === 3 /* SoundState.Started */) {
211
+ return;
212
+ }
213
+ if (options.loop !== undefined) {
214
+ this._options.loop = options.loop;
215
+ }
216
+ this._mediaElement.loop = this._options.loop;
217
+ let startOffset = options.startOffset;
218
+ if (this._currentTimeChangedWhilePaused) {
219
+ startOffset = this._options.startOffset;
220
+ this._currentTimeChangedWhilePaused = false;
221
+ }
222
+ else if (this._state === 5 /* SoundState.Paused */) {
223
+ startOffset = this.currentTime + this._options.startOffset;
224
+ }
225
+ if (startOffset && startOffset > 0) {
226
+ this._mediaElement.currentTime = startOffset;
227
+ }
228
+ this._volumeNode.gain.value = options.volume ?? 1;
229
+ this._play();
230
+ }
231
+ /** @internal */
232
+ pause() {
233
+ if (this._state !== 2 /* SoundState.Starting */ && this._state !== 3 /* SoundState.Started */) {
234
+ return;
235
+ }
236
+ this._setState(5 /* SoundState.Paused */);
237
+ this._enginePauseTime += this.engine.currentTime - this._enginePlayTime;
238
+ this._mediaElement.pause();
239
+ }
240
+ /** @internal */
241
+ resume() {
242
+ if (this._state === 5 /* SoundState.Paused */) {
243
+ this.play();
244
+ }
245
+ else if (this._currentTimeChangedWhilePaused) {
246
+ this.play();
247
+ }
248
+ }
249
+ /** @internal */
250
+ stop() {
251
+ if (this._state === 1 /* SoundState.Stopped */) {
252
+ return;
253
+ }
254
+ this._stop();
255
+ }
256
+ /** @internal */
257
+ getClassName() {
258
+ return "_WebAudioStreamingSoundInstance";
259
+ }
260
+ _connect(node) {
261
+ const connected = super._connect(node);
262
+ if (!connected) {
263
+ return false;
264
+ }
265
+ // If the wrapped node is not available now, it will be connected later by the sound's subgraph.
266
+ if (node instanceof _WebAudioStreamingSound && node.inNode) {
267
+ this.outNode?.connect(node.inNode);
268
+ }
269
+ return true;
270
+ }
271
+ _disconnect(node) {
272
+ const disconnected = super._disconnect(node);
273
+ if (!disconnected) {
274
+ return false;
275
+ }
276
+ if (node instanceof _WebAudioStreamingSound && node.inNode) {
277
+ this.outNode?.disconnect(node.inNode);
278
+ }
279
+ return true;
280
+ }
281
+ _initFromMediaElement(mediaElement) {
282
+ Tools.SetCorsBehavior(mediaElement.currentSrc, mediaElement);
283
+ mediaElement.controls = false;
284
+ mediaElement.loop = this._options.loop;
285
+ mediaElement.preload = "auto";
286
+ mediaElement.addEventListener("canplaythrough", this._onCanPlayThrough, { once: true });
287
+ mediaElement.addEventListener("ended", this._onEnded, { once: true });
288
+ mediaElement.addEventListener("error", this._onError, { once: true });
289
+ mediaElement.load();
290
+ this._sourceNode = new MediaElementAudioSourceNode(this._sound.audioContext, { mediaElement: mediaElement });
291
+ this._sourceNode.connect(this._volumeNode);
292
+ if (!this._connect(this._sound)) {
293
+ throw new Error("Connect failed");
294
+ }
295
+ this._mediaElement = mediaElement;
296
+ }
297
+ _initFromUrl(url) {
298
+ const audio = new Audio(_CleanUrl(url));
299
+ this._initFromMediaElement(audio);
300
+ }
301
+ _initFromUrls(urls) {
302
+ const audio = new Audio();
303
+ for (const url of urls) {
304
+ const source = document.createElement("source");
305
+ source.src = _CleanUrl(url);
306
+ audio.appendChild(source);
307
+ }
308
+ this._initFromMediaElement(audio);
309
+ }
310
+ _play() {
311
+ this._setState(2 /* SoundState.Starting */);
312
+ if (!this._isReady) {
313
+ this._playWhenReady();
314
+ return;
315
+ }
316
+ if (this._state !== 2 /* SoundState.Starting */) {
317
+ return;
318
+ }
319
+ if (this.engine.state === "running") {
320
+ const result = this._mediaElement.play();
321
+ this._enginePlayTime = this.engine.currentTime;
322
+ this._setState(3 /* SoundState.Started */);
323
+ // It's possible that the play() method fails on Safari, even if the audio engine's state is "running".
324
+ // This occurs when the audio context is paused by the system and resumed automatically by the audio engine
325
+ // without a user interaction (e.g. when the Vision Pro exits and reenters immersive mode).
326
+ result.catch(() => {
327
+ this._setState(4 /* SoundState.FailedToStart */);
328
+ if (this._options.loop) {
329
+ this.engine.userGestureObservable.addOnce(this._onUserGesture);
330
+ }
331
+ });
332
+ }
333
+ else if (this._options.loop) {
334
+ this.engine.stateChangedObservable.add(this._onEngineStateChanged);
335
+ }
336
+ else {
337
+ this.stop();
338
+ this._setState(4 /* SoundState.FailedToStart */);
339
+ }
340
+ }
341
+ _playWhenReady() {
342
+ this._isReadyPromise
343
+ .then(() => {
344
+ this._play();
345
+ })
346
+ .catch(() => {
347
+ Logger.Error("Streaming sound instance failed to play");
348
+ this._setState(4 /* SoundState.FailedToStart */);
349
+ });
350
+ }
351
+ _stop() {
352
+ this._mediaElement.pause();
353
+ this._setState(1 /* SoundState.Stopped */);
354
+ this._onEnded();
355
+ this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);
356
+ }
357
+ }
358
+ //# sourceMappingURL=webAudioStreamingSound.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webAudioStreamingSound.js","sourceRoot":"","sources":["../../../../../dev/core/src/AudioV2/webAudio/webAudioStreamingSound.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger } from \"../../Misc/logger\";\nimport { Tools } from \"../../Misc/tools\";\nimport type { Nullable } from \"../../types\";\nimport type { AbstractAudioNode } from \"../abstractAudio/abstractAudioNode\";\nimport type {} from \"../abstractAudio/abstractSound\";\nimport type { IStreamingSoundOptions, IStreamingSoundPlayOptions, IStreamingSoundStoredOptions } from \"../abstractAudio/streamingSound\";\nimport { StreamingSound } from \"../abstractAudio/streamingSound\";\nimport { _StreamingSoundInstance } from \"../abstractAudio/streamingSoundInstance\";\nimport type { _SpatialAudio } from \"../abstractAudio/subProperties/spatialAudio\";\nimport { _StereoAudio } from \"../abstractAudio/subProperties/stereoAudio\";\nimport { _CleanUrl } from \"../audioUtils\";\nimport { SoundState } from \"../soundState\";\nimport { _WebAudioBusAndSoundSubGraph } from \"./subNodes/webAudioBusAndSoundSubGraph\";\nimport { _SpatialWebAudio } from \"./subProperties/spatialWebAudio\";\nimport type { _WebAudioEngine } from \"./webAudioEngine\";\nimport type { IWebAudioInNode, IWebAudioOutNode, IWebAudioSuperNode } from \"./webAudioNode\";\n\ntype StreamingSoundSourceType = HTMLMediaElement | string | string[];\n\n/** @internal */\nexport class _WebAudioStreamingSound extends StreamingSound implements IWebAudioSuperNode {\n private _spatial: Nullable<_SpatialAudio> = null;\n private _stereo: Nullable<_StereoAudio> = null;\n\n protected override readonly _options: IStreamingSoundStoredOptions;\n protected _subGraph: _WebAudioBusAndSoundSubGraph;\n\n /** @internal */\n public audioContext: AudioContext;\n\n /** @internal */\n public override readonly engine: _WebAudioEngine;\n\n /** @internal */\n public source: StreamingSoundSourceType;\n\n /** @internal */\n public constructor(name: string, engine: _WebAudioEngine, options: Partial<IStreamingSoundOptions>) {\n super(name, engine, options);\n\n this._options = {\n autoplay: options.autoplay ?? false,\n loop: options.loop ?? false,\n maxInstances: options.maxInstances ?? Infinity,\n preloadCount: options.preloadCount ?? 1,\n startOffset: options.startOffset ?? 0,\n };\n\n this._subGraph = new _WebAudioStreamingSound._SubGraph(this);\n }\n\n /** @internal */\n public async init(source: StreamingSoundSourceType, options: Partial<IStreamingSoundOptions>): Promise<void> {\n const audioContext = this.engine.audioContext;\n\n if (!(audioContext instanceof AudioContext)) {\n throw new Error(\"Unsupported audio context type.\");\n }\n\n this.audioContext = audioContext;\n this.source = source;\n\n if (options.outBus) {\n this.outBus = options.outBus;\n } else {\n await this.engine.isReadyPromise;\n this.outBus = this.engine.defaultMainBus;\n }\n\n await this._subGraph.init(options);\n\n if (this.preloadCount) {\n await this.preloadInstances(this.preloadCount);\n }\n\n if (options.autoplay) {\n this.play(options);\n }\n\n this.engine.addNode(this);\n }\n\n /** @internal */\n public get inNode() {\n return this._subGraph.inNode;\n }\n\n /** @internal */\n public get outNode() {\n return this._subGraph.outNode;\n }\n\n /** @internal */\n public override get spatial(): _SpatialAudio {\n return this._spatial ?? (this._spatial = new _SpatialWebAudio(this._subGraph, this._spatialAutoUpdate));\n }\n\n /** @internal */\n public override get stereo(): _StereoAudio {\n return this._stereo ?? (this._stereo = new _StereoAudio(this._subGraph));\n }\n\n /** @internal */\n public override dispose(): void {\n super.dispose();\n\n this._spatial = null;\n this._stereo = null;\n\n this._subGraph.dispose();\n\n this.engine.removeNode(this);\n }\n\n /** @internal */\n public getClassName(): string {\n return \"_WebAudioStreamingSound\";\n }\n\n protected _createInstance(): _WebAudioStreamingSoundInstance {\n return new _WebAudioStreamingSoundInstance(this, this._options);\n }\n\n protected override _connect(node: IWebAudioInNode): boolean {\n const connected = super._connect(node);\n\n if (!connected) {\n return false;\n }\n\n // If the wrapped node is not available now, it will be connected later by the subgraph.\n if (node.inNode) {\n this.outNode?.connect(node.inNode);\n }\n\n return true;\n }\n\n protected override _disconnect(node: IWebAudioInNode): boolean {\n const disconnected = super._disconnect(node);\n\n if (!disconnected) {\n return false;\n }\n\n if (node.inNode) {\n this.outNode?.disconnect(node.inNode);\n }\n\n return true;\n }\n\n private static _SubGraph = class extends _WebAudioBusAndSoundSubGraph {\n protected override _owner: _WebAudioStreamingSound;\n\n protected get _downstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n return this._owner._downstreamNodes ?? null;\n }\n\n protected get _upstreamNodes(): Nullable<Set<AbstractAudioNode>> {\n return this._owner._upstreamNodes ?? null;\n }\n };\n}\n\n/** @internal */\nclass _WebAudioStreamingSoundInstance extends _StreamingSoundInstance implements IWebAudioOutNode {\n private _currentTimeChangedWhilePaused = false;\n private _enginePlayTime: number = Infinity;\n private _enginePauseTime: number = 0;\n private _isReady: boolean = false;\n private _isReadyPromise: Promise<HTMLMediaElement> = new Promise((resolve, reject) => {\n this._resolveIsReadyPromise = resolve;\n this._rejectIsReadyPromise = reject;\n });\n private _mediaElement: HTMLMediaElement;\n private _sourceNode: Nullable<MediaElementAudioSourceNode>;\n private _volumeNode: GainNode;\n\n protected override readonly _options: IStreamingSoundStoredOptions;\n protected override _sound: _WebAudioStreamingSound;\n\n /** @internal */\n public override readonly engine: _WebAudioEngine;\n\n public constructor(sound: _WebAudioStreamingSound, options: IStreamingSoundStoredOptions) {\n super(sound);\n\n this._options = options;\n this._volumeNode = new GainNode(sound.audioContext);\n\n if (typeof sound.source === \"string\") {\n this._initFromUrl(sound.source);\n } else if (Array.isArray(sound.source)) {\n this._initFromUrls(sound.source);\n } else if (sound.source instanceof HTMLMediaElement) {\n this._initFromMediaElement(sound.source);\n }\n }\n\n /** @internal */\n public get currentTime(): number {\n if (this._state === SoundState.Stopped) {\n return 0;\n }\n\n const timeSinceLastStart = this._state === SoundState.Paused ? 0 : this.engine.currentTime - this._enginePlayTime;\n return this._enginePauseTime + timeSinceLastStart + this._options.startOffset;\n }\n\n public set currentTime(value: number) {\n const restart = this._state === SoundState.Starting || this._state === SoundState.Started;\n\n if (restart) {\n this._mediaElement.pause();\n this._setState(SoundState.Stopped);\n }\n\n this._options.startOffset = value;\n\n if (restart) {\n this.play({ startOffset: value });\n } else if (this._state === SoundState.Paused) {\n this._currentTimeChangedWhilePaused = true;\n }\n }\n\n public get outNode(): Nullable<AudioNode> {\n return this._volumeNode;\n }\n\n /** @internal */\n public get startTime(): number {\n if (this._state === SoundState.Stopped) {\n return 0;\n }\n\n return this._enginePlayTime;\n }\n\n /** @internal */\n public override dispose(): void {\n super.dispose();\n\n this.stop();\n\n this._sourceNode?.disconnect(this._volumeNode);\n this._sourceNode = null;\n\n this._mediaElement.removeEventListener(\"error\", this._onError);\n this._mediaElement.removeEventListener(\"ended\", this._onEnded);\n this._mediaElement.removeEventListener(\"canplaythrough\", this._onCanPlayThrough);\n\n for (const source of Array.from(this._mediaElement.children)) {\n this._mediaElement.removeChild(source);\n }\n\n this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n this.engine.userGestureObservable.removeCallback(this._onUserGesture);\n }\n\n /** @internal */\n public play(options: Partial<IStreamingSoundPlayOptions> = {}): void {\n if (this._state === SoundState.Started) {\n return;\n }\n\n if (options.loop !== undefined) {\n this._options.loop = options.loop;\n }\n this._mediaElement.loop = this._options.loop;\n\n let startOffset = options.startOffset;\n\n if (this._currentTimeChangedWhilePaused) {\n startOffset = this._options.startOffset;\n this._currentTimeChangedWhilePaused = false;\n } else if (this._state === SoundState.Paused) {\n startOffset = this.currentTime + this._options.startOffset;\n }\n\n if (startOffset && startOffset > 0) {\n this._mediaElement.currentTime = startOffset;\n }\n\n this._volumeNode.gain.value = options.volume ?? 1;\n\n this._play();\n }\n\n /** @internal */\n public pause(): void {\n if (this._state !== SoundState.Starting && this._state !== SoundState.Started) {\n return;\n }\n\n this._setState(SoundState.Paused);\n this._enginePauseTime += this.engine.currentTime - this._enginePlayTime;\n\n this._mediaElement.pause();\n }\n\n /** @internal */\n public resume(): void {\n if (this._state === SoundState.Paused) {\n this.play();\n } else if (this._currentTimeChangedWhilePaused) {\n this.play();\n }\n }\n\n /** @internal */\n public override stop(): void {\n if (this._state === SoundState.Stopped) {\n return;\n }\n\n this._stop();\n }\n\n /** @internal */\n public getClassName(): string {\n return \"_WebAudioStreamingSoundInstance\";\n }\n\n protected override _connect(node: AbstractAudioNode): boolean {\n const connected = super._connect(node);\n\n if (!connected) {\n return false;\n }\n\n // If the wrapped node is not available now, it will be connected later by the sound's subgraph.\n if (node instanceof _WebAudioStreamingSound && node.inNode) {\n this.outNode?.connect(node.inNode);\n }\n\n return true;\n }\n\n protected override _disconnect(node: AbstractAudioNode): boolean {\n const disconnected = super._disconnect(node);\n\n if (!disconnected) {\n return false;\n }\n\n if (node instanceof _WebAudioStreamingSound && node.inNode) {\n this.outNode?.disconnect(node.inNode);\n }\n\n return true;\n }\n\n private _initFromMediaElement(mediaElement: HTMLMediaElement): void {\n Tools.SetCorsBehavior(mediaElement.currentSrc, mediaElement);\n\n mediaElement.controls = false;\n mediaElement.loop = this._options.loop;\n mediaElement.preload = \"auto\";\n\n mediaElement.addEventListener(\"canplaythrough\", this._onCanPlayThrough, { once: true });\n mediaElement.addEventListener(\"ended\", this._onEnded, { once: true });\n mediaElement.addEventListener(\"error\", this._onError, { once: true });\n\n mediaElement.load();\n\n this._sourceNode = new MediaElementAudioSourceNode(this._sound.audioContext, { mediaElement: mediaElement });\n this._sourceNode.connect(this._volumeNode);\n\n if (!this._connect(this._sound)) {\n throw new Error(\"Connect failed\");\n }\n\n this._mediaElement = mediaElement;\n }\n\n private _initFromUrl(url: string): void {\n const audio = new Audio(_CleanUrl(url));\n this._initFromMediaElement(audio);\n }\n\n private _initFromUrls(urls: string[]): void {\n const audio = new Audio();\n\n for (const url of urls) {\n const source = document.createElement(\"source\");\n source.src = _CleanUrl(url);\n audio.appendChild(source);\n }\n\n this._initFromMediaElement(audio);\n }\n\n private _onCanPlayThrough: () => void = () => {\n this._isReady = true;\n this._resolveIsReadyPromise(this._mediaElement);\n this.onReadyObservable.notifyObservers(this);\n };\n\n private _onEnded: () => void = () => {\n this.onEndedObservable.notifyObservers(this);\n this.dispose();\n };\n\n private _onError: (reason: any) => void = (reason: any) => {\n this._setState(SoundState.FailedToStart);\n this.onErrorObservable.notifyObservers(reason);\n this._rejectIsReadyPromise(reason);\n this.dispose();\n };\n\n private _onEngineStateChanged = () => {\n if (this.engine.state !== \"running\") {\n return;\n }\n\n if (this._options.loop && this.state === SoundState.Starting) {\n this.play();\n }\n\n this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n };\n\n private _onUserGesture = () => {\n this.play();\n };\n\n private _play(): void {\n this._setState(SoundState.Starting);\n\n if (!this._isReady) {\n this._playWhenReady();\n return;\n }\n\n if (this._state !== SoundState.Starting) {\n return;\n }\n\n if (this.engine.state === \"running\") {\n const result = this._mediaElement.play();\n\n this._enginePlayTime = this.engine.currentTime;\n this._setState(SoundState.Started);\n\n // It's possible that the play() method fails on Safari, even if the audio engine's state is \"running\".\n // This occurs when the audio context is paused by the system and resumed automatically by the audio engine\n // without a user interaction (e.g. when the Vision Pro exits and reenters immersive mode).\n result.catch(() => {\n this._setState(SoundState.FailedToStart);\n\n if (this._options.loop) {\n this.engine.userGestureObservable.addOnce(this._onUserGesture);\n }\n });\n } else if (this._options.loop) {\n this.engine.stateChangedObservable.add(this._onEngineStateChanged);\n } else {\n this.stop();\n this._setState(SoundState.FailedToStart);\n }\n }\n\n private _playWhenReady(): void {\n this._isReadyPromise\n .then(() => {\n this._play();\n })\n .catch(() => {\n Logger.Error(\"Streaming sound instance failed to play\");\n this._setState(SoundState.FailedToStart);\n });\n }\n\n private _rejectIsReadyPromise: (reason?: any) => void;\n private _resolveIsReadyPromise: (mediaElement: HTMLMediaElement) => void;\n\n private _stop(): void {\n this._mediaElement.pause();\n this._setState(SoundState.Stopped);\n this._onEnded();\n this.engine.stateChangedObservable.removeCallback(this._onEngineStateChanged);\n }\n}\n"]}
@@ -72,6 +72,100 @@ export interface IImage {
72
72
  */
73
73
  referrerPolicy: string;
74
74
  }
75
+ /**
76
+ * Class used to abstract a 2D path to use with the canvas and its context
77
+ */
78
+ export interface IPath2D {
79
+ /**
80
+ * Adds a path to the current path.
81
+ * @param path A Path2D path to add.
82
+ * @param transform A DOMMatrix to be used as the transformation matrix for the path that is added.
83
+ */
84
+ addPath(path: IPath2D, transform?: DOMMatrix): void;
85
+ /**
86
+ * Causes the point of the pen to move back to the start of the current sub-path. It tries to draw a straight line from the current point to the start.
87
+ * If the shape has already been closed or has only one point, this function does nothing.
88
+ */
89
+ closePath(): void;
90
+ /**
91
+ * Moves the starting point of a new sub-path to the (x, y) coordinates.
92
+ * @param x The x-axis (horizontal) coordinate of the point.
93
+ * @param y The y-axis (vertical) coordinate of the point.
94
+ */
95
+ moveTo(x: number, y: number): void;
96
+ /**
97
+ * Connects the last point in the current sub-path to the specified (x, y) coordinates with a straight line.
98
+ * @param x The x-axis coordinate of the line's end point.
99
+ * @param y The y-axis coordinate of the line's end point.
100
+ */
101
+ lineTo(x: number, y: number): void;
102
+ /**
103
+ * Adds a cubic Bézier curve to the current path.
104
+ * @param cp1x The x-axis coordinate of the first control point.
105
+ * @param cp1x The x-axis coordinate of the first control point.
106
+ * @param cp2y The y-axis coordinate of the second control point.
107
+ * @param cp2y The y-axis coordinate of the second control point.
108
+ * @param x The x-axis coordinate of the end point.
109
+ * @param y The y-axis coordinate of the end point.
110
+ */
111
+ bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
112
+ /**
113
+ * Adds a quadratic Bézier curve to the current path.
114
+ * @param cpx The x-axis coordinate of the control point.
115
+ * @param cpy The y-axis coordinate of the control point.
116
+ * @param x The x-axis coordinate of the end point.
117
+ * @param y The y-axis coordinate of the end point.
118
+ */
119
+ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
120
+ /**
121
+ * Adds a circular arc to the current path.
122
+ * @param x The horizontal coordinate of the arc's center.
123
+ * @param y The vertical coordinate of the arc's center.
124
+ * @param radius The arc's radius. Must be positive.
125
+ * @param startAngle The angle at which the arc starts in radians, measured from the positive x-axis.
126
+ * @param endAngle The angle at which the arc ends in radians, measured from the positive x-axis.
127
+ * @param anticlockwise An optional Boolean. If true, draws the arc counter-clockwise between the start and end angles. The default is false (clockwise).
128
+ */
129
+ arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
130
+ /**
131
+ * Adds a circular arc to the current sub-path, using the given control points and radius.
132
+ * @param x1 The x-axis coordinate of the first control point.
133
+ * @param y1 The y-axis coordinate of the first control point.
134
+ * @param x2 The x-axis coordinate of the second control point.
135
+ * @param y2 The y-axis coordinate of the second control point.
136
+ * @param radius The arc's radius. Must be non-negative.
137
+ */
138
+ arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
139
+ /**
140
+ * Creates an elliptical arc centered at (x, y) with the radii radiusX and radiusY. The path starts at startAngle and ends at endAngle, and travels in the direction given by counterclockwise.
141
+ * @param x The x-axis (horizontal) coordinate of the ellipse's center.
142
+ * @param y The y-axis (vertical) coordinate of the ellipse's center.
143
+ * @param radiusX The ellipse's major-axis radius. Must be non-negative.
144
+ * @param radiusY The ellipse's minor-axis radius. Must be non-negative.
145
+ * @param rotation The rotation of the ellipse, expressed in radians.
146
+ * @param startAngle The eccentric angle at which the ellipse starts, measured clockwise from the positive x-axis and expressed in radians.
147
+ * @param endAngle The eccentric angle at which the ellipse ends, measured clockwise from the positive x-axis and expressed in radians.
148
+ * @param counterclockwise An optional boolean value which, if true, draws the ellipse counterclockwise (anticlockwise). The default value is false (clockwise).
149
+ */
150
+ ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
151
+ /**
152
+ * Creates a path for a rectangle at position (x, y) with a size that is determined by width and height.
153
+ * @param x The x-axis coordinate of the rectangle's starting point.
154
+ * @param y The y-axis coordinate of the rectangle's starting point.
155
+ * @param width The rectangle's width. Positive values are to the right, and negative to the left.
156
+ * @param height The rectangle's height. Positive values are down, and negative are up.
157
+ */
158
+ rect(x: number, y: number, width: number, height: number): void;
159
+ /**
160
+ * Adds a rounded rectangle to the current path.
161
+ * @param x The x-axis coordinate of the rectangle's starting point, in pixels.
162
+ * @param y The y-axis coordinate of the rectangle's starting point, in pixels.
163
+ * @param width The rectangle's width. Positive values are to the right, and negative to the left.
164
+ * @param height The rectangle's height. Positive values are down, and negative are up.
165
+ * @param radii A number specifying the radii of the circular arc to be used for the corners of the rectangle. The number and order of the radii function in the same way as the border-radius CSS property when width and height are positive:
166
+ */
167
+ roundRect(x: number, y: number, width: number, height: number, radii: number): void;
168
+ }
75
169
  /**
76
170
  * Class used to abstract a canvas gradient
77
171
  */
@@ -380,8 +474,9 @@ export interface ICanvasRenderingContext {
380
474
  measureText(text: string): ITextMetrics;
381
475
  /**
382
476
  * Strokes the current sub-paths with the current stroke style.
477
+ * @param path Optional Path2D.
383
478
  */
384
- stroke(): void;
479
+ stroke(path?: IPath2D): void;
385
480
  /**
386
481
  * Fills the current sub-paths with the current fill style.
387
482
  */