@luma.gl/engine 9.0.0-alpha.16 → 9.0.0-alpha.17

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 (183) hide show
  1. package/dist/animation/key-frames.d.ts +1 -1
  2. package/dist/animation/key-frames.d.ts.map +1 -1
  3. package/dist/animation/key-frames.js +55 -54
  4. package/dist/animation/key-frames.js.map +1 -0
  5. package/dist/animation/timeline.d.ts +4 -4
  6. package/dist/animation/timeline.d.ts.map +1 -1
  7. package/dist/animation/timeline.js +101 -94
  8. package/dist/animation/timeline.js.map +1 -0
  9. package/dist/animation-loop/animation-loop.d.ts +4 -2
  10. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  11. package/dist/animation-loop/animation-loop.js +358 -414
  12. package/dist/animation-loop/animation-loop.js.map +1 -0
  13. package/dist/animation-loop/animation-props.d.ts +3 -1
  14. package/dist/animation-loop/animation-props.d.ts.map +1 -1
  15. package/dist/animation-loop/animation-props.js +1 -0
  16. package/dist/animation-loop/animation-props.js.map +1 -0
  17. package/dist/animation-loop/make-animation-loop.d.ts +1 -1
  18. package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
  19. package/dist/animation-loop/make-animation-loop.js +25 -26
  20. package/dist/animation-loop/make-animation-loop.js.map +1 -0
  21. package/dist/animation-loop/render-loop.js +5 -17
  22. package/dist/animation-loop/render-loop.js.map +1 -0
  23. package/dist/dist.dev.js +5240 -0
  24. package/dist/geometries/cone-geometry.d.ts +1 -1
  25. package/dist/geometries/cone-geometry.d.ts.map +1 -1
  26. package/dist/geometries/cone-geometry.js +18 -12
  27. package/dist/geometries/cone-geometry.js.map +1 -0
  28. package/dist/geometries/cube-geometry.d.ts +1 -1
  29. package/dist/geometries/cube-geometry.d.ts.map +1 -1
  30. package/dist/geometries/cube-geometry.js +60 -187
  31. package/dist/geometries/cube-geometry.js.map +1 -0
  32. package/dist/geometries/cylinder-geometry.d.ts +1 -1
  33. package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
  34. package/dist/geometries/cylinder-geometry.js +15 -10
  35. package/dist/geometries/cylinder-geometry.js.map +1 -0
  36. package/dist/geometries/ico-sphere-geometry.d.ts +1 -1
  37. package/dist/geometries/ico-sphere-geometry.d.ts.map +1 -1
  38. package/dist/geometries/ico-sphere-geometry.js +160 -141
  39. package/dist/geometries/ico-sphere-geometry.js.map +1 -0
  40. package/dist/geometries/plane-geometry.d.ts +1 -1
  41. package/dist/geometries/plane-geometry.d.ts.map +1 -1
  42. package/dist/geometries/plane-geometry.js +111 -93
  43. package/dist/geometries/plane-geometry.js.map +1 -0
  44. package/dist/geometries/sphere-geometry.d.ts +1 -1
  45. package/dist/geometries/sphere-geometry.d.ts.map +1 -1
  46. package/dist/geometries/sphere-geometry.js +95 -76
  47. package/dist/geometries/sphere-geometry.js.map +1 -0
  48. package/dist/geometries/truncated-cone-geometry.d.ts +1 -1
  49. package/dist/geometries/truncated-cone-geometry.d.ts.map +1 -1
  50. package/dist/geometries/truncated-cone-geometry.js +126 -105
  51. package/dist/geometries/truncated-cone-geometry.js.map +1 -0
  52. package/dist/geometry/geometry-table.d.ts +1 -1
  53. package/dist/geometry/geometry-table.d.ts.map +1 -1
  54. package/dist/geometry/geometry-table.js +1 -0
  55. package/dist/geometry/geometry-table.js.map +1 -0
  56. package/dist/geometry/geometry-utils.js +32 -22
  57. package/dist/geometry/geometry-utils.js.map +1 -0
  58. package/dist/geometry/geometry.d.ts +4 -4
  59. package/dist/geometry/geometry.d.ts.map +1 -1
  60. package/dist/geometry/geometry.js +109 -96
  61. package/dist/geometry/geometry.js.map +1 -0
  62. package/dist/geometry/primitive-utils.js +1 -30
  63. package/dist/geometry/primitive-utils.js.map +1 -0
  64. package/dist/index.cjs +2222 -0
  65. package/dist/index.js +16 -20
  66. package/dist/index.js.map +1 -0
  67. package/dist/lib/clip-space.js +1 -50
  68. package/dist/lib/clip-space.js.map +1 -0
  69. package/dist/lib/model-utils.js +28 -101
  70. package/dist/lib/model-utils.js.map +1 -0
  71. package/dist/lib/model.d.ts +1 -1
  72. package/dist/lib/model.d.ts.map +1 -1
  73. package/dist/lib/model.js +129 -121
  74. package/dist/lib/model.js.map +1 -0
  75. package/dist/lib/pipeline-factory.d.ts +3 -3
  76. package/dist/lib/pipeline-factory.d.ts.map +1 -1
  77. package/dist/lib/pipeline-factory.js +165 -136
  78. package/dist/lib/pipeline-factory.js.map +1 -0
  79. package/dist.min.js +245 -0
  80. package/package.json +22 -13
  81. package/src/.DS_Store +0 -0
  82. package/src/animation/timeline.ts +1 -1
  83. package/src/animation-loop/animation-loop.ts +5 -5
  84. package/src/animation-loop/make-animation-loop.ts +2 -1
  85. package/src/geometry/geometry.ts +2 -2
  86. package/src/lib/pipeline-factory.ts +1 -1
  87. package/dist/bundle.d.ts +0 -2
  88. package/dist/bundle.d.ts.map +0 -1
  89. package/dist/bundle.js +0 -5
  90. package/dist/dist.min.js +0 -31
  91. package/dist/es5/animation/key-frames.js +0 -84
  92. package/dist/es5/animation/key-frames.js.map +0 -1
  93. package/dist/es5/animation/timeline.js +0 -183
  94. package/dist/es5/animation/timeline.js.map +0 -1
  95. package/dist/es5/animation-loop/animation-loop.js +0 -534
  96. package/dist/es5/animation-loop/animation-loop.js.map +0 -1
  97. package/dist/es5/animation-loop/animation-props.js +0 -2
  98. package/dist/es5/animation-loop/animation-props.js.map +0 -1
  99. package/dist/es5/animation-loop/make-animation-loop.js +0 -53
  100. package/dist/es5/animation-loop/make-animation-loop.js.map +0 -1
  101. package/dist/es5/animation-loop/render-loop.js +0 -39
  102. package/dist/es5/animation-loop/render-loop.js.map +0 -1
  103. package/dist/es5/bundle.js +0 -6
  104. package/dist/es5/bundle.js.map +0 -1
  105. package/dist/es5/geometries/cone-geometry.js +0 -43
  106. package/dist/es5/geometries/cone-geometry.js.map +0 -1
  107. package/dist/es5/geometries/cube-geometry.js +0 -84
  108. package/dist/es5/geometries/cube-geometry.js.map +0 -1
  109. package/dist/es5/geometries/cylinder-geometry.js +0 -39
  110. package/dist/es5/geometries/cylinder-geometry.js.map +0 -1
  111. package/dist/es5/geometries/ico-sphere-geometry.js +0 -185
  112. package/dist/es5/geometries/ico-sphere-geometry.js.map +0 -1
  113. package/dist/es5/geometries/plane-geometry.js +0 -137
  114. package/dist/es5/geometries/plane-geometry.js.map +0 -1
  115. package/dist/es5/geometries/sphere-geometry.js +0 -120
  116. package/dist/es5/geometries/sphere-geometry.js.map +0 -1
  117. package/dist/es5/geometries/truncated-cone-geometry.js +0 -160
  118. package/dist/es5/geometries/truncated-cone-geometry.js.map +0 -1
  119. package/dist/es5/geometry/geometry-table.js +0 -2
  120. package/dist/es5/geometry/geometry-table.js.map +0 -1
  121. package/dist/es5/geometry/geometry-utils.js +0 -39
  122. package/dist/es5/geometry/geometry-utils.js.map +0 -1
  123. package/dist/es5/geometry/geometry.js +0 -150
  124. package/dist/es5/geometry/geometry.js.map +0 -1
  125. package/dist/es5/geometry/primitive-utils.js +0 -2
  126. package/dist/es5/geometry/primitive-utils.js.map +0 -1
  127. package/dist/es5/index.js +0 -112
  128. package/dist/es5/index.js.map +0 -1
  129. package/dist/es5/lib/clip-space.js +0 -2
  130. package/dist/es5/lib/clip-space.js.map +0 -1
  131. package/dist/es5/lib/model-utils.js +0 -52
  132. package/dist/es5/lib/model-utils.js.map +0 -1
  133. package/dist/es5/lib/model.js +0 -173
  134. package/dist/es5/lib/model.js.map +0 -1
  135. package/dist/es5/lib/pipeline-factory.js +0 -244
  136. package/dist/es5/lib/pipeline-factory.js.map +0 -1
  137. package/dist/esm/animation/key-frames.js +0 -57
  138. package/dist/esm/animation/key-frames.js.map +0 -1
  139. package/dist/esm/animation/timeline.js +0 -113
  140. package/dist/esm/animation/timeline.js.map +0 -1
  141. package/dist/esm/animation-loop/animation-loop.js +0 -367
  142. package/dist/esm/animation-loop/animation-loop.js.map +0 -1
  143. package/dist/esm/animation-loop/animation-props.js +0 -2
  144. package/dist/esm/animation-loop/animation-props.js.map +0 -1
  145. package/dist/esm/animation-loop/make-animation-loop.js +0 -28
  146. package/dist/esm/animation-loop/make-animation-loop.js.map +0 -1
  147. package/dist/esm/animation-loop/render-loop.js +0 -7
  148. package/dist/esm/animation-loop/render-loop.js.map +0 -1
  149. package/dist/esm/bundle.js +0 -4
  150. package/dist/esm/bundle.js.map +0 -1
  151. package/dist/esm/geometries/cone-geometry.js +0 -21
  152. package/dist/esm/geometries/cone-geometry.js.map +0 -1
  153. package/dist/esm/geometries/cube-geometry.js +0 -67
  154. package/dist/esm/geometries/cube-geometry.js.map +0 -1
  155. package/dist/esm/geometries/cylinder-geometry.js +0 -18
  156. package/dist/esm/geometries/cylinder-geometry.js.map +0 -1
  157. package/dist/esm/geometries/ico-sphere-geometry.js +0 -170
  158. package/dist/esm/geometries/ico-sphere-geometry.js.map +0 -1
  159. package/dist/esm/geometries/plane-geometry.js +0 -119
  160. package/dist/esm/geometries/plane-geometry.js.map +0 -1
  161. package/dist/esm/geometries/sphere-geometry.js +0 -102
  162. package/dist/esm/geometries/sphere-geometry.js.map +0 -1
  163. package/dist/esm/geometries/truncated-cone-geometry.js +0 -136
  164. package/dist/esm/geometries/truncated-cone-geometry.js.map +0 -1
  165. package/dist/esm/geometry/geometry-table.js +0 -2
  166. package/dist/esm/geometry/geometry-table.js.map +0 -1
  167. package/dist/esm/geometry/geometry-utils.js +0 -37
  168. package/dist/esm/geometry/geometry-utils.js.map +0 -1
  169. package/dist/esm/geometry/geometry.js +0 -119
  170. package/dist/esm/geometry/geometry.js.map +0 -1
  171. package/dist/esm/geometry/primitive-utils.js +0 -2
  172. package/dist/esm/geometry/primitive-utils.js.map +0 -1
  173. package/dist/esm/index.js +0 -16
  174. package/dist/esm/index.js.map +0 -1
  175. package/dist/esm/lib/clip-space.js +0 -2
  176. package/dist/esm/lib/clip-space.js.map +0 -1
  177. package/dist/esm/lib/model-utils.js +0 -40
  178. package/dist/esm/lib/model-utils.js.map +0 -1
  179. package/dist/esm/lib/model.js +0 -146
  180. package/dist/esm/lib/model.js.map +0 -1
  181. package/dist/esm/lib/pipeline-factory.js +0 -180
  182. package/dist/esm/lib/pipeline-factory.js.map +0 -1
  183. package/src/bundle.ts +0 -4
@@ -1,423 +1,367 @@
1
- // luma.gl, MIT license
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
2
  import { luma } from '@luma.gl/api';
3
3
  import { requestAnimationFrame, cancelAnimationFrame } from '@luma.gl/api';
4
4
  import { Stats } from '@probe.gl/stats';
5
5
  let statIdCounter = 0;
6
6
  const DEFAULT_ANIMATION_LOOP_PROPS = {
7
- device: null,
8
- onAddHTML: () => '',
9
- onInitialize: async () => { return null; },
10
- onRender: () => { },
11
- onFinalize: () => { },
12
- onError: (error) => console.error(error),
13
- stats: luma.stats.get(`animation-loop-${statIdCounter++}`),
14
- // view parameters
15
- useDevicePixels: true,
16
- autoResizeViewport: false,
17
- autoResizeDrawingBuffer: false,
7
+ device: null,
8
+ onAddHTML: () => '',
9
+ onInitialize: async () => {
10
+ return null;
11
+ },
12
+ onRender: () => {},
13
+ onFinalize: () => {},
14
+ onError: error => console.error(error),
15
+ stats: luma.stats.get("animation-loop-".concat(statIdCounter++)),
16
+ useDevicePixels: true,
17
+ autoResizeViewport: false,
18
+ autoResizeDrawingBuffer: false
18
19
  };
19
- /** Convenient animation loop */
20
20
  export class AnimationLoop {
21
- // _gpuTimeQuery: Query | null = null;
22
- /*
23
- * @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
24
- */
25
- constructor(props) {
26
- this.device = null;
27
- this.canvas = null;
28
- this.animationProps = null;
29
- this.timeline = null;
30
- this.needsRedraw = 'initialized';
31
- this._initialized = false;
32
- this._running = false;
33
- this._animationFrameId = null;
34
- this._nextFramePromise = null;
35
- this._resolveNextFrame = null;
36
- this._cpuStartTime = 0;
37
- this.props = { ...DEFAULT_ANIMATION_LOOP_PROPS, ...props };
38
- props = this.props;
39
- if (!props.device) {
40
- throw new Error('No device provided');
41
- }
42
- let { useDevicePixels = true } = this.props;
43
- // state
44
- this.stats = props.stats || new Stats({ id: 'animation-loop-stats' });
45
- this.cpuTime = this.stats.get('CPU Time');
46
- this.gpuTime = this.stats.get('GPU Time');
47
- this.frameRate = this.stats.get('Frame Rate');
48
- this.setProps({
49
- autoResizeViewport: props.autoResizeViewport,
50
- autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
51
- useDevicePixels
52
- });
53
- // Bind methods
54
- this.start = this.start.bind(this);
55
- this.stop = this.stop.bind(this);
56
- this._onMousemove = this._onMousemove.bind(this);
57
- this._onMouseleave = this._onMouseleave.bind(this);
58
- }
59
- destroy() {
60
- this.stop();
61
- this._setDisplay(null);
62
- }
63
- /** @deprecated Use .destroy() */
64
- delete() {
65
- this.destroy();
66
- }
67
- setNeedsRedraw(reason) {
68
- this.needsRedraw = this.needsRedraw || reason;
69
- return this;
70
- }
71
- // TODO - move to CanvasContext
72
- setProps(props) {
73
- if ('autoResizeViewport' in props) {
74
- this.props.autoResizeViewport = props.autoResizeViewport || false;
75
- }
76
- if ('autoResizeDrawingBuffer' in props) {
77
- this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;
78
- }
79
- if ('useDevicePixels' in props) {
80
- this.props.useDevicePixels = props.useDevicePixels || false;
81
- }
82
- return this;
83
- }
84
- /** Starts a render loop if not already running */
85
- async start() {
86
- if (this._running) {
87
- return this;
88
- }
89
- this._running = true;
90
- try {
91
- // check that we haven't been stopped
92
- if (!this._running) {
93
- return null;
94
- }
95
- let appContext;
96
- if (!this._initialized) {
97
- this._initialized = true;
98
- // Create the WebGL context
99
- await this._initDevice();
100
- this._initialize();
101
- // Note: onIntialize can return a promise (e.g. in case app needs to load resources)
102
- await this.props.onInitialize(this._getAnimationProps());
103
- }
104
- // check that we haven't been stopped
105
- if (!this._running) {
106
- return null;
107
- }
108
- // Start the loop
109
- if (appContext !== false) {
110
- // cancel any pending renders to ensure only one loop can ever run
111
- this._cancelAnimationFrame();
112
- this._requestAnimationFrame();
113
- }
114
- return this;
115
- }
116
- catch (err) {
117
- const error = err instanceof Error ? err : new Error('Unknown error');
118
- this.props.onError(error);
119
- // this._running = false; // TODO
120
- throw error;
121
- }
122
- }
123
- /** Explicitly draw a frame */
124
- redraw() {
125
- if (this.device?.isLost) {
126
- return this;
127
- }
128
- this._beginTimers();
129
- this._setupFrame();
130
- this._updateAnimationProps();
131
- this._renderFrame(this._getAnimationProps());
132
- // clear needsRedraw flag
133
- this._clearNeedsRedraw();
134
- if (this._resolveNextFrame) {
135
- this._resolveNextFrame(this);
136
- this._nextFramePromise = null;
137
- this._resolveNextFrame = null;
138
- }
139
- this._endTimers();
140
- return this;
141
- }
142
- // Stops a render loop if already running, finalizing
143
- stop() {
144
- // console.debug(`Stopping ${this.constructor.name}`);
145
- if (this._running) {
146
- // call callback
147
- // If stop is called immediately, we can end up in a state where props haven't been initialized...
148
- if (this.animationProps) {
149
- this.props.onFinalize(this.animationProps);
150
- }
151
- this._cancelAnimationFrame();
152
- this._nextFramePromise = null;
153
- this._resolveNextFrame = null;
154
- this._running = false;
155
- }
156
- return this;
157
- }
158
- attachTimeline(timeline) {
159
- this.timeline = timeline;
160
- return this.timeline;
161
- }
162
- detachTimeline() {
163
- this.timeline = null;
164
- }
165
- waitForRender() {
166
- this.setNeedsRedraw('waitForRender');
167
- if (!this._nextFramePromise) {
168
- this._nextFramePromise = new Promise((resolve) => {
169
- this._resolveNextFrame = resolve;
170
- });
171
- }
172
- return this._nextFramePromise;
173
- }
174
- async toDataURL() {
175
- this.setNeedsRedraw('toDataURL');
176
- await this.waitForRender();
177
- if (this.canvas instanceof HTMLCanvasElement) {
178
- return this.canvas.toDataURL();
179
- }
180
- throw new Error('OffscreenCanvas');
181
- }
182
- // PRIVATE METHODS
183
- _initialize() {
184
- this._startEventHandling();
185
- // Initialize the callback data
186
- this._initializeAnimationProps();
187
- this._updateAnimationProps();
188
- // Default viewport setup, in case onInitialize wants to render
189
- this._resizeCanvasDrawingBuffer();
190
- this._resizeViewport();
191
- // this._gpuTimeQuery = Query.isSupported(this.gl, ['timers']) ? new Query(this.gl) : null;
192
- }
193
- _setDisplay(display) {
194
- if (this.display) {
195
- this.display.delete();
196
- this.display.animationLoop = null;
197
- }
198
- // store animation loop on the display
199
- if (display) {
200
- display.animationLoop = this;
201
- }
202
- this.display = display;
203
- }
204
- _requestAnimationFrame() {
205
- if (!this._running) {
206
- return;
207
- }
208
- // VR display has a separate animation frame to sync with headset
209
- // TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/
210
- // See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame
211
- // if (this.display && this.display.requestAnimationFrame) {
212
- // this._animationFrameId = this.display.requestAnimationFrame(this._animationFrame.bind(this));
213
- // }
214
- this._animationFrameId = requestAnimationFrame(this._animationFrame.bind(this));
215
- }
216
- _cancelAnimationFrame() {
217
- if (this._animationFrameId !== null) {
218
- return;
219
- }
220
- // VR display has a separate animation frame to sync with headset
221
- // TODO WebVR API discontinued, replaced by WebXR: https://immersive-web.github.io/webxr/
222
- // See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/requestAnimationFrame
223
- // if (this.display && this.display.cancelAnimationFrame) {
224
- // this.display.cancelAnimationFrame(this._animationFrameId);
225
- // }
226
- cancelAnimationFrame(this._animationFrameId);
227
- this._animationFrameId = null;
228
- }
229
- _animationFrame() {
230
- if (!this._running) {
231
- return;
232
- }
233
- this.redraw();
21
+ constructor(props) {
22
+ _defineProperty(this, "device", null);
23
+ _defineProperty(this, "canvas", null);
24
+ _defineProperty(this, "props", void 0);
25
+ _defineProperty(this, "animationProps", null);
26
+ _defineProperty(this, "timeline", null);
27
+ _defineProperty(this, "stats", void 0);
28
+ _defineProperty(this, "cpuTime", void 0);
29
+ _defineProperty(this, "gpuTime", void 0);
30
+ _defineProperty(this, "frameRate", void 0);
31
+ _defineProperty(this, "display", void 0);
32
+ _defineProperty(this, "needsRedraw", 'initialized');
33
+ _defineProperty(this, "_initialized", false);
34
+ _defineProperty(this, "_running", false);
35
+ _defineProperty(this, "_animationFrameId", null);
36
+ _defineProperty(this, "_nextFramePromise", null);
37
+ _defineProperty(this, "_resolveNextFrame", null);
38
+ _defineProperty(this, "_cpuStartTime", 0);
39
+ this.props = {
40
+ ...DEFAULT_ANIMATION_LOOP_PROPS,
41
+ ...props
42
+ };
43
+ props = this.props;
44
+ if (!props.device) {
45
+ throw new Error('No device provided');
46
+ }
47
+ const {
48
+ useDevicePixels = true
49
+ } = this.props;
50
+ this.stats = props.stats || new Stats({
51
+ id: 'animation-loop-stats'
52
+ });
53
+ this.cpuTime = this.stats.get('CPU Time');
54
+ this.gpuTime = this.stats.get('GPU Time');
55
+ this.frameRate = this.stats.get('Frame Rate');
56
+ this.setProps({
57
+ autoResizeViewport: props.autoResizeViewport,
58
+ autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
59
+ useDevicePixels
60
+ });
61
+ this.start = this.start.bind(this);
62
+ this.stop = this.stop.bind(this);
63
+ this._onMousemove = this._onMousemove.bind(this);
64
+ this._onMouseleave = this._onMouseleave.bind(this);
65
+ }
66
+ destroy() {
67
+ this.stop();
68
+ this._setDisplay(null);
69
+ }
70
+ delete() {
71
+ this.destroy();
72
+ }
73
+ setNeedsRedraw(reason) {
74
+ this.needsRedraw = this.needsRedraw || reason;
75
+ return this;
76
+ }
77
+ setProps(props) {
78
+ if ('autoResizeViewport' in props) {
79
+ this.props.autoResizeViewport = props.autoResizeViewport || false;
80
+ }
81
+ if ('autoResizeDrawingBuffer' in props) {
82
+ this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false;
83
+ }
84
+ if ('useDevicePixels' in props) {
85
+ this.props.useDevicePixels = props.useDevicePixels || false;
86
+ }
87
+ return this;
88
+ }
89
+ async start() {
90
+ if (this._running) {
91
+ return this;
92
+ }
93
+ this._running = true;
94
+ try {
95
+ if (!this._running) {
96
+ return null;
97
+ }
98
+ let appContext;
99
+ if (!this._initialized) {
100
+ this._initialized = true;
101
+ await this._initDevice();
102
+ this._initialize();
103
+ await this.props.onInitialize(this._getAnimationProps());
104
+ }
105
+ if (!this._running) {
106
+ return null;
107
+ }
108
+ if (appContext !== false) {
109
+ this._cancelAnimationFrame();
234
110
  this._requestAnimationFrame();
235
- }
236
- // Called on each frame, can be overridden to call onRender multiple times
237
- // to support e.g. stereoscopic rendering
238
- _renderFrame(animationProps) {
239
- // Allow e.g. VR display to render multiple frames.
240
- if (this.display) {
241
- this.display._renderFrame(animationProps);
242
- return;
243
- }
244
- // call callback
245
- this.props.onRender(this._getAnimationProps());
246
- // end callback
247
- }
248
- _clearNeedsRedraw() {
249
- this.needsRedraw = false;
250
- }
251
- _setupFrame() {
252
- this._resizeCanvasDrawingBuffer();
253
- this._resizeViewport();
254
- }
255
- // Initialize the object that will be passed to app callbacks
256
- _initializeAnimationProps() {
257
- if (!this.device) {
258
- throw new Error('loop');
259
- }
260
- this.animationProps = {
261
- animationLoop: this,
262
- device: this.device,
263
- canvas: this.device?.canvasContext?.canvas,
264
- timeline: this.timeline,
265
- // Initial values
266
- useDevicePixels: this.props.useDevicePixels,
267
- needsRedraw: false,
268
- // Placeholders
269
- width: 1,
270
- height: 1,
271
- aspect: 1,
272
- // Animation props
273
- time: 0,
274
- startTime: Date.now(),
275
- engineTime: 0,
276
- tick: 0,
277
- tock: 0,
278
- // Experimental
279
- _mousePosition: null // Event props
280
- };
281
- }
282
- _getAnimationProps() {
283
- if (!this.animationProps) {
284
- throw new Error('animationProps');
285
- }
286
- return this.animationProps;
287
- }
288
- // Update the context object that will be passed to app callbacks
289
- _updateAnimationProps() {
290
- if (!this.animationProps) {
291
- return;
292
- }
293
- const { width, height, aspect } = this._getSizeAndAspect();
294
- if (width !== this.animationProps.width || height !== this.animationProps.height) {
295
- this.setNeedsRedraw('drawing buffer resized');
296
- }
297
- if (aspect !== this.animationProps.aspect) {
298
- this.setNeedsRedraw('drawing buffer aspect changed');
299
- }
300
- this.animationProps.width = width;
301
- this.animationProps.height = height;
302
- this.animationProps.aspect = aspect;
303
- this.animationProps.needsRedraw = this.needsRedraw;
304
- // Update time properties
305
- this.animationProps.engineTime = Date.now() - this.animationProps.startTime;
306
- if (this.timeline) {
307
- this.timeline.update(this.animationProps.engineTime);
308
- }
309
- this.animationProps.tick = Math.floor((this.animationProps.time / 1000) * 60);
310
- this.animationProps.tock++;
311
- // For back compatibility
312
- this.animationProps.time = this.timeline
313
- ? this.timeline.getTime()
314
- : this.animationProps.engineTime;
315
- }
316
- /** Wait for supplied device */
317
- async _initDevice() {
318
- this.device = await this.props.device;
319
- if (!this.device) {
320
- throw new Error('No device provided');
321
- }
322
- this.canvas = this.device.canvasContext?.canvas || null;
323
- // this._createInfoDiv();
324
- }
325
- _createInfoDiv() {
326
- if (this.canvas && this.props.onAddHTML) {
327
- const wrapperDiv = document.createElement('div');
328
- document.body.appendChild(wrapperDiv);
329
- wrapperDiv.style.position = 'relative';
330
- const div = document.createElement('div');
331
- div.style.position = 'absolute';
332
- div.style.left = '10px';
333
- div.style.bottom = '10px';
334
- div.style.width = '300px';
335
- div.style.background = 'white';
336
- if (this.canvas instanceof HTMLCanvasElement) {
337
- wrapperDiv.appendChild(this.canvas);
338
- }
339
- wrapperDiv.appendChild(div);
340
- const html = this.props.onAddHTML(div);
341
- if (html) {
342
- div.innerHTML = html;
343
- }
344
- }
345
- }
346
- _getSizeAndAspect() {
347
- if (!this.device) {
348
- return { width: 1, height: 1, aspect: 1 };
349
- }
350
- // https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
351
- const [width, height] = this.device?.canvasContext?.getPixelSize() || [1, 1];
352
- // https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
353
- let aspect = 1;
354
- const canvas = this.device?.canvasContext?.canvas;
355
- // @ts-expect-error
356
- if (canvas && canvas.clientHeight) {
357
- // @ts-expect-error
358
- aspect = canvas.clientWidth / canvas.clientHeight;
359
- }
360
- else if (width > 0 && height > 0) {
361
- aspect = width / height;
362
- }
363
- return { width, height, aspect };
364
- }
365
- /** Default viewport setup */
366
- _resizeViewport() {
367
- // @ts-expect-error Expose on canvasContext
368
- if (this.props.autoResizeViewport && this.device.gl) {
369
- // @ts-expect-error Expose canvasContext
370
- this.device.gl.viewport(0, 0, this.device.gl.drawingBufferWidth, this.device.gl.drawingBufferHeight);
371
- }
372
- }
373
- /**
374
- * Resize the render buffer of the canvas to match canvas client size
375
- * Optionally multiplying with devicePixel ratio
376
- */
377
- _resizeCanvasDrawingBuffer() {
378
- if (this.props.autoResizeDrawingBuffer) {
379
- this.device?.canvasContext?.resize({ useDevicePixels: this.props.useDevicePixels });
380
- }
381
- }
382
- _beginTimers() {
383
- this.frameRate.timeEnd();
384
- this.frameRate.timeStart();
385
- // Check if timer for last frame has completed.
386
- // GPU timer results are never available in the same
387
- // frame they are captured.
388
- // if (
389
- // this._gpuTimeQuery &&
390
- // this._gpuTimeQuery.isResultAvailable() &&
391
- // !this._gpuTimeQuery.isTimerDisjoint()
392
- // ) {
393
- // this.stats.get('GPU Time').addTime(this._gpuTimeQuery.getTimerMilliseconds());
394
- // }
395
- // if (this._gpuTimeQuery) {
396
- // // GPU time query start
397
- // this._gpuTimeQuery.beginTimeElapsedQuery();
398
- // }
399
- // this.cpuTime.timeStart();
400
- }
401
- _endTimers() {
402
- this.cpuTime.timeEnd();
403
- // if (this._gpuTimeQuery) {
404
- // // GPU time query end. Results will be available on next frame.
405
- // this._gpuTimeQuery.end();
406
- // }
407
- }
408
- // Event handling
409
- _startEventHandling() {
410
- if (this.canvas) {
411
- this.canvas.addEventListener('mousemove', this._onMousemove);
412
- this.canvas.addEventListener('mouseleave', this._onMouseleave);
413
- }
414
- }
415
- _onMousemove(event) {
416
- if (event instanceof MouseEvent) {
417
- this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];
418
- }
419
- }
420
- _onMouseleave(event) {
421
- this._getAnimationProps()._mousePosition = null;
422
- }
111
+ }
112
+ return this;
113
+ } catch (err) {
114
+ const error = err instanceof Error ? err : new Error('Unknown error');
115
+ this.props.onError(error);
116
+ throw error;
117
+ }
118
+ }
119
+ redraw() {
120
+ var _this$device;
121
+ if ((_this$device = this.device) !== null && _this$device !== void 0 && _this$device.isLost) {
122
+ return this;
123
+ }
124
+ this._beginTimers();
125
+ this._setupFrame();
126
+ this._updateAnimationProps();
127
+ this._renderFrame(this._getAnimationProps());
128
+ this._clearNeedsRedraw();
129
+ if (this._resolveNextFrame) {
130
+ this._resolveNextFrame(this);
131
+ this._nextFramePromise = null;
132
+ this._resolveNextFrame = null;
133
+ }
134
+ this._endTimers();
135
+ return this;
136
+ }
137
+ stop() {
138
+ if (this._running) {
139
+ if (this.animationProps) {
140
+ this.props.onFinalize(this.animationProps);
141
+ }
142
+ this._cancelAnimationFrame();
143
+ this._nextFramePromise = null;
144
+ this._resolveNextFrame = null;
145
+ this._running = false;
146
+ }
147
+ return this;
148
+ }
149
+ attachTimeline(timeline) {
150
+ this.timeline = timeline;
151
+ return this.timeline;
152
+ }
153
+ detachTimeline() {
154
+ this.timeline = null;
155
+ }
156
+ waitForRender() {
157
+ this.setNeedsRedraw('waitForRender');
158
+ if (!this._nextFramePromise) {
159
+ this._nextFramePromise = new Promise(resolve => {
160
+ this._resolveNextFrame = resolve;
161
+ });
162
+ }
163
+ return this._nextFramePromise;
164
+ }
165
+ async toDataURL() {
166
+ this.setNeedsRedraw('toDataURL');
167
+ await this.waitForRender();
168
+ if (this.canvas instanceof HTMLCanvasElement) {
169
+ return this.canvas.toDataURL();
170
+ }
171
+ throw new Error('OffscreenCanvas');
172
+ }
173
+ _initialize() {
174
+ this._startEventHandling();
175
+ this._initializeAnimationProps();
176
+ this._updateAnimationProps();
177
+ this._resizeCanvasDrawingBuffer();
178
+ this._resizeViewport();
179
+ }
180
+ _setDisplay(display) {
181
+ if (this.display) {
182
+ this.display.delete();
183
+ this.display.animationLoop = null;
184
+ }
185
+ if (display) {
186
+ display.animationLoop = this;
187
+ }
188
+ this.display = display;
189
+ }
190
+ _requestAnimationFrame() {
191
+ if (!this._running) {
192
+ return;
193
+ }
194
+ this._animationFrameId = requestAnimationFrame(this._animationFrame.bind(this));
195
+ }
196
+ _cancelAnimationFrame() {
197
+ if (this._animationFrameId !== null) {
198
+ return;
199
+ }
200
+ cancelAnimationFrame(this._animationFrameId);
201
+ this._animationFrameId = null;
202
+ }
203
+ _animationFrame() {
204
+ if (!this._running) {
205
+ return;
206
+ }
207
+ this.redraw();
208
+ this._requestAnimationFrame();
209
+ }
210
+ _renderFrame(animationProps) {
211
+ if (this.display) {
212
+ this.display._renderFrame(animationProps);
213
+ return;
214
+ }
215
+ this.props.onRender(this._getAnimationProps());
216
+ }
217
+ _clearNeedsRedraw() {
218
+ this.needsRedraw = false;
219
+ }
220
+ _setupFrame() {
221
+ this._resizeCanvasDrawingBuffer();
222
+ this._resizeViewport();
223
+ }
224
+ _initializeAnimationProps() {
225
+ var _this$device2, _this$device2$canvasC;
226
+ if (!this.device) {
227
+ throw new Error('loop');
228
+ }
229
+ this.animationProps = {
230
+ animationLoop: this,
231
+ device: this.device,
232
+ canvas: (_this$device2 = this.device) === null || _this$device2 === void 0 ? void 0 : (_this$device2$canvasC = _this$device2.canvasContext) === null || _this$device2$canvasC === void 0 ? void 0 : _this$device2$canvasC.canvas,
233
+ timeline: this.timeline,
234
+ useDevicePixels: this.props.useDevicePixels,
235
+ needsRedraw: false,
236
+ width: 1,
237
+ height: 1,
238
+ aspect: 1,
239
+ time: 0,
240
+ startTime: Date.now(),
241
+ engineTime: 0,
242
+ tick: 0,
243
+ tock: 0,
244
+ _mousePosition: null
245
+ };
246
+ }
247
+ _getAnimationProps() {
248
+ if (!this.animationProps) {
249
+ throw new Error('animationProps');
250
+ }
251
+ return this.animationProps;
252
+ }
253
+ _updateAnimationProps() {
254
+ if (!this.animationProps) {
255
+ return;
256
+ }
257
+ const {
258
+ width,
259
+ height,
260
+ aspect
261
+ } = this._getSizeAndAspect();
262
+ if (width !== this.animationProps.width || height !== this.animationProps.height) {
263
+ this.setNeedsRedraw('drawing buffer resized');
264
+ }
265
+ if (aspect !== this.animationProps.aspect) {
266
+ this.setNeedsRedraw('drawing buffer aspect changed');
267
+ }
268
+ this.animationProps.width = width;
269
+ this.animationProps.height = height;
270
+ this.animationProps.aspect = aspect;
271
+ this.animationProps.needsRedraw = this.needsRedraw;
272
+ this.animationProps.engineTime = Date.now() - this.animationProps.startTime;
273
+ if (this.timeline) {
274
+ this.timeline.update(this.animationProps.engineTime);
275
+ }
276
+ this.animationProps.tick = Math.floor(this.animationProps.time / 1000 * 60);
277
+ this.animationProps.tock++;
278
+ this.animationProps.time = this.timeline ? this.timeline.getTime() : this.animationProps.engineTime;
279
+ }
280
+ async _initDevice() {
281
+ var _this$device$canvasCo;
282
+ this.device = await this.props.device;
283
+ if (!this.device) {
284
+ throw new Error('No device provided');
285
+ }
286
+ this.canvas = ((_this$device$canvasCo = this.device.canvasContext) === null || _this$device$canvasCo === void 0 ? void 0 : _this$device$canvasCo.canvas) || null;
287
+ }
288
+ _createInfoDiv() {
289
+ if (this.canvas && this.props.onAddHTML) {
290
+ const wrapperDiv = document.createElement('div');
291
+ document.body.appendChild(wrapperDiv);
292
+ wrapperDiv.style.position = 'relative';
293
+ const div = document.createElement('div');
294
+ div.style.position = 'absolute';
295
+ div.style.left = '10px';
296
+ div.style.bottom = '10px';
297
+ div.style.width = '300px';
298
+ div.style.background = 'white';
299
+ if (this.canvas instanceof HTMLCanvasElement) {
300
+ wrapperDiv.appendChild(this.canvas);
301
+ }
302
+ wrapperDiv.appendChild(div);
303
+ const html = this.props.onAddHTML(div);
304
+ if (html) {
305
+ div.innerHTML = html;
306
+ }
307
+ }
308
+ }
309
+ _getSizeAndAspect() {
310
+ var _this$device3, _this$device3$canvasC, _this$device4, _this$device4$canvasC;
311
+ if (!this.device) {
312
+ return {
313
+ width: 1,
314
+ height: 1,
315
+ aspect: 1
316
+ };
317
+ }
318
+ const [width, height] = ((_this$device3 = this.device) === null || _this$device3 === void 0 ? void 0 : (_this$device3$canvasC = _this$device3.canvasContext) === null || _this$device3$canvasC === void 0 ? void 0 : _this$device3$canvasC.getPixelSize()) || [1, 1];
319
+ let aspect = 1;
320
+ const canvas = (_this$device4 = this.device) === null || _this$device4 === void 0 ? void 0 : (_this$device4$canvasC = _this$device4.canvasContext) === null || _this$device4$canvasC === void 0 ? void 0 : _this$device4$canvasC.canvas;
321
+ if (canvas && canvas.clientHeight) {
322
+ aspect = canvas.clientWidth / canvas.clientHeight;
323
+ } else if (width > 0 && height > 0) {
324
+ aspect = width / height;
325
+ }
326
+ return {
327
+ width,
328
+ height,
329
+ aspect
330
+ };
331
+ }
332
+ _resizeViewport() {
333
+ if (this.props.autoResizeViewport && this.device.gl) {
334
+ this.device.gl.viewport(0, 0, this.device.gl.drawingBufferWidth, this.device.gl.drawingBufferHeight);
335
+ }
336
+ }
337
+ _resizeCanvasDrawingBuffer() {
338
+ if (this.props.autoResizeDrawingBuffer) {
339
+ var _this$device5, _this$device5$canvasC;
340
+ (_this$device5 = this.device) === null || _this$device5 === void 0 ? void 0 : (_this$device5$canvasC = _this$device5.canvasContext) === null || _this$device5$canvasC === void 0 ? void 0 : _this$device5$canvasC.resize({
341
+ useDevicePixels: this.props.useDevicePixels
342
+ });
343
+ }
344
+ }
345
+ _beginTimers() {
346
+ this.frameRate.timeEnd();
347
+ this.frameRate.timeStart();
348
+ }
349
+ _endTimers() {
350
+ this.cpuTime.timeEnd();
351
+ }
352
+ _startEventHandling() {
353
+ if (this.canvas) {
354
+ this.canvas.addEventListener('mousemove', this._onMousemove.bind(this));
355
+ this.canvas.addEventListener('mouseleave', this._onMouseleave.bind(this));
356
+ }
357
+ }
358
+ _onMousemove(event) {
359
+ if (event instanceof MouseEvent) {
360
+ this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY];
361
+ }
362
+ }
363
+ _onMouseleave(event) {
364
+ this._getAnimationProps()._mousePosition = null;
365
+ }
423
366
  }
367
+ //# sourceMappingURL=animation-loop.js.map