motion 12.3.1 → 12.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/debug.js +291 -0
- package/dist/cjs/index.js +34 -16
- package/dist/cjs/mini.js +2 -1
- package/dist/cjs/react-client.js +48 -54
- package/dist/cjs/react-m.js +30 -13
- package/dist/cjs/react-mini.js +2 -1
- package/dist/debug.d.ts +1 -0
- package/dist/es/framer-motion/dist/es/animation/animators/MainThreadAnimation.mjs +3 -0
- package/dist/es/framer-motion/dist/es/animation/animators/waapi/index.mjs +12 -1
- package/dist/es/framer-motion/dist/es/frameloop/batcher.mjs +8 -13
- package/dist/es/framer-motion/dist/es/frameloop/index-legacy.mjs +1 -1
- package/dist/es/framer-motion/dist/es/frameloop/order.mjs +10 -0
- package/dist/es/framer-motion/dist/es/frameloop/render-step.mjs +12 -1
- package/dist/es/framer-motion/dist/es/projection/node/create-projection-node.mjs +22 -17
- package/dist/es/framer-motion/dist/es/render/utils/animation-state.mjs +12 -0
- package/dist/es/framer-motion/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/framer-motion/dist/es/stats/animation-count.mjs +7 -0
- package/dist/es/framer-motion/dist/es/stats/buffer.mjs +6 -0
- package/dist/es/framer-motion/dist/es/stats/index.mjs +113 -0
- package/dist/es/framer-motion/dist/es/utils/use-in-view.mjs +2 -2
- package/dist/es/framer-motion/dist/es/value/index.mjs +1 -1
- package/dist/es/motion/lib/debug.mjs +1 -0
- package/dist/motion.dev.js +34 -16
- package/dist/motion.js +1 -1
- package/package.json +9 -3
|
@@ -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
|
-
|
|
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
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
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.
|
|
1589
|
+
this.version = "12.4.1";
|
|
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
|
-
|
|
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.
|
|
4524
|
+
warnOnce(nextValue.version === "12.4.1", `Attempting to mix Motion versions ${nextValue.version} with 12.4.1 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
|
-
|
|
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) => ({
|
package/dist/cjs/react-client.js
CHANGED
|
@@ -614,7 +614,21 @@ const MotionGlobalConfig = {
|
|
|
614
614
|
useManualTiming: false,
|
|
615
615
|
};
|
|
616
616
|
|
|
617
|
-
|
|
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
|
-
|
|
724
|
-
|
|
725
|
-
|
|
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.
|
|
905
|
+
this.version = "12.4.1";
|
|
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
|
-
|
|
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"));
|
|
@@ -4372,6 +4390,18 @@ function createAnimationState(visualElement) {
|
|
|
4372
4390
|
*/
|
|
4373
4391
|
if (removedKeys.size) {
|
|
4374
4392
|
const fallbackAnimation = {};
|
|
4393
|
+
/**
|
|
4394
|
+
* If the initial prop contains a transition we can use that, otherwise
|
|
4395
|
+
* allow the animation function to use the visual element's default.
|
|
4396
|
+
*/
|
|
4397
|
+
if (typeof props.initial !== "boolean") {
|
|
4398
|
+
const initialTransition = resolveVariant(visualElement, Array.isArray(props.initial)
|
|
4399
|
+
? props.initial[0]
|
|
4400
|
+
: props.initial);
|
|
4401
|
+
if (initialTransition && initialTransition.transition) {
|
|
4402
|
+
fallbackAnimation.transition = initialTransition.transition;
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4375
4405
|
removedKeys.forEach((key) => {
|
|
4376
4406
|
const fallbackTarget = visualElement.getBaseTarget(key);
|
|
4377
4407
|
const motionValue = visualElement.getValue(key);
|
|
@@ -6306,13 +6336,6 @@ function buildProjectionTransform(delta, treeScale, latestTransform) {
|
|
|
6306
6336
|
return transform || "none";
|
|
6307
6337
|
}
|
|
6308
6338
|
|
|
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
6339
|
const transformAxes = ["", "X", "Y", "Z"];
|
|
6317
6340
|
const hiddenVisibility = { visibility: "hidden" };
|
|
6318
6341
|
/**
|
|
@@ -6462,23 +6485,10 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
6462
6485
|
*/
|
|
6463
6486
|
this.updateProjection = () => {
|
|
6464
6487
|
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
6488
|
this.nodes.forEach(propagateDirtyNodes);
|
|
6476
6489
|
this.nodes.forEach(resolveTargetDelta);
|
|
6477
6490
|
this.nodes.forEach(calcProjection);
|
|
6478
6491
|
this.nodes.forEach(cleanDirtyNodes);
|
|
6479
|
-
if (isDebug) {
|
|
6480
|
-
window.MotionDebug.record(metrics);
|
|
6481
|
-
}
|
|
6482
6492
|
};
|
|
6483
6493
|
/**
|
|
6484
6494
|
* Frame calculations
|
|
@@ -7121,12 +7131,6 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
7121
7131
|
this.relativeParent = this.relativeTarget = undefined;
|
|
7122
7132
|
}
|
|
7123
7133
|
}
|
|
7124
|
-
/**
|
|
7125
|
-
* Increase debug counter for resolved target deltas
|
|
7126
|
-
*/
|
|
7127
|
-
if (isDebug) {
|
|
7128
|
-
metrics.resolvedTargetDeltas++;
|
|
7129
|
-
}
|
|
7130
7134
|
}
|
|
7131
7135
|
getClosestProjectingParent() {
|
|
7132
7136
|
if (!this.parent ||
|
|
@@ -7252,12 +7256,6 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
7252
7256
|
this.scheduleRender();
|
|
7253
7257
|
this.notifyListeners("projectionUpdate", target);
|
|
7254
7258
|
}
|
|
7255
|
-
/**
|
|
7256
|
-
* Increase debug counter for recalculated projections
|
|
7257
|
-
*/
|
|
7258
|
-
if (isDebug) {
|
|
7259
|
-
metrics.recalculatedProjection++;
|
|
7260
|
-
}
|
|
7261
7259
|
}
|
|
7262
7260
|
hide() {
|
|
7263
7261
|
this.isVisible = false;
|
|
@@ -7364,6 +7362,8 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
7364
7362
|
this.mixTargetDelta(latest);
|
|
7365
7363
|
options.onUpdate && options.onUpdate(latest);
|
|
7366
7364
|
},
|
|
7365
|
+
onStop: () => {
|
|
7366
|
+
},
|
|
7367
7367
|
onComplete: () => {
|
|
7368
7368
|
options.onComplete && options.onComplete();
|
|
7369
7369
|
this.completeAnimation();
|
|
@@ -7761,12 +7761,6 @@ function notifyLayoutUpdate(node) {
|
|
|
7761
7761
|
node.options.transition = undefined;
|
|
7762
7762
|
}
|
|
7763
7763
|
function propagateDirtyNodes(node) {
|
|
7764
|
-
/**
|
|
7765
|
-
* Increase debug counter for nodes encountered this frame
|
|
7766
|
-
*/
|
|
7767
|
-
if (isDebug) {
|
|
7768
|
-
metrics.totalNodes++;
|
|
7769
|
-
}
|
|
7770
7764
|
if (!node.parent)
|
|
7771
7765
|
return;
|
|
7772
7766
|
/**
|
|
@@ -9266,7 +9260,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
9266
9260
|
* and warn against mismatches.
|
|
9267
9261
|
*/
|
|
9268
9262
|
if (process.env.NODE_ENV === "development") {
|
|
9269
|
-
warnOnce(nextValue.version === "12.
|
|
9263
|
+
warnOnce(nextValue.version === "12.4.1", `Attempting to mix Motion versions ${nextValue.version} with 12.4.1 may not work as expected.`);
|
|
9270
9264
|
}
|
|
9271
9265
|
}
|
|
9272
9266
|
else if (isMotionValue(prevValue)) {
|