framer-motion 12.3.0 → 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.
- package/dist/cjs/client.js +1 -1
- package/dist/cjs/{create-C54gSMJp.js → create-BUi_omOK.js} +36 -54
- package/dist/cjs/debug.js +288 -0
- package/dist/cjs/dom-mini.js +3 -2
- package/dist/cjs/dom.js +35 -17
- package/dist/cjs/index.js +27 -27
- package/dist/cjs/m.js +30 -13
- package/dist/cjs/mini.js +3 -2
- package/dist/debug.d.ts +35 -0
- package/dist/dom-mini.js +1 -1
- package/dist/dom.js +1 -1
- package/dist/es/animation/animators/MainThreadAnimation.mjs +3 -0
- package/dist/es/animation/animators/waapi/index.mjs +12 -1
- package/dist/es/animation/animators/waapi/utils/style.mjs +1 -1
- package/dist/es/debug.mjs +1 -0
- package/dist/es/frameloop/batcher.mjs +8 -13
- package/dist/es/frameloop/index-legacy.mjs +1 -1
- package/dist/es/frameloop/order.mjs +10 -0
- package/dist/es/frameloop/render-step.mjs +12 -1
- package/dist/es/projection/node/create-projection-node.mjs +22 -17
- package/dist/es/projection.mjs +8 -6
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/stats/animation-count.mjs +7 -0
- package/dist/es/stats/buffer.mjs +6 -0
- package/dist/es/stats/index.mjs +113 -0
- package/dist/es/utils/use-in-view.mjs +2 -2
- package/dist/es/value/index.mjs +1 -1
- package/dist/framer-motion.dev.js +62 -80
- package/dist/framer-motion.js +1 -1
- package/dist/mini.js +1 -1
- package/dist/types/index.d.ts +2 -1
- package/package.json +8 -2
package/dist/cjs/client.js
CHANGED
|
@@ -58,7 +58,21 @@ const MotionGlobalConfig = {
|
|
|
58
58
|
useManualTiming: false,
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
const stepsOrder = [
|
|
62
|
+
"read", // Read
|
|
63
|
+
"resolveKeyframes", // Write/Read/Write/Read
|
|
64
|
+
"update", // Compute
|
|
65
|
+
"preRender", // Compute
|
|
66
|
+
"render", // Write
|
|
67
|
+
"postRender", // Compute
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
const statsBuffer = {
|
|
71
|
+
value: null,
|
|
72
|
+
addProjectionMetrics: null,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
function createRenderStep(runNextFrame, stepName) {
|
|
62
76
|
/**
|
|
63
77
|
* We create and reuse two queues, one to queue jobs for the current frame
|
|
64
78
|
* and one for the next. We reuse to avoid triggering GC after x frames.
|
|
@@ -80,11 +94,13 @@ function createRenderStep(runNextFrame) {
|
|
|
80
94
|
timestamp: 0.0,
|
|
81
95
|
isProcessing: false,
|
|
82
96
|
};
|
|
97
|
+
let numCalls = 0;
|
|
83
98
|
function triggerCallback(callback) {
|
|
84
99
|
if (toKeepAlive.has(callback)) {
|
|
85
100
|
step.schedule(callback);
|
|
86
101
|
runNextFrame();
|
|
87
102
|
}
|
|
103
|
+
numCalls++;
|
|
88
104
|
callback(latestFrameData);
|
|
89
105
|
}
|
|
90
106
|
const step = {
|
|
@@ -125,6 +141,13 @@ function createRenderStep(runNextFrame) {
|
|
|
125
141
|
[thisFrame, nextFrame] = [nextFrame, thisFrame];
|
|
126
142
|
// Execute this frame
|
|
127
143
|
thisFrame.forEach(triggerCallback);
|
|
144
|
+
/**
|
|
145
|
+
* If we're recording stats then
|
|
146
|
+
*/
|
|
147
|
+
if (stepName && statsBuffer.value) {
|
|
148
|
+
statsBuffer.value.frameloop[stepName].push(numCalls);
|
|
149
|
+
}
|
|
150
|
+
numCalls = 0;
|
|
128
151
|
// Clear the frame so no callbacks remain. This is to avoid
|
|
129
152
|
// memory leaks should this render step not run for a while.
|
|
130
153
|
thisFrame.clear();
|
|
@@ -138,14 +161,6 @@ function createRenderStep(runNextFrame) {
|
|
|
138
161
|
return step;
|
|
139
162
|
}
|
|
140
163
|
|
|
141
|
-
const stepsOrder = [
|
|
142
|
-
"read", // Read
|
|
143
|
-
"resolveKeyframes", // Write/Read/Write/Read
|
|
144
|
-
"update", // Compute
|
|
145
|
-
"preRender", // Compute
|
|
146
|
-
"render", // Write
|
|
147
|
-
"postRender", // Compute
|
|
148
|
-
];
|
|
149
164
|
const maxElapsed = 40;
|
|
150
165
|
function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
|
|
151
166
|
let runNextFrame = false;
|
|
@@ -157,7 +172,7 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
|
|
|
157
172
|
};
|
|
158
173
|
const flagRunNextFrame = () => (runNextFrame = true);
|
|
159
174
|
const steps = stepsOrder.reduce((acc, key) => {
|
|
160
|
-
acc[key] = createRenderStep(flagRunNextFrame);
|
|
175
|
+
acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : undefined);
|
|
161
176
|
return acc;
|
|
162
177
|
}, {});
|
|
163
178
|
const { read, resolveKeyframes, update, preRender, render, postRender } = steps;
|
|
@@ -166,9 +181,11 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
|
|
|
166
181
|
? state.timestamp
|
|
167
182
|
: performance.now();
|
|
168
183
|
runNextFrame = false;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
184
|
+
if (!MotionGlobalConfig.useManualTiming) {
|
|
185
|
+
state.delta = useDefaultElapsed
|
|
186
|
+
? 1000 / 60
|
|
187
|
+
: Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
|
|
188
|
+
}
|
|
172
189
|
state.timestamp = timestamp;
|
|
173
190
|
state.isProcessing = true;
|
|
174
191
|
// Unrolled render loop for better per-frame performance
|
|
@@ -393,7 +410,7 @@ class MotionValue {
|
|
|
393
410
|
* This will be replaced by the build step with the latest version number.
|
|
394
411
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
395
412
|
*/
|
|
396
|
-
this.version = "12.
|
|
413
|
+
this.version = "12.4.0";
|
|
397
414
|
/**
|
|
398
415
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
399
416
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -2986,7 +3003,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
|
|
|
2986
3003
|
*/
|
|
2987
3004
|
if (Array.isArray(easing))
|
|
2988
3005
|
keyframeOptions.easing = easing;
|
|
2989
|
-
|
|
3006
|
+
const animation = element.animate(keyframeOptions, {
|
|
2990
3007
|
delay,
|
|
2991
3008
|
duration,
|
|
2992
3009
|
easing: !Array.isArray(easing) ? easing : "linear",
|
|
@@ -2994,6 +3011,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
|
|
|
2994
3011
|
iterations: repeat + 1,
|
|
2995
3012
|
direction: repeatType === "reverse" ? "alternate" : "normal",
|
|
2996
3013
|
});
|
|
3014
|
+
return animation;
|
|
2997
3015
|
}
|
|
2998
3016
|
|
|
2999
3017
|
const supportsWaapi = /*@__PURE__*/ motionUtils.memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
|
|
@@ -4538,7 +4556,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
4538
4556
|
* and warn against mismatches.
|
|
4539
4557
|
*/
|
|
4540
4558
|
if (process.env.NODE_ENV === "development") {
|
|
4541
|
-
warnOnce(nextValue.version === "12.
|
|
4559
|
+
warnOnce(nextValue.version === "12.4.0", `Attempting to mix Motion versions ${nextValue.version} with 12.4.0 may not work as expected.`);
|
|
4542
4560
|
}
|
|
4543
4561
|
}
|
|
4544
4562
|
else if (isMotionValue(prevValue)) {
|
|
@@ -6080,13 +6098,6 @@ const globalProjectionState = {
|
|
|
6080
6098
|
hasEverUpdated: false,
|
|
6081
6099
|
};
|
|
6082
6100
|
|
|
6083
|
-
const metrics = {
|
|
6084
|
-
type: "projectionFrame",
|
|
6085
|
-
totalNodes: 0,
|
|
6086
|
-
resolvedTargetDeltas: 0,
|
|
6087
|
-
recalculatedProjection: 0,
|
|
6088
|
-
};
|
|
6089
|
-
const isDebug = typeof window !== "undefined" && window.MotionDebug !== undefined;
|
|
6090
6101
|
const transformAxes = ["", "X", "Y", "Z"];
|
|
6091
6102
|
const hiddenVisibility = { visibility: "hidden" };
|
|
6092
6103
|
/**
|
|
@@ -6236,23 +6247,10 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
6236
6247
|
*/
|
|
6237
6248
|
this.updateProjection = () => {
|
|
6238
6249
|
this.projectionUpdateScheduled = false;
|
|
6239
|
-
/**
|
|
6240
|
-
* Reset debug counts. Manually resetting rather than creating a new
|
|
6241
|
-
* object each frame.
|
|
6242
|
-
*/
|
|
6243
|
-
if (isDebug) {
|
|
6244
|
-
metrics.totalNodes =
|
|
6245
|
-
metrics.resolvedTargetDeltas =
|
|
6246
|
-
metrics.recalculatedProjection =
|
|
6247
|
-
0;
|
|
6248
|
-
}
|
|
6249
6250
|
this.nodes.forEach(propagateDirtyNodes);
|
|
6250
6251
|
this.nodes.forEach(resolveTargetDelta);
|
|
6251
6252
|
this.nodes.forEach(calcProjection);
|
|
6252
6253
|
this.nodes.forEach(cleanDirtyNodes);
|
|
6253
|
-
if (isDebug) {
|
|
6254
|
-
window.MotionDebug.record(metrics);
|
|
6255
|
-
}
|
|
6256
6254
|
};
|
|
6257
6255
|
/**
|
|
6258
6256
|
* Frame calculations
|
|
@@ -6895,12 +6893,6 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
6895
6893
|
this.relativeParent = this.relativeTarget = undefined;
|
|
6896
6894
|
}
|
|
6897
6895
|
}
|
|
6898
|
-
/**
|
|
6899
|
-
* Increase debug counter for resolved target deltas
|
|
6900
|
-
*/
|
|
6901
|
-
if (isDebug) {
|
|
6902
|
-
metrics.resolvedTargetDeltas++;
|
|
6903
|
-
}
|
|
6904
6896
|
}
|
|
6905
6897
|
getClosestProjectingParent() {
|
|
6906
6898
|
if (!this.parent ||
|
|
@@ -7026,12 +7018,6 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
7026
7018
|
this.scheduleRender();
|
|
7027
7019
|
this.notifyListeners("projectionUpdate", target);
|
|
7028
7020
|
}
|
|
7029
|
-
/**
|
|
7030
|
-
* Increase debug counter for recalculated projections
|
|
7031
|
-
*/
|
|
7032
|
-
if (isDebug) {
|
|
7033
|
-
metrics.recalculatedProjection++;
|
|
7034
|
-
}
|
|
7035
7021
|
}
|
|
7036
7022
|
hide() {
|
|
7037
7023
|
this.isVisible = false;
|
|
@@ -7138,6 +7124,8 @@ function createProjectionNode$1({ attachResizeListener, defaultParent, measureSc
|
|
|
7138
7124
|
this.mixTargetDelta(latest);
|
|
7139
7125
|
options.onUpdate && options.onUpdate(latest);
|
|
7140
7126
|
},
|
|
7127
|
+
onStop: () => {
|
|
7128
|
+
},
|
|
7141
7129
|
onComplete: () => {
|
|
7142
7130
|
options.onComplete && options.onComplete();
|
|
7143
7131
|
this.completeAnimation();
|
|
@@ -7535,12 +7523,6 @@ function notifyLayoutUpdate(node) {
|
|
|
7535
7523
|
node.options.transition = undefined;
|
|
7536
7524
|
}
|
|
7537
7525
|
function propagateDirtyNodes(node) {
|
|
7538
|
-
/**
|
|
7539
|
-
* Increase debug counter for nodes encountered this frame
|
|
7540
|
-
*/
|
|
7541
|
-
if (isDebug) {
|
|
7542
|
-
metrics.totalNodes++;
|
|
7543
|
-
}
|
|
7544
7526
|
if (!node.parent)
|
|
7545
7527
|
return;
|
|
7546
7528
|
/**
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var motionUtils = require('motion-utils');
|
|
6
|
+
|
|
7
|
+
const stepsOrder = [
|
|
8
|
+
"read", // Read
|
|
9
|
+
"resolveKeyframes", // Write/Read/Write/Read
|
|
10
|
+
"update", // Compute
|
|
11
|
+
"preRender", // Compute
|
|
12
|
+
"render", // Write
|
|
13
|
+
"postRender", // Compute
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const statsBuffer = {
|
|
17
|
+
value: null,
|
|
18
|
+
addProjectionMetrics: null,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function createRenderStep(runNextFrame, stepName) {
|
|
22
|
+
/**
|
|
23
|
+
* We create and reuse two queues, one to queue jobs for the current frame
|
|
24
|
+
* and one for the next. We reuse to avoid triggering GC after x frames.
|
|
25
|
+
*/
|
|
26
|
+
let thisFrame = new Set();
|
|
27
|
+
let nextFrame = new Set();
|
|
28
|
+
/**
|
|
29
|
+
* Track whether we're currently processing jobs in this step. This way
|
|
30
|
+
* we can decide whether to schedule new jobs for this frame or next.
|
|
31
|
+
*/
|
|
32
|
+
let isProcessing = false;
|
|
33
|
+
let flushNextFrame = false;
|
|
34
|
+
/**
|
|
35
|
+
* A set of processes which were marked keepAlive when scheduled.
|
|
36
|
+
*/
|
|
37
|
+
const toKeepAlive = new WeakSet();
|
|
38
|
+
let latestFrameData = {
|
|
39
|
+
delta: 0.0,
|
|
40
|
+
timestamp: 0.0,
|
|
41
|
+
isProcessing: false,
|
|
42
|
+
};
|
|
43
|
+
let numCalls = 0;
|
|
44
|
+
function triggerCallback(callback) {
|
|
45
|
+
if (toKeepAlive.has(callback)) {
|
|
46
|
+
step.schedule(callback);
|
|
47
|
+
runNextFrame();
|
|
48
|
+
}
|
|
49
|
+
numCalls++;
|
|
50
|
+
callback(latestFrameData);
|
|
51
|
+
}
|
|
52
|
+
const step = {
|
|
53
|
+
/**
|
|
54
|
+
* Schedule a process to run on the next frame.
|
|
55
|
+
*/
|
|
56
|
+
schedule: (callback, keepAlive = false, immediate = false) => {
|
|
57
|
+
const addToCurrentFrame = immediate && isProcessing;
|
|
58
|
+
const queue = addToCurrentFrame ? thisFrame : nextFrame;
|
|
59
|
+
if (keepAlive)
|
|
60
|
+
toKeepAlive.add(callback);
|
|
61
|
+
if (!queue.has(callback))
|
|
62
|
+
queue.add(callback);
|
|
63
|
+
return callback;
|
|
64
|
+
},
|
|
65
|
+
/**
|
|
66
|
+
* Cancel the provided callback from running on the next frame.
|
|
67
|
+
*/
|
|
68
|
+
cancel: (callback) => {
|
|
69
|
+
nextFrame.delete(callback);
|
|
70
|
+
toKeepAlive.delete(callback);
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* Execute all schedule callbacks.
|
|
74
|
+
*/
|
|
75
|
+
process: (frameData) => {
|
|
76
|
+
latestFrameData = frameData;
|
|
77
|
+
/**
|
|
78
|
+
* If we're already processing we've probably been triggered by a flushSync
|
|
79
|
+
* inside an existing process. Instead of executing, mark flushNextFrame
|
|
80
|
+
* as true and ensure we flush the following frame at the end of this one.
|
|
81
|
+
*/
|
|
82
|
+
if (isProcessing) {
|
|
83
|
+
flushNextFrame = true;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
isProcessing = true;
|
|
87
|
+
[thisFrame, nextFrame] = [nextFrame, thisFrame];
|
|
88
|
+
// Execute this frame
|
|
89
|
+
thisFrame.forEach(triggerCallback);
|
|
90
|
+
/**
|
|
91
|
+
* If we're recording stats then
|
|
92
|
+
*/
|
|
93
|
+
if (stepName && statsBuffer.value) {
|
|
94
|
+
statsBuffer.value.frameloop[stepName].push(numCalls);
|
|
95
|
+
}
|
|
96
|
+
numCalls = 0;
|
|
97
|
+
// Clear the frame so no callbacks remain. This is to avoid
|
|
98
|
+
// memory leaks should this render step not run for a while.
|
|
99
|
+
thisFrame.clear();
|
|
100
|
+
isProcessing = false;
|
|
101
|
+
if (flushNextFrame) {
|
|
102
|
+
flushNextFrame = false;
|
|
103
|
+
step.process(frameData);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
return step;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const maxElapsed = 40;
|
|
111
|
+
function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
|
|
112
|
+
let runNextFrame = false;
|
|
113
|
+
let useDefaultElapsed = true;
|
|
114
|
+
const state = {
|
|
115
|
+
delta: 0.0,
|
|
116
|
+
timestamp: 0.0,
|
|
117
|
+
isProcessing: false,
|
|
118
|
+
};
|
|
119
|
+
const flagRunNextFrame = () => (runNextFrame = true);
|
|
120
|
+
const steps = stepsOrder.reduce((acc, key) => {
|
|
121
|
+
acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : undefined);
|
|
122
|
+
return acc;
|
|
123
|
+
}, {});
|
|
124
|
+
const { read, resolveKeyframes, update, preRender, render, postRender } = steps;
|
|
125
|
+
const processBatch = () => {
|
|
126
|
+
const timestamp = performance.now();
|
|
127
|
+
runNextFrame = false;
|
|
128
|
+
{
|
|
129
|
+
state.delta = useDefaultElapsed
|
|
130
|
+
? 1000 / 60
|
|
131
|
+
: Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
|
|
132
|
+
}
|
|
133
|
+
state.timestamp = timestamp;
|
|
134
|
+
state.isProcessing = true;
|
|
135
|
+
// Unrolled render loop for better per-frame performance
|
|
136
|
+
read.process(state);
|
|
137
|
+
resolveKeyframes.process(state);
|
|
138
|
+
update.process(state);
|
|
139
|
+
preRender.process(state);
|
|
140
|
+
render.process(state);
|
|
141
|
+
postRender.process(state);
|
|
142
|
+
state.isProcessing = false;
|
|
143
|
+
if (runNextFrame && allowKeepAlive) {
|
|
144
|
+
useDefaultElapsed = false;
|
|
145
|
+
scheduleNextBatch(processBatch);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const wake = () => {
|
|
149
|
+
runNextFrame = true;
|
|
150
|
+
useDefaultElapsed = true;
|
|
151
|
+
if (!state.isProcessing) {
|
|
152
|
+
scheduleNextBatch(processBatch);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const schedule = stepsOrder.reduce((acc, key) => {
|
|
156
|
+
const step = steps[key];
|
|
157
|
+
acc[key] = (process, keepAlive = false, immediate = false) => {
|
|
158
|
+
if (!runNextFrame)
|
|
159
|
+
wake();
|
|
160
|
+
return step.schedule(process, keepAlive, immediate);
|
|
161
|
+
};
|
|
162
|
+
return acc;
|
|
163
|
+
}, {});
|
|
164
|
+
const cancel = (process) => {
|
|
165
|
+
for (let i = 0; i < stepsOrder.length; i++) {
|
|
166
|
+
steps[stepsOrder[i]].cancel(process);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
return { schedule, cancel, state, steps };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps, } = createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : motionUtils.noop, true);
|
|
173
|
+
|
|
174
|
+
const activeAnimations = {
|
|
175
|
+
layout: 0,
|
|
176
|
+
mainThread: 0,
|
|
177
|
+
waapi: 0,
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
function record() {
|
|
181
|
+
const { value } = statsBuffer;
|
|
182
|
+
if (value === null) {
|
|
183
|
+
cancelFrame(record);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
value.frameloop.rate.push(frameData.delta);
|
|
187
|
+
value.animations.mainThread.push(activeAnimations.mainThread);
|
|
188
|
+
value.animations.waapi.push(activeAnimations.waapi);
|
|
189
|
+
value.animations.layout.push(activeAnimations.layout);
|
|
190
|
+
}
|
|
191
|
+
function mean(values) {
|
|
192
|
+
return values.reduce((acc, value) => acc + value, 0) / values.length;
|
|
193
|
+
}
|
|
194
|
+
function summarise(values, calcAverage = mean) {
|
|
195
|
+
if (values.length === 0) {
|
|
196
|
+
return {
|
|
197
|
+
min: 0,
|
|
198
|
+
max: 0,
|
|
199
|
+
avg: 0,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
min: Math.min(...values),
|
|
204
|
+
max: Math.max(...values),
|
|
205
|
+
avg: calcAverage(values),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
const msToFps = (ms) => Math.round(1000 / ms);
|
|
209
|
+
function clearStatsBuffer() {
|
|
210
|
+
statsBuffer.value = null;
|
|
211
|
+
statsBuffer.addProjectionMetrics = null;
|
|
212
|
+
}
|
|
213
|
+
function reportStats() {
|
|
214
|
+
const { value } = statsBuffer;
|
|
215
|
+
if (!value) {
|
|
216
|
+
throw new Error("Stats are not being measured");
|
|
217
|
+
}
|
|
218
|
+
clearStatsBuffer();
|
|
219
|
+
cancelFrame(record);
|
|
220
|
+
const summary = {
|
|
221
|
+
frameloop: {
|
|
222
|
+
rate: summarise(value.frameloop.rate),
|
|
223
|
+
read: summarise(value.frameloop.read),
|
|
224
|
+
resolveKeyframes: summarise(value.frameloop.resolveKeyframes),
|
|
225
|
+
update: summarise(value.frameloop.update),
|
|
226
|
+
preRender: summarise(value.frameloop.preRender),
|
|
227
|
+
render: summarise(value.frameloop.render),
|
|
228
|
+
postRender: summarise(value.frameloop.postRender),
|
|
229
|
+
},
|
|
230
|
+
animations: {
|
|
231
|
+
mainThread: summarise(value.animations.mainThread),
|
|
232
|
+
waapi: summarise(value.animations.waapi),
|
|
233
|
+
layout: summarise(value.animations.layout),
|
|
234
|
+
},
|
|
235
|
+
layoutProjection: {
|
|
236
|
+
nodes: summarise(value.layoutProjection.nodes),
|
|
237
|
+
calculatedTargetDeltas: summarise(value.layoutProjection.calculatedTargetDeltas),
|
|
238
|
+
calculatedProjections: summarise(value.layoutProjection.calculatedProjections),
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Convert the rate to FPS
|
|
243
|
+
*/
|
|
244
|
+
const { rate } = summary.frameloop;
|
|
245
|
+
rate.min = msToFps(rate.min);
|
|
246
|
+
rate.max = msToFps(rate.max);
|
|
247
|
+
rate.avg = msToFps(rate.avg);
|
|
248
|
+
[rate.min, rate.max] = [rate.max, rate.min];
|
|
249
|
+
return summary;
|
|
250
|
+
}
|
|
251
|
+
function recordStats() {
|
|
252
|
+
if (statsBuffer.value) {
|
|
253
|
+
clearStatsBuffer();
|
|
254
|
+
throw new Error("Stats are already being measured");
|
|
255
|
+
}
|
|
256
|
+
const newStatsBuffer = statsBuffer;
|
|
257
|
+
newStatsBuffer.value = {
|
|
258
|
+
frameloop: {
|
|
259
|
+
rate: [],
|
|
260
|
+
read: [],
|
|
261
|
+
resolveKeyframes: [],
|
|
262
|
+
update: [],
|
|
263
|
+
preRender: [],
|
|
264
|
+
render: [],
|
|
265
|
+
postRender: [],
|
|
266
|
+
},
|
|
267
|
+
animations: {
|
|
268
|
+
mainThread: [],
|
|
269
|
+
waapi: [],
|
|
270
|
+
layout: [],
|
|
271
|
+
},
|
|
272
|
+
layoutProjection: {
|
|
273
|
+
nodes: [],
|
|
274
|
+
calculatedTargetDeltas: [],
|
|
275
|
+
calculatedProjections: [],
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
newStatsBuffer.addProjectionMetrics = (metrics) => {
|
|
279
|
+
const { layoutProjection } = newStatsBuffer.value;
|
|
280
|
+
layoutProjection.nodes.push(metrics.nodes);
|
|
281
|
+
layoutProjection.calculatedTargetDeltas.push(metrics.calculatedTargetDeltas);
|
|
282
|
+
layoutProjection.calculatedProjections.push(metrics.calculatedProjections);
|
|
283
|
+
};
|
|
284
|
+
frame.postRender(record, true);
|
|
285
|
+
return reportStats;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
exports.recordStats = recordStats;
|
package/dist/cjs/dom-mini.js
CHANGED
|
@@ -408,7 +408,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
|
|
|
408
408
|
*/
|
|
409
409
|
if (Array.isArray(easing))
|
|
410
410
|
keyframeOptions.easing = easing;
|
|
411
|
-
|
|
411
|
+
const animation = element.animate(keyframeOptions, {
|
|
412
412
|
delay,
|
|
413
413
|
duration,
|
|
414
414
|
easing: !Array.isArray(easing) ? easing : "linear",
|
|
@@ -416,6 +416,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
|
|
|
416
416
|
iterations: repeat + 1,
|
|
417
417
|
direction: repeatType === "reverse" ? "alternate" : "normal",
|
|
418
418
|
});
|
|
419
|
+
return animation;
|
|
419
420
|
}
|
|
420
421
|
|
|
421
422
|
const createUnitType = (unit) => ({
|
|
@@ -475,7 +476,7 @@ function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyfr
|
|
|
475
476
|
}
|
|
476
477
|
|
|
477
478
|
function setCSSVar(element, name, value) {
|
|
478
|
-
element.style.setProperty(
|
|
479
|
+
element.style.setProperty(name, value);
|
|
479
480
|
}
|
|
480
481
|
function setStyle(element, name, value) {
|
|
481
482
|
element.style[name] = value;
|
package/dist/cjs/dom.js
CHANGED
|
@@ -697,7 +697,21 @@ const MotionGlobalConfig = {
|
|
|
697
697
|
useManualTiming: false,
|
|
698
698
|
};
|
|
699
699
|
|
|
700
|
-
|
|
700
|
+
const stepsOrder = [
|
|
701
|
+
"read", // Read
|
|
702
|
+
"resolveKeyframes", // Write/Read/Write/Read
|
|
703
|
+
"update", // Compute
|
|
704
|
+
"preRender", // Compute
|
|
705
|
+
"render", // Write
|
|
706
|
+
"postRender", // Compute
|
|
707
|
+
];
|
|
708
|
+
|
|
709
|
+
const statsBuffer = {
|
|
710
|
+
value: null,
|
|
711
|
+
addProjectionMetrics: null,
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
function createRenderStep(runNextFrame, stepName) {
|
|
701
715
|
/**
|
|
702
716
|
* We create and reuse two queues, one to queue jobs for the current frame
|
|
703
717
|
* and one for the next. We reuse to avoid triggering GC after x frames.
|
|
@@ -719,11 +733,13 @@ function createRenderStep(runNextFrame) {
|
|
|
719
733
|
timestamp: 0.0,
|
|
720
734
|
isProcessing: false,
|
|
721
735
|
};
|
|
736
|
+
let numCalls = 0;
|
|
722
737
|
function triggerCallback(callback) {
|
|
723
738
|
if (toKeepAlive.has(callback)) {
|
|
724
739
|
step.schedule(callback);
|
|
725
740
|
runNextFrame();
|
|
726
741
|
}
|
|
742
|
+
numCalls++;
|
|
727
743
|
callback(latestFrameData);
|
|
728
744
|
}
|
|
729
745
|
const step = {
|
|
@@ -764,6 +780,13 @@ function createRenderStep(runNextFrame) {
|
|
|
764
780
|
[thisFrame, nextFrame] = [nextFrame, thisFrame];
|
|
765
781
|
// Execute this frame
|
|
766
782
|
thisFrame.forEach(triggerCallback);
|
|
783
|
+
/**
|
|
784
|
+
* If we're recording stats then
|
|
785
|
+
*/
|
|
786
|
+
if (stepName && statsBuffer.value) {
|
|
787
|
+
statsBuffer.value.frameloop[stepName].push(numCalls);
|
|
788
|
+
}
|
|
789
|
+
numCalls = 0;
|
|
767
790
|
// Clear the frame so no callbacks remain. This is to avoid
|
|
768
791
|
// memory leaks should this render step not run for a while.
|
|
769
792
|
thisFrame.clear();
|
|
@@ -777,14 +800,6 @@ function createRenderStep(runNextFrame) {
|
|
|
777
800
|
return step;
|
|
778
801
|
}
|
|
779
802
|
|
|
780
|
-
const stepsOrder = [
|
|
781
|
-
"read", // Read
|
|
782
|
-
"resolveKeyframes", // Write/Read/Write/Read
|
|
783
|
-
"update", // Compute
|
|
784
|
-
"preRender", // Compute
|
|
785
|
-
"render", // Write
|
|
786
|
-
"postRender", // Compute
|
|
787
|
-
];
|
|
788
803
|
const maxElapsed$1 = 40;
|
|
789
804
|
function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
|
|
790
805
|
let runNextFrame = false;
|
|
@@ -796,16 +811,18 @@ function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
|
|
|
796
811
|
};
|
|
797
812
|
const flagRunNextFrame = () => (runNextFrame = true);
|
|
798
813
|
const steps = stepsOrder.reduce((acc, key) => {
|
|
799
|
-
acc[key] = createRenderStep(flagRunNextFrame);
|
|
814
|
+
acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : undefined);
|
|
800
815
|
return acc;
|
|
801
816
|
}, {});
|
|
802
817
|
const { read, resolveKeyframes, update, preRender, render, postRender } = steps;
|
|
803
818
|
const processBatch = () => {
|
|
804
819
|
const timestamp = performance.now();
|
|
805
820
|
runNextFrame = false;
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
821
|
+
{
|
|
822
|
+
state.delta = useDefaultElapsed
|
|
823
|
+
? 1000 / 60
|
|
824
|
+
: Math.max(Math.min(timestamp - state.timestamp, maxElapsed$1), 1);
|
|
825
|
+
}
|
|
809
826
|
state.timestamp = timestamp;
|
|
810
827
|
state.isProcessing = true;
|
|
811
828
|
// Unrolled render loop for better per-frame performance
|
|
@@ -994,7 +1011,7 @@ class MotionValue {
|
|
|
994
1011
|
* This will be replaced by the build step with the latest version number.
|
|
995
1012
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
996
1013
|
*/
|
|
997
|
-
this.version = "12.
|
|
1014
|
+
this.version = "12.4.0";
|
|
998
1015
|
/**
|
|
999
1016
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
1000
1017
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -3293,7 +3310,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
|
|
|
3293
3310
|
*/
|
|
3294
3311
|
if (Array.isArray(easing))
|
|
3295
3312
|
keyframeOptions.easing = easing;
|
|
3296
|
-
|
|
3313
|
+
const animation = element.animate(keyframeOptions, {
|
|
3297
3314
|
delay,
|
|
3298
3315
|
duration,
|
|
3299
3316
|
easing: !Array.isArray(easing) ? easing : "linear",
|
|
@@ -3301,6 +3318,7 @@ function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duratio
|
|
|
3301
3318
|
iterations: repeat + 1,
|
|
3302
3319
|
direction: repeatType === "reverse" ? "alternate" : "normal",
|
|
3303
3320
|
});
|
|
3321
|
+
return animation;
|
|
3304
3322
|
}
|
|
3305
3323
|
|
|
3306
3324
|
const supportsWaapi = /*@__PURE__*/ motionUtils.memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
|
|
@@ -3928,7 +3946,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
3928
3946
|
* and warn against mismatches.
|
|
3929
3947
|
*/
|
|
3930
3948
|
if (process.env.NODE_ENV === "development") {
|
|
3931
|
-
warnOnce(nextValue.version === "12.
|
|
3949
|
+
warnOnce(nextValue.version === "12.4.0", `Attempting to mix Motion versions ${nextValue.version} with 12.4.0 may not work as expected.`);
|
|
3932
3950
|
}
|
|
3933
3951
|
}
|
|
3934
3952
|
else if (isMotionValue(prevValue)) {
|
|
@@ -5051,7 +5069,7 @@ function createScopedAnimate(scope) {
|
|
|
5051
5069
|
const animate = createScopedAnimate();
|
|
5052
5070
|
|
|
5053
5071
|
function setCSSVar(element, name, value) {
|
|
5054
|
-
element.style.setProperty(
|
|
5072
|
+
element.style.setProperty(name, value);
|
|
5055
5073
|
}
|
|
5056
5074
|
function setStyle(element, name, value) {
|
|
5057
5075
|
element.style[name] = value;
|