motion 12.3.1 → 12.4.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.
@@ -0,0 +1,291 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const activeAnimations = {
6
+ layout: 0,
7
+ mainThread: 0,
8
+ waapi: 0,
9
+ };
10
+
11
+ const statsBuffer = {
12
+ value: null,
13
+ addProjectionMetrics: null,
14
+ };
15
+
16
+ /*#__NO_SIDE_EFFECTS__*/
17
+ const noop = (any) => any;
18
+
19
+ if (process.env.NODE_ENV !== "production") ;
20
+
21
+ const stepsOrder = [
22
+ "read", // Read
23
+ "resolveKeyframes", // Write/Read/Write/Read
24
+ "update", // Compute
25
+ "preRender", // Compute
26
+ "render", // Write
27
+ "postRender", // Compute
28
+ ];
29
+
30
+ function createRenderStep(runNextFrame, stepName) {
31
+ /**
32
+ * We create and reuse two queues, one to queue jobs for the current frame
33
+ * and one for the next. We reuse to avoid triggering GC after x frames.
34
+ */
35
+ let thisFrame = new Set();
36
+ let nextFrame = new Set();
37
+ /**
38
+ * Track whether we're currently processing jobs in this step. This way
39
+ * we can decide whether to schedule new jobs for this frame or next.
40
+ */
41
+ let isProcessing = false;
42
+ let flushNextFrame = false;
43
+ /**
44
+ * A set of processes which were marked keepAlive when scheduled.
45
+ */
46
+ const toKeepAlive = new WeakSet();
47
+ let latestFrameData = {
48
+ delta: 0.0,
49
+ timestamp: 0.0,
50
+ isProcessing: false,
51
+ };
52
+ let numCalls = 0;
53
+ function triggerCallback(callback) {
54
+ if (toKeepAlive.has(callback)) {
55
+ step.schedule(callback);
56
+ runNextFrame();
57
+ }
58
+ numCalls++;
59
+ callback(latestFrameData);
60
+ }
61
+ const step = {
62
+ /**
63
+ * Schedule a process to run on the next frame.
64
+ */
65
+ schedule: (callback, keepAlive = false, immediate = false) => {
66
+ const addToCurrentFrame = immediate && isProcessing;
67
+ const queue = addToCurrentFrame ? thisFrame : nextFrame;
68
+ if (keepAlive)
69
+ toKeepAlive.add(callback);
70
+ if (!queue.has(callback))
71
+ queue.add(callback);
72
+ return callback;
73
+ },
74
+ /**
75
+ * Cancel the provided callback from running on the next frame.
76
+ */
77
+ cancel: (callback) => {
78
+ nextFrame.delete(callback);
79
+ toKeepAlive.delete(callback);
80
+ },
81
+ /**
82
+ * Execute all schedule callbacks.
83
+ */
84
+ process: (frameData) => {
85
+ latestFrameData = frameData;
86
+ /**
87
+ * If we're already processing we've probably been triggered by a flushSync
88
+ * inside an existing process. Instead of executing, mark flushNextFrame
89
+ * as true and ensure we flush the following frame at the end of this one.
90
+ */
91
+ if (isProcessing) {
92
+ flushNextFrame = true;
93
+ return;
94
+ }
95
+ isProcessing = true;
96
+ [thisFrame, nextFrame] = [nextFrame, thisFrame];
97
+ // Execute this frame
98
+ thisFrame.forEach(triggerCallback);
99
+ /**
100
+ * If we're recording stats then
101
+ */
102
+ if (stepName && statsBuffer.value) {
103
+ statsBuffer.value.frameloop[stepName].push(numCalls);
104
+ }
105
+ numCalls = 0;
106
+ // Clear the frame so no callbacks remain. This is to avoid
107
+ // memory leaks should this render step not run for a while.
108
+ thisFrame.clear();
109
+ isProcessing = false;
110
+ if (flushNextFrame) {
111
+ flushNextFrame = false;
112
+ step.process(frameData);
113
+ }
114
+ },
115
+ };
116
+ return step;
117
+ }
118
+
119
+ const maxElapsed = 40;
120
+ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
121
+ let runNextFrame = false;
122
+ let useDefaultElapsed = true;
123
+ const state = {
124
+ delta: 0.0,
125
+ timestamp: 0.0,
126
+ isProcessing: false,
127
+ };
128
+ const flagRunNextFrame = () => (runNextFrame = true);
129
+ const steps = stepsOrder.reduce((acc, key) => {
130
+ acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : undefined);
131
+ return acc;
132
+ }, {});
133
+ const { read, resolveKeyframes, update, preRender, render, postRender } = steps;
134
+ const processBatch = () => {
135
+ const timestamp = performance.now();
136
+ runNextFrame = false;
137
+ {
138
+ state.delta = useDefaultElapsed
139
+ ? 1000 / 60
140
+ : Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
141
+ }
142
+ state.timestamp = timestamp;
143
+ state.isProcessing = true;
144
+ // Unrolled render loop for better per-frame performance
145
+ read.process(state);
146
+ resolveKeyframes.process(state);
147
+ update.process(state);
148
+ preRender.process(state);
149
+ render.process(state);
150
+ postRender.process(state);
151
+ state.isProcessing = false;
152
+ if (runNextFrame && allowKeepAlive) {
153
+ useDefaultElapsed = false;
154
+ scheduleNextBatch(processBatch);
155
+ }
156
+ };
157
+ const wake = () => {
158
+ runNextFrame = true;
159
+ useDefaultElapsed = true;
160
+ if (!state.isProcessing) {
161
+ scheduleNextBatch(processBatch);
162
+ }
163
+ };
164
+ const schedule = stepsOrder.reduce((acc, key) => {
165
+ const step = steps[key];
166
+ acc[key] = (process, keepAlive = false, immediate = false) => {
167
+ if (!runNextFrame)
168
+ wake();
169
+ return step.schedule(process, keepAlive, immediate);
170
+ };
171
+ return acc;
172
+ }, {});
173
+ const cancel = (process) => {
174
+ for (let i = 0; i < stepsOrder.length; i++) {
175
+ steps[stepsOrder[i]].cancel(process);
176
+ }
177
+ };
178
+ return { schedule, cancel, state, steps };
179
+ }
180
+
181
+ const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps, } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
182
+
183
+ function record() {
184
+ const { value } = statsBuffer;
185
+ if (value === null) {
186
+ cancelFrame(record);
187
+ return;
188
+ }
189
+ value.frameloop.rate.push(frameData.delta);
190
+ value.animations.mainThread.push(activeAnimations.mainThread);
191
+ value.animations.waapi.push(activeAnimations.waapi);
192
+ value.animations.layout.push(activeAnimations.layout);
193
+ }
194
+ function mean(values) {
195
+ return values.reduce((acc, value) => acc + value, 0) / values.length;
196
+ }
197
+ function summarise(values, calcAverage = mean) {
198
+ if (values.length === 0) {
199
+ return {
200
+ min: 0,
201
+ max: 0,
202
+ avg: 0,
203
+ };
204
+ }
205
+ return {
206
+ min: Math.min(...values),
207
+ max: Math.max(...values),
208
+ avg: calcAverage(values),
209
+ };
210
+ }
211
+ const msToFps = (ms) => Math.round(1000 / ms);
212
+ function clearStatsBuffer() {
213
+ statsBuffer.value = null;
214
+ statsBuffer.addProjectionMetrics = null;
215
+ }
216
+ function reportStats() {
217
+ const { value } = statsBuffer;
218
+ if (!value) {
219
+ throw new Error("Stats are not being measured");
220
+ }
221
+ clearStatsBuffer();
222
+ cancelFrame(record);
223
+ const summary = {
224
+ frameloop: {
225
+ rate: summarise(value.frameloop.rate),
226
+ read: summarise(value.frameloop.read),
227
+ resolveKeyframes: summarise(value.frameloop.resolveKeyframes),
228
+ update: summarise(value.frameloop.update),
229
+ preRender: summarise(value.frameloop.preRender),
230
+ render: summarise(value.frameloop.render),
231
+ postRender: summarise(value.frameloop.postRender),
232
+ },
233
+ animations: {
234
+ mainThread: summarise(value.animations.mainThread),
235
+ waapi: summarise(value.animations.waapi),
236
+ layout: summarise(value.animations.layout),
237
+ },
238
+ layoutProjection: {
239
+ nodes: summarise(value.layoutProjection.nodes),
240
+ calculatedTargetDeltas: summarise(value.layoutProjection.calculatedTargetDeltas),
241
+ calculatedProjections: summarise(value.layoutProjection.calculatedProjections),
242
+ },
243
+ };
244
+ /**
245
+ * Convert the rate to FPS
246
+ */
247
+ const { rate } = summary.frameloop;
248
+ rate.min = msToFps(rate.min);
249
+ rate.max = msToFps(rate.max);
250
+ rate.avg = msToFps(rate.avg);
251
+ [rate.min, rate.max] = [rate.max, rate.min];
252
+ return summary;
253
+ }
254
+ function recordStats() {
255
+ if (statsBuffer.value) {
256
+ clearStatsBuffer();
257
+ throw new Error("Stats are already being measured");
258
+ }
259
+ const newStatsBuffer = statsBuffer;
260
+ newStatsBuffer.value = {
261
+ frameloop: {
262
+ rate: [],
263
+ read: [],
264
+ resolveKeyframes: [],
265
+ update: [],
266
+ preRender: [],
267
+ render: [],
268
+ postRender: [],
269
+ },
270
+ animations: {
271
+ mainThread: [],
272
+ waapi: [],
273
+ layout: [],
274
+ },
275
+ layoutProjection: {
276
+ nodes: [],
277
+ calculatedTargetDeltas: [],
278
+ calculatedProjections: [],
279
+ },
280
+ };
281
+ newStatsBuffer.addProjectionMetrics = (metrics) => {
282
+ const { layoutProjection } = newStatsBuffer.value;
283
+ layoutProjection.nodes.push(metrics.nodes);
284
+ layoutProjection.calculatedTargetDeltas.push(metrics.calculatedTargetDeltas);
285
+ layoutProjection.calculatedProjections.push(metrics.calculatedProjections);
286
+ };
287
+ frame.postRender(record, true);
288
+ return reportStats;
289
+ }
290
+
291
+ exports.recordStats = recordStats;
package/dist/cjs/index.js CHANGED
@@ -1318,7 +1318,21 @@ const MotionGlobalConfig = {
1318
1318
  useManualTiming: false,
1319
1319
  };
1320
1320
 
1321
- function createRenderStep(runNextFrame) {
1321
+ const stepsOrder = [
1322
+ "read", // Read
1323
+ "resolveKeyframes", // Write/Read/Write/Read
1324
+ "update", // Compute
1325
+ "preRender", // Compute
1326
+ "render", // Write
1327
+ "postRender", // Compute
1328
+ ];
1329
+
1330
+ const statsBuffer = {
1331
+ value: null,
1332
+ addProjectionMetrics: null,
1333
+ };
1334
+
1335
+ function createRenderStep(runNextFrame, stepName) {
1322
1336
  /**
1323
1337
  * We create and reuse two queues, one to queue jobs for the current frame
1324
1338
  * and one for the next. We reuse to avoid triggering GC after x frames.
@@ -1340,11 +1354,13 @@ function createRenderStep(runNextFrame) {
1340
1354
  timestamp: 0.0,
1341
1355
  isProcessing: false,
1342
1356
  };
1357
+ let numCalls = 0;
1343
1358
  function triggerCallback(callback) {
1344
1359
  if (toKeepAlive.has(callback)) {
1345
1360
  step.schedule(callback);
1346
1361
  runNextFrame();
1347
1362
  }
1363
+ numCalls++;
1348
1364
  callback(latestFrameData);
1349
1365
  }
1350
1366
  const step = {
@@ -1385,6 +1401,13 @@ function createRenderStep(runNextFrame) {
1385
1401
  [thisFrame, nextFrame] = [nextFrame, thisFrame];
1386
1402
  // Execute this frame
1387
1403
  thisFrame.forEach(triggerCallback);
1404
+ /**
1405
+ * If we're recording stats then
1406
+ */
1407
+ if (stepName && statsBuffer.value) {
1408
+ statsBuffer.value.frameloop[stepName].push(numCalls);
1409
+ }
1410
+ numCalls = 0;
1388
1411
  // Clear the frame so no callbacks remain. This is to avoid
1389
1412
  // memory leaks should this render step not run for a while.
1390
1413
  thisFrame.clear();
@@ -1398,14 +1421,6 @@ function createRenderStep(runNextFrame) {
1398
1421
  return step;
1399
1422
  }
1400
1423
 
1401
- const stepsOrder = [
1402
- "read", // Read
1403
- "resolveKeyframes", // Write/Read/Write/Read
1404
- "update", // Compute
1405
- "preRender", // Compute
1406
- "render", // Write
1407
- "postRender", // Compute
1408
- ];
1409
1424
  const maxElapsed$1 = 40;
1410
1425
  function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
1411
1426
  let runNextFrame = false;
@@ -1417,16 +1432,18 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
1417
1432
  };
1418
1433
  const flagRunNextFrame = () => (runNextFrame = true);
1419
1434
  const steps = stepsOrder.reduce((acc, key) => {
1420
- acc[key] = createRenderStep(flagRunNextFrame);
1435
+ acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : undefined);
1421
1436
  return acc;
1422
1437
  }, {});
1423
1438
  const { read, resolveKeyframes, update, preRender, render, postRender } = steps;
1424
1439
  const processBatch = () => {
1425
1440
  const timestamp = performance.now();
1426
1441
  runNextFrame = false;
1427
- state.delta = useDefaultElapsed
1428
- ? 1000 / 60
1429
- : Math.max(Math.min(timestamp - state.timestamp, maxElapsed$1), 1);
1442
+ {
1443
+ state.delta = useDefaultElapsed
1444
+ ? 1000 / 60
1445
+ : Math.max(Math.min(timestamp - state.timestamp, maxElapsed$1), 1);
1446
+ }
1430
1447
  state.timestamp = timestamp;
1431
1448
  state.isProcessing = true;
1432
1449
  // Unrolled render loop for better per-frame performance
@@ -1569,7 +1586,7 @@ class MotionValue {
1569
1586
  * This will be replaced by the build step with the latest version number.
1570
1587
  * When MotionValues are provided to motion components, warn if versions are mixed.
1571
1588
  */
1572
- this.version = "12.3.1";
1589
+ this.version = "12.4.0";
1573
1590
  /**
1574
1591
  * Tracks whether this value can output a velocity. Currently this is only true
1575
1592
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -3868,7 +3885,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
3868
3885
  */
3869
3886
  if (Array.isArray(easing))
3870
3887
  keyframeOptions.easing = easing;
3871
- return element.animate(keyframeOptions, {
3888
+ const animation = element.animate(keyframeOptions, {
3872
3889
  delay,
3873
3890
  duration,
3874
3891
  easing: !Array.isArray(easing) ? easing : "linear",
@@ -3876,6 +3893,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
3876
3893
  iterations: repeat + 1,
3877
3894
  direction: repeatType === "reverse" ? "alternate" : "normal",
3878
3895
  });
3896
+ return animation;
3879
3897
  }
3880
3898
 
3881
3899
  const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
@@ -4503,7 +4521,7 @@ function updateMotionValuesFromProps(element, next, prev) {
4503
4521
  * and warn against mismatches.
4504
4522
  */
4505
4523
  if (process.env.NODE_ENV === "development") {
4506
- warnOnce(nextValue.version === "12.3.1", `Attempting to mix Motion versions ${nextValue.version} with 12.3.1 may not work as expected.`);
4524
+ warnOnce(nextValue.version === "12.4.0", `Attempting to mix Motion versions ${nextValue.version} with 12.4.0 may not work as expected.`);
4507
4525
  }
4508
4526
  }
4509
4527
  else if (isMotionValue(prevValue)) {
package/dist/cjs/mini.js CHANGED
@@ -764,7 +764,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
764
764
  */
765
765
  if (Array.isArray(easing))
766
766
  keyframeOptions.easing = easing;
767
- return element.animate(keyframeOptions, {
767
+ const animation = element.animate(keyframeOptions, {
768
768
  delay,
769
769
  duration,
770
770
  easing: !Array.isArray(easing) ? easing : "linear",
@@ -772,6 +772,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
772
772
  iterations: repeat + 1,
773
773
  direction: repeatType === "reverse" ? "alternate" : "normal",
774
774
  });
775
+ return animation;
775
776
  }
776
777
 
777
778
  const createUnitType = (unit) => ({
@@ -614,7 +614,21 @@ const MotionGlobalConfig = {
614
614
  useManualTiming: false,
615
615
  };
616
616
 
617
- function createRenderStep(runNextFrame) {
617
+ const stepsOrder = [
618
+ "read", // Read
619
+ "resolveKeyframes", // Write/Read/Write/Read
620
+ "update", // Compute
621
+ "preRender", // Compute
622
+ "render", // Write
623
+ "postRender", // Compute
624
+ ];
625
+
626
+ const statsBuffer = {
627
+ value: null,
628
+ addProjectionMetrics: null,
629
+ };
630
+
631
+ function createRenderStep(runNextFrame, stepName) {
618
632
  /**
619
633
  * We create and reuse two queues, one to queue jobs for the current frame
620
634
  * and one for the next. We reuse to avoid triggering GC after x frames.
@@ -636,11 +650,13 @@ function createRenderStep(runNextFrame) {
636
650
  timestamp: 0.0,
637
651
  isProcessing: false,
638
652
  };
653
+ let numCalls = 0;
639
654
  function triggerCallback(callback) {
640
655
  if (toKeepAlive.has(callback)) {
641
656
  step.schedule(callback);
642
657
  runNextFrame();
643
658
  }
659
+ numCalls++;
644
660
  callback(latestFrameData);
645
661
  }
646
662
  const step = {
@@ -681,6 +697,13 @@ function createRenderStep(runNextFrame) {
681
697
  [thisFrame, nextFrame] = [nextFrame, thisFrame];
682
698
  // Execute this frame
683
699
  thisFrame.forEach(triggerCallback);
700
+ /**
701
+ * If we're recording stats then
702
+ */
703
+ if (stepName && statsBuffer.value) {
704
+ statsBuffer.value.frameloop[stepName].push(numCalls);
705
+ }
706
+ numCalls = 0;
684
707
  // Clear the frame so no callbacks remain. This is to avoid
685
708
  // memory leaks should this render step not run for a while.
686
709
  thisFrame.clear();
@@ -694,14 +717,6 @@ function createRenderStep(runNextFrame) {
694
717
  return step;
695
718
  }
696
719
 
697
- const stepsOrder = [
698
- "read", // Read
699
- "resolveKeyframes", // Write/Read/Write/Read
700
- "update", // Compute
701
- "preRender", // Compute
702
- "render", // Write
703
- "postRender", // Compute
704
- ];
705
720
  const maxElapsed = 40;
706
721
  function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
707
722
  let runNextFrame = false;
@@ -713,16 +728,18 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
713
728
  };
714
729
  const flagRunNextFrame = () => (runNextFrame = true);
715
730
  const steps = stepsOrder.reduce((acc, key) => {
716
- acc[key] = createRenderStep(flagRunNextFrame);
731
+ acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : undefined);
717
732
  return acc;
718
733
  }, {});
719
734
  const { read, resolveKeyframes, update, preRender, render, postRender } = steps;
720
735
  const processBatch = () => {
721
736
  const timestamp = performance.now();
722
737
  runNextFrame = false;
723
- state.delta = useDefaultElapsed
724
- ? 1000 / 60
725
- : Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
738
+ {
739
+ state.delta = useDefaultElapsed
740
+ ? 1000 / 60
741
+ : Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
742
+ }
726
743
  state.timestamp = timestamp;
727
744
  state.isProcessing = true;
728
745
  // Unrolled render loop for better per-frame performance
@@ -885,7 +902,7 @@ class MotionValue {
885
902
  * This will be replaced by the build step with the latest version number.
886
903
  * When MotionValues are provided to motion components, warn if versions are mixed.
887
904
  */
888
- this.version = "12.3.1";
905
+ this.version = "12.4.0";
889
906
  /**
890
907
  * Tracks whether this value can output a velocity. Currently this is only true
891
908
  * if the value is numerical, but we might be able to widen the scope here and support
@@ -3467,7 +3484,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
3467
3484
  */
3468
3485
  if (Array.isArray(easing))
3469
3486
  keyframeOptions.easing = easing;
3470
- return element.animate(keyframeOptions, {
3487
+ const animation = element.animate(keyframeOptions, {
3471
3488
  delay,
3472
3489
  duration,
3473
3490
  easing: !Array.isArray(easing) ? easing : "linear",
@@ -3475,6 +3492,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
3475
3492
  iterations: repeat + 1,
3476
3493
  direction: repeatType === "reverse" ? "alternate" : "normal",
3477
3494
  });
3495
+ return animation;
3478
3496
  }
3479
3497
 
3480
3498
  const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
@@ -6306,13 +6324,6 @@ function buildProjectionTransform(delta, treeScale, latestTransform) {
6306
6324
  return transform || "none";
6307
6325
  }
6308
6326
 
6309
- const metrics = {
6310
- type: "projectionFrame",
6311
- totalNodes: 0,
6312
- resolvedTargetDeltas: 0,
6313
- recalculatedProjection: 0,
6314
- };
6315
- const isDebug = typeof window !== "undefined" && window.MotionDebug !== undefined;
6316
6327
  const transformAxes = ["", "X", "Y", "Z"];
6317
6328
  const hiddenVisibility = { visibility: "hidden" };
6318
6329
  /**
@@ -6462,23 +6473,10 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
6462
6473
  */
6463
6474
  this.updateProjection = () => {
6464
6475
  this.projectionUpdateScheduled = false;
6465
- /**
6466
- * Reset debug counts. Manually resetting rather than creating a new
6467
- * object each frame.
6468
- */
6469
- if (isDebug) {
6470
- metrics.totalNodes =
6471
- metrics.resolvedTargetDeltas =
6472
- metrics.recalculatedProjection =
6473
- 0;
6474
- }
6475
6476
  this.nodes.forEach(propagateDirtyNodes);
6476
6477
  this.nodes.forEach(resolveTargetDelta);
6477
6478
  this.nodes.forEach(calcProjection);
6478
6479
  this.nodes.forEach(cleanDirtyNodes);
6479
- if (isDebug) {
6480
- window.MotionDebug.record(metrics);
6481
- }
6482
6480
  };
6483
6481
  /**
6484
6482
  * Frame calculations
@@ -7121,12 +7119,6 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
7121
7119
  this.relativeParent = this.relativeTarget = undefined;
7122
7120
  }
7123
7121
  }
7124
- /**
7125
- * Increase debug counter for resolved target deltas
7126
- */
7127
- if (isDebug) {
7128
- metrics.resolvedTargetDeltas++;
7129
- }
7130
7122
  }
7131
7123
  getClosestProjectingParent() {
7132
7124
  if (!this.parent ||
@@ -7252,12 +7244,6 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
7252
7244
  this.scheduleRender();
7253
7245
  this.notifyListeners("projectionUpdate", target);
7254
7246
  }
7255
- /**
7256
- * Increase debug counter for recalculated projections
7257
- */
7258
- if (isDebug) {
7259
- metrics.recalculatedProjection++;
7260
- }
7261
7247
  }
7262
7248
  hide() {
7263
7249
  this.isVisible = false;
@@ -7364,6 +7350,8 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
7364
7350
  this.mixTargetDelta(latest);
7365
7351
  options.onUpdate && options.onUpdate(latest);
7366
7352
  },
7353
+ onStop: () => {
7354
+ },
7367
7355
  onComplete: () => {
7368
7356
  options.onComplete && options.onComplete();
7369
7357
  this.completeAnimation();
@@ -7761,12 +7749,6 @@ function notifyLayoutUpdate(node) {
7761
7749
  node.options.transition = undefined;
7762
7750
  }
7763
7751
  function propagateDirtyNodes(node) {
7764
- /**
7765
- * Increase debug counter for nodes encountered this frame
7766
- */
7767
- if (isDebug) {
7768
- metrics.totalNodes++;
7769
- }
7770
7752
  if (!node.parent)
7771
7753
  return;
7772
7754
  /**
@@ -9266,7 +9248,7 @@ function updateMotionValuesFromProps(element, next, prev) {
9266
9248
  * and warn against mismatches.
9267
9249
  */
9268
9250
  if (process.env.NODE_ENV === "development") {
9269
- warnOnce(nextValue.version === "12.3.1", `Attempting to mix Motion versions ${nextValue.version} with 12.3.1 may not work as expected.`);
9251
+ warnOnce(nextValue.version === "12.4.0", `Attempting to mix Motion versions ${nextValue.version} with 12.4.0 may not work as expected.`);
9270
9252
  }
9271
9253
  }
9272
9254
  else if (isMotionValue(prevValue)) {