framer-motion 7.9.0 → 7.10.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/index.js +72 -56
- package/dist/es/animation/waapi/easing.mjs +20 -1
- package/dist/es/animation/waapi/index.mjs +2 -2
- package/dist/es/index.mjs +1 -0
- package/dist/es/render/VisualElement.mjs +2 -2
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/utils/use-motion-value-event.mjs +7 -0
- package/dist/es/value/index.mjs +42 -48
- package/dist/es/value/use-motion-value.mjs +1 -1
- package/dist/es/value/use-on-change.mjs +2 -2
- package/dist/es/value/use-velocity.mjs +1 -1
- package/dist/framer-motion.dev.js +72 -56
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +19 -4
- package/dist/projection.dev.js +68 -52
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max-assets.js +1 -1
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-motion.js +1 -1
- package/dist/size-webpack-dom-animation.js +1 -1
- package/dist/size-webpack-dom-max.js +1 -1
- package/dist/three-entry.d.ts +16 -3
- package/package.json +6 -6
package/dist/cjs/index.js
CHANGED
|
@@ -2124,7 +2124,7 @@ class MotionValue {
|
|
|
2124
2124
|
* This will be replaced by the build step with the latest version number.
|
|
2125
2125
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
2126
2126
|
*/
|
|
2127
|
-
this.version = "7.
|
|
2127
|
+
this.version = "7.10.0";
|
|
2128
2128
|
/**
|
|
2129
2129
|
* Duration, in milliseconds, since last updating frame.
|
|
2130
2130
|
*
|
|
@@ -2137,24 +2137,6 @@ class MotionValue {
|
|
|
2137
2137
|
* @internal
|
|
2138
2138
|
*/
|
|
2139
2139
|
this.lastUpdated = 0;
|
|
2140
|
-
/**
|
|
2141
|
-
* Functions to notify when the `MotionValue` updates.
|
|
2142
|
-
*
|
|
2143
|
-
* @internal
|
|
2144
|
-
*/
|
|
2145
|
-
this.updateSubscribers = new SubscriptionManager();
|
|
2146
|
-
/**
|
|
2147
|
-
* Functions to notify when the velocity updates.
|
|
2148
|
-
*
|
|
2149
|
-
* @internal
|
|
2150
|
-
*/
|
|
2151
|
-
this.velocityUpdateSubscribers = new SubscriptionManager();
|
|
2152
|
-
/**
|
|
2153
|
-
* Functions to notify when the `MotionValue` updates and `render` is set to `true`.
|
|
2154
|
-
*
|
|
2155
|
-
* @internal
|
|
2156
|
-
*/
|
|
2157
|
-
this.renderSubscribers = new SubscriptionManager();
|
|
2158
2140
|
/**
|
|
2159
2141
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
2160
2142
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -2163,6 +2145,10 @@ class MotionValue {
|
|
|
2163
2145
|
* @internal
|
|
2164
2146
|
*/
|
|
2165
2147
|
this.canTrackVelocity = false;
|
|
2148
|
+
/**
|
|
2149
|
+
* An object containing a SubscriptionManager for each active event.
|
|
2150
|
+
*/
|
|
2151
|
+
this.events = {};
|
|
2166
2152
|
this.updateAndNotify = (v, render = true) => {
|
|
2167
2153
|
this.prev = this.current;
|
|
2168
2154
|
this.current = v;
|
|
@@ -2174,16 +2160,16 @@ class MotionValue {
|
|
|
2174
2160
|
sync.postRender(this.scheduleVelocityCheck);
|
|
2175
2161
|
}
|
|
2176
2162
|
// Update update subscribers
|
|
2177
|
-
if (this.prev !== this.current) {
|
|
2178
|
-
this.
|
|
2163
|
+
if (this.prev !== this.current && this.events.change) {
|
|
2164
|
+
this.events.change.notify(this.current);
|
|
2179
2165
|
}
|
|
2180
2166
|
// Update velocity subscribers
|
|
2181
|
-
if (this.
|
|
2182
|
-
this.
|
|
2167
|
+
if (this.events.velocityChange) {
|
|
2168
|
+
this.events.velocityChange.notify(this.getVelocity());
|
|
2183
2169
|
}
|
|
2184
2170
|
// Update render subscribers
|
|
2185
|
-
if (render) {
|
|
2186
|
-
this.
|
|
2171
|
+
if (render && this.events.renderRequest) {
|
|
2172
|
+
this.events.renderRequest.notify(this.current);
|
|
2187
2173
|
}
|
|
2188
2174
|
};
|
|
2189
2175
|
/**
|
|
@@ -2207,7 +2193,9 @@ class MotionValue {
|
|
|
2207
2193
|
this.velocityCheck = ({ timestamp }) => {
|
|
2208
2194
|
if (timestamp !== this.lastUpdated) {
|
|
2209
2195
|
this.prev = this.current;
|
|
2210
|
-
this.
|
|
2196
|
+
if (this.events.velocityChange) {
|
|
2197
|
+
this.events.velocityChange.notify(this.getVelocity());
|
|
2198
|
+
}
|
|
2211
2199
|
}
|
|
2212
2200
|
};
|
|
2213
2201
|
this.hasAnimated = false;
|
|
@@ -2237,8 +2225,8 @@ class MotionValue {
|
|
|
2237
2225
|
* opacity.set(newOpacity)
|
|
2238
2226
|
* }
|
|
2239
2227
|
*
|
|
2240
|
-
* const unsubscribeX = x.
|
|
2241
|
-
* const unsubscribeY = y.
|
|
2228
|
+
* const unsubscribeX = x.on("change", updateOpacity)
|
|
2229
|
+
* const unsubscribeY = y.on("change", updateOpacity)
|
|
2242
2230
|
*
|
|
2243
2231
|
* return () => {
|
|
2244
2232
|
* unsubscribeX()
|
|
@@ -2261,26 +2249,21 @@ class MotionValue {
|
|
|
2261
2249
|
* @param subscriber - A function that receives the latest value.
|
|
2262
2250
|
* @returns A function that, when called, will cancel this subscription.
|
|
2263
2251
|
*
|
|
2264
|
-
* @
|
|
2252
|
+
* @deprecated
|
|
2265
2253
|
*/
|
|
2266
2254
|
onChange(subscription) {
|
|
2267
|
-
return this.
|
|
2255
|
+
return this.on("change", subscription);
|
|
2268
2256
|
}
|
|
2269
|
-
|
|
2270
|
-
this.
|
|
2257
|
+
on(eventName, callback) {
|
|
2258
|
+
if (!this.events[eventName]) {
|
|
2259
|
+
this.events[eventName] = new SubscriptionManager();
|
|
2260
|
+
}
|
|
2261
|
+
return this.events[eventName].add(callback);
|
|
2271
2262
|
}
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
* @returns A function that, when called, will cancel this subscription.
|
|
2277
|
-
*
|
|
2278
|
-
* @internal
|
|
2279
|
-
*/
|
|
2280
|
-
onRenderRequest(subscription) {
|
|
2281
|
-
// Render immediately
|
|
2282
|
-
subscription(this.get());
|
|
2283
|
-
return this.renderSubscribers.add(subscription);
|
|
2263
|
+
clearListeners() {
|
|
2264
|
+
for (const eventManagers in this.events) {
|
|
2265
|
+
this.events[eventManagers].clear();
|
|
2266
|
+
}
|
|
2284
2267
|
}
|
|
2285
2268
|
/**
|
|
2286
2269
|
* Attaches a passive effect to the `MotionValue`.
|
|
@@ -2366,7 +2349,15 @@ class MotionValue {
|
|
|
2366
2349
|
return new Promise((resolve) => {
|
|
2367
2350
|
this.hasAnimated = true;
|
|
2368
2351
|
this.stopAnimation = animation(resolve);
|
|
2369
|
-
|
|
2352
|
+
if (this.events.animationStart) {
|
|
2353
|
+
this.events.animationStart.notify();
|
|
2354
|
+
}
|
|
2355
|
+
}).then(() => {
|
|
2356
|
+
if (this.events.animationComplete) {
|
|
2357
|
+
this.events.animationComplete.notify();
|
|
2358
|
+
}
|
|
2359
|
+
this.clearAnimation();
|
|
2360
|
+
});
|
|
2370
2361
|
}
|
|
2371
2362
|
/**
|
|
2372
2363
|
* Stop the currently active animation.
|
|
@@ -2374,8 +2365,12 @@ class MotionValue {
|
|
|
2374
2365
|
* @public
|
|
2375
2366
|
*/
|
|
2376
2367
|
stop() {
|
|
2377
|
-
if (this.stopAnimation)
|
|
2368
|
+
if (this.stopAnimation) {
|
|
2378
2369
|
this.stopAnimation();
|
|
2370
|
+
if (this.events.animationCancel) {
|
|
2371
|
+
this.events.animationCancel.notify();
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2379
2374
|
this.clearAnimation();
|
|
2380
2375
|
}
|
|
2381
2376
|
/**
|
|
@@ -2399,8 +2394,7 @@ class MotionValue {
|
|
|
2399
2394
|
* @public
|
|
2400
2395
|
*/
|
|
2401
2396
|
destroy() {
|
|
2402
|
-
this.
|
|
2403
|
-
this.renderSubscribers.clear();
|
|
2397
|
+
this.clearListeners();
|
|
2404
2398
|
this.stop();
|
|
2405
2399
|
}
|
|
2406
2400
|
}
|
|
@@ -3620,12 +3614,29 @@ function animate$1({ duration, driver = framesync, elapsed = 0, repeat: repeatMa
|
|
|
3620
3614
|
}
|
|
3621
3615
|
|
|
3622
3616
|
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
|
3617
|
+
const validWaapiEasing = new Set([
|
|
3618
|
+
"linear",
|
|
3619
|
+
"ease-in",
|
|
3620
|
+
"ease-out",
|
|
3621
|
+
"ease-in-out",
|
|
3622
|
+
]);
|
|
3623
|
+
function mapEasingName(easingName) {
|
|
3624
|
+
const name = camelToDash(easingName);
|
|
3625
|
+
return validWaapiEasing.has(name) ? name : "ease";
|
|
3626
|
+
}
|
|
3627
|
+
function mapEasingToNativeEasing(easing) {
|
|
3628
|
+
if (!easing)
|
|
3629
|
+
return undefined;
|
|
3630
|
+
return Array.isArray(easing)
|
|
3631
|
+
? cubicBezierAsString(easing)
|
|
3632
|
+
: mapEasingName(easing);
|
|
3633
|
+
}
|
|
3623
3634
|
|
|
3624
3635
|
function animateStyle(element, valueName, keyframes, { delay = 0, duration, repeat = 0, repeatType = "loop", ease, times, } = {}) {
|
|
3625
3636
|
return element.animate({ [valueName]: keyframes, offset: times }, {
|
|
3626
3637
|
delay,
|
|
3627
3638
|
duration,
|
|
3628
|
-
easing:
|
|
3639
|
+
easing: mapEasingToNativeEasing(ease),
|
|
3629
3640
|
fill: "both",
|
|
3630
3641
|
iterations: repeat + 1,
|
|
3631
3642
|
direction: repeatType === "reverse" ? "alternate" : "normal",
|
|
@@ -5927,7 +5938,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
5927
5938
|
* and warn against mismatches.
|
|
5928
5939
|
*/
|
|
5929
5940
|
if (process.env.NODE_ENV === "development") {
|
|
5930
|
-
warnOnce(nextValue.version === "7.
|
|
5941
|
+
warnOnce(nextValue.version === "7.10.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.10.0 may not work as expected.`);
|
|
5931
5942
|
}
|
|
5932
5943
|
}
|
|
5933
5944
|
else if (isMotionValue(prevValue)) {
|
|
@@ -6130,7 +6141,7 @@ class VisualElement {
|
|
|
6130
6141
|
}
|
|
6131
6142
|
bindToMotionValue(key, value) {
|
|
6132
6143
|
const valueIsTransform = transformProps.has(key);
|
|
6133
|
-
const removeOnChange = value.
|
|
6144
|
+
const removeOnChange = value.on("change", (latestValue) => {
|
|
6134
6145
|
this.latestValues[key] = latestValue;
|
|
6135
6146
|
this.props.onUpdate &&
|
|
6136
6147
|
sync.update(this.notifyUpdate, false, true);
|
|
@@ -6138,7 +6149,7 @@ class VisualElement {
|
|
|
6138
6149
|
this.projection.isTransformDirty = true;
|
|
6139
6150
|
}
|
|
6140
6151
|
});
|
|
6141
|
-
const removeOnRenderRequest = value.
|
|
6152
|
+
const removeOnRenderRequest = value.on("renderRequest", this.scheduleRender);
|
|
6142
6153
|
this.valueSubscriptions.set(key, () => {
|
|
6143
6154
|
removeOnChange();
|
|
6144
6155
|
removeOnRenderRequest();
|
|
@@ -9020,7 +9031,7 @@ function useMotionValue(initial) {
|
|
|
9020
9031
|
const { isStatic } = React.useContext(MotionConfigContext);
|
|
9021
9032
|
if (isStatic) {
|
|
9022
9033
|
const [, setLatest] = React.useState(initial);
|
|
9023
|
-
React.useEffect(() => value.
|
|
9034
|
+
React.useEffect(() => value.on("change", setLatest), []);
|
|
9024
9035
|
}
|
|
9025
9036
|
return value;
|
|
9026
9037
|
}
|
|
@@ -9047,13 +9058,13 @@ function useOnChange(value, callback) {
|
|
|
9047
9058
|
useIsomorphicLayoutEffect(() => {
|
|
9048
9059
|
if (isMotionValue(value)) {
|
|
9049
9060
|
callback(value.get());
|
|
9050
|
-
return value.
|
|
9061
|
+
return value.on("change", callback);
|
|
9051
9062
|
}
|
|
9052
9063
|
}, [value, callback]);
|
|
9053
9064
|
}
|
|
9054
9065
|
function useMultiOnChange(values, handler, cleanup) {
|
|
9055
9066
|
useIsomorphicLayoutEffect(() => {
|
|
9056
|
-
const subscriptions = values.map((value) => value.
|
|
9067
|
+
const subscriptions = values.map((value) => value.on("change", handler));
|
|
9057
9068
|
return () => {
|
|
9058
9069
|
subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
9059
9070
|
cleanup();
|
|
@@ -9260,7 +9271,7 @@ function useSpring(source, config = {}) {
|
|
|
9260
9271
|
function useVelocity(value) {
|
|
9261
9272
|
const velocity = useMotionValue(value.getVelocity());
|
|
9262
9273
|
React.useEffect(() => {
|
|
9263
|
-
return value.
|
|
9274
|
+
return value.on("velocityChange", (newVelocity) => {
|
|
9264
9275
|
velocity.set(newVelocity);
|
|
9265
9276
|
});
|
|
9266
9277
|
}, [value]);
|
|
@@ -9373,6 +9384,10 @@ function useWillChange() {
|
|
|
9373
9384
|
return useConstant(() => new WillChangeMotionValue("auto"));
|
|
9374
9385
|
}
|
|
9375
9386
|
|
|
9387
|
+
function useMotionValueEvent(value, event, callback) {
|
|
9388
|
+
useIsomorphicLayoutEffect(() => value.on(event, callback), [value, event, callback]);
|
|
9389
|
+
}
|
|
9390
|
+
|
|
9376
9391
|
/**
|
|
9377
9392
|
* A hook that returns `true` if we should be using reduced motion based on the current device's Reduced Motion setting.
|
|
9378
9393
|
*
|
|
@@ -9929,6 +9944,7 @@ exports.useIsPresent = useIsPresent;
|
|
|
9929
9944
|
exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
|
|
9930
9945
|
exports.useMotionTemplate = useMotionTemplate;
|
|
9931
9946
|
exports.useMotionValue = useMotionValue;
|
|
9947
|
+
exports.useMotionValueEvent = useMotionValueEvent;
|
|
9932
9948
|
exports.usePresence = usePresence;
|
|
9933
9949
|
exports.useReducedMotion = useReducedMotion;
|
|
9934
9950
|
exports.useReducedMotionConfig = useReducedMotionConfig;
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
import { camelToDash } from '../../render/dom/utils/camel-to-dash.mjs';
|
|
2
|
+
|
|
1
3
|
const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
|
|
4
|
+
const validWaapiEasing = new Set([
|
|
5
|
+
"linear",
|
|
6
|
+
"ease-in",
|
|
7
|
+
"ease-out",
|
|
8
|
+
"ease-in-out",
|
|
9
|
+
]);
|
|
10
|
+
function mapEasingName(easingName) {
|
|
11
|
+
const name = camelToDash(easingName);
|
|
12
|
+
return validWaapiEasing.has(name) ? name : "ease";
|
|
13
|
+
}
|
|
14
|
+
function mapEasingToNativeEasing(easing) {
|
|
15
|
+
if (!easing)
|
|
16
|
+
return undefined;
|
|
17
|
+
return Array.isArray(easing)
|
|
18
|
+
? cubicBezierAsString(easing)
|
|
19
|
+
: mapEasingName(easing);
|
|
20
|
+
}
|
|
2
21
|
|
|
3
|
-
export { cubicBezierAsString };
|
|
22
|
+
export { cubicBezierAsString, mapEasingName, mapEasingToNativeEasing };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mapEasingToNativeEasing } from './easing.mjs';
|
|
2
2
|
|
|
3
3
|
function animateStyle(element, valueName, keyframes, { delay = 0, duration, repeat = 0, repeatType = "loop", ease, times, } = {}) {
|
|
4
4
|
return element.animate({ [valueName]: keyframes, offset: times }, {
|
|
5
5
|
delay,
|
|
6
6
|
duration,
|
|
7
|
-
easing:
|
|
7
|
+
easing: mapEasingToNativeEasing(ease),
|
|
8
8
|
fill: "both",
|
|
9
9
|
iterations: repeat + 1,
|
|
10
10
|
direction: repeatType === "reverse" ? "alternate" : "normal",
|
package/dist/es/index.mjs
CHANGED
|
@@ -20,6 +20,7 @@ export { useElementScroll } from './value/scroll/use-element-scroll.mjs';
|
|
|
20
20
|
export { useViewportScroll } from './value/scroll/use-viewport-scroll.mjs';
|
|
21
21
|
export { useTime } from './value/use-time.mjs';
|
|
22
22
|
export { useWillChange } from './value/use-will-change/index.mjs';
|
|
23
|
+
export { useMotionValueEvent } from './utils/use-motion-value-event.mjs';
|
|
23
24
|
export { useReducedMotion } from './utils/reduced-motion/use-reduced-motion.mjs';
|
|
24
25
|
export { useReducedMotionConfig } from './utils/reduced-motion/use-reduced-motion-config.mjs';
|
|
25
26
|
export { animationControls } from './animation/hooks/animation-controls.mjs';
|
|
@@ -183,7 +183,7 @@ class VisualElement {
|
|
|
183
183
|
}
|
|
184
184
|
bindToMotionValue(key, value) {
|
|
185
185
|
const valueIsTransform = transformProps.has(key);
|
|
186
|
-
const removeOnChange = value.
|
|
186
|
+
const removeOnChange = value.on("change", (latestValue) => {
|
|
187
187
|
this.latestValues[key] = latestValue;
|
|
188
188
|
this.props.onUpdate &&
|
|
189
189
|
sync.update(this.notifyUpdate, false, true);
|
|
@@ -191,7 +191,7 @@ class VisualElement {
|
|
|
191
191
|
this.projection.isTransformDirty = true;
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
|
-
const removeOnRenderRequest = value.
|
|
194
|
+
const removeOnRenderRequest = value.on("renderRequest", this.scheduleRender);
|
|
195
195
|
this.valueSubscriptions.set(key, () => {
|
|
196
196
|
removeOnChange();
|
|
197
197
|
removeOnRenderRequest();
|
|
@@ -22,7 +22,7 @@ function updateMotionValuesFromProps(element, next, prev) {
|
|
|
22
22
|
* and warn against mismatches.
|
|
23
23
|
*/
|
|
24
24
|
if (process.env.NODE_ENV === "development") {
|
|
25
|
-
warnOnce(nextValue.version === "7.
|
|
25
|
+
warnOnce(nextValue.version === "7.10.0", `Attempting to mix Framer Motion versions ${nextValue.version} with 7.10.0 may not work as expected.`);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
else if (isMotionValue(prevValue)) {
|
package/dist/es/value/index.mjs
CHANGED
|
@@ -25,7 +25,7 @@ class MotionValue {
|
|
|
25
25
|
* This will be replaced by the build step with the latest version number.
|
|
26
26
|
* When MotionValues are provided to motion components, warn if versions are mixed.
|
|
27
27
|
*/
|
|
28
|
-
this.version = "7.
|
|
28
|
+
this.version = "7.10.0";
|
|
29
29
|
/**
|
|
30
30
|
* Duration, in milliseconds, since last updating frame.
|
|
31
31
|
*
|
|
@@ -38,24 +38,6 @@ class MotionValue {
|
|
|
38
38
|
* @internal
|
|
39
39
|
*/
|
|
40
40
|
this.lastUpdated = 0;
|
|
41
|
-
/**
|
|
42
|
-
* Functions to notify when the `MotionValue` updates.
|
|
43
|
-
*
|
|
44
|
-
* @internal
|
|
45
|
-
*/
|
|
46
|
-
this.updateSubscribers = new SubscriptionManager();
|
|
47
|
-
/**
|
|
48
|
-
* Functions to notify when the velocity updates.
|
|
49
|
-
*
|
|
50
|
-
* @internal
|
|
51
|
-
*/
|
|
52
|
-
this.velocityUpdateSubscribers = new SubscriptionManager();
|
|
53
|
-
/**
|
|
54
|
-
* Functions to notify when the `MotionValue` updates and `render` is set to `true`.
|
|
55
|
-
*
|
|
56
|
-
* @internal
|
|
57
|
-
*/
|
|
58
|
-
this.renderSubscribers = new SubscriptionManager();
|
|
59
41
|
/**
|
|
60
42
|
* Tracks whether this value can output a velocity. Currently this is only true
|
|
61
43
|
* if the value is numerical, but we might be able to widen the scope here and support
|
|
@@ -64,6 +46,10 @@ class MotionValue {
|
|
|
64
46
|
* @internal
|
|
65
47
|
*/
|
|
66
48
|
this.canTrackVelocity = false;
|
|
49
|
+
/**
|
|
50
|
+
* An object containing a SubscriptionManager for each active event.
|
|
51
|
+
*/
|
|
52
|
+
this.events = {};
|
|
67
53
|
this.updateAndNotify = (v, render = true) => {
|
|
68
54
|
this.prev = this.current;
|
|
69
55
|
this.current = v;
|
|
@@ -75,16 +61,16 @@ class MotionValue {
|
|
|
75
61
|
sync.postRender(this.scheduleVelocityCheck);
|
|
76
62
|
}
|
|
77
63
|
// Update update subscribers
|
|
78
|
-
if (this.prev !== this.current) {
|
|
79
|
-
this.
|
|
64
|
+
if (this.prev !== this.current && this.events.change) {
|
|
65
|
+
this.events.change.notify(this.current);
|
|
80
66
|
}
|
|
81
67
|
// Update velocity subscribers
|
|
82
|
-
if (this.
|
|
83
|
-
this.
|
|
68
|
+
if (this.events.velocityChange) {
|
|
69
|
+
this.events.velocityChange.notify(this.getVelocity());
|
|
84
70
|
}
|
|
85
71
|
// Update render subscribers
|
|
86
|
-
if (render) {
|
|
87
|
-
this.
|
|
72
|
+
if (render && this.events.renderRequest) {
|
|
73
|
+
this.events.renderRequest.notify(this.current);
|
|
88
74
|
}
|
|
89
75
|
};
|
|
90
76
|
/**
|
|
@@ -108,7 +94,9 @@ class MotionValue {
|
|
|
108
94
|
this.velocityCheck = ({ timestamp }) => {
|
|
109
95
|
if (timestamp !== this.lastUpdated) {
|
|
110
96
|
this.prev = this.current;
|
|
111
|
-
this.
|
|
97
|
+
if (this.events.velocityChange) {
|
|
98
|
+
this.events.velocityChange.notify(this.getVelocity());
|
|
99
|
+
}
|
|
112
100
|
}
|
|
113
101
|
};
|
|
114
102
|
this.hasAnimated = false;
|
|
@@ -138,8 +126,8 @@ class MotionValue {
|
|
|
138
126
|
* opacity.set(newOpacity)
|
|
139
127
|
* }
|
|
140
128
|
*
|
|
141
|
-
* const unsubscribeX = x.
|
|
142
|
-
* const unsubscribeY = y.
|
|
129
|
+
* const unsubscribeX = x.on("change", updateOpacity)
|
|
130
|
+
* const unsubscribeY = y.on("change", updateOpacity)
|
|
143
131
|
*
|
|
144
132
|
* return () => {
|
|
145
133
|
* unsubscribeX()
|
|
@@ -162,26 +150,21 @@ class MotionValue {
|
|
|
162
150
|
* @param subscriber - A function that receives the latest value.
|
|
163
151
|
* @returns A function that, when called, will cancel this subscription.
|
|
164
152
|
*
|
|
165
|
-
* @
|
|
153
|
+
* @deprecated
|
|
166
154
|
*/
|
|
167
155
|
onChange(subscription) {
|
|
168
|
-
return this.
|
|
156
|
+
return this.on("change", subscription);
|
|
169
157
|
}
|
|
170
|
-
|
|
171
|
-
this.
|
|
158
|
+
on(eventName, callback) {
|
|
159
|
+
if (!this.events[eventName]) {
|
|
160
|
+
this.events[eventName] = new SubscriptionManager();
|
|
161
|
+
}
|
|
162
|
+
return this.events[eventName].add(callback);
|
|
172
163
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
* @returns A function that, when called, will cancel this subscription.
|
|
178
|
-
*
|
|
179
|
-
* @internal
|
|
180
|
-
*/
|
|
181
|
-
onRenderRequest(subscription) {
|
|
182
|
-
// Render immediately
|
|
183
|
-
subscription(this.get());
|
|
184
|
-
return this.renderSubscribers.add(subscription);
|
|
164
|
+
clearListeners() {
|
|
165
|
+
for (const eventManagers in this.events) {
|
|
166
|
+
this.events[eventManagers].clear();
|
|
167
|
+
}
|
|
185
168
|
}
|
|
186
169
|
/**
|
|
187
170
|
* Attaches a passive effect to the `MotionValue`.
|
|
@@ -267,7 +250,15 @@ class MotionValue {
|
|
|
267
250
|
return new Promise((resolve) => {
|
|
268
251
|
this.hasAnimated = true;
|
|
269
252
|
this.stopAnimation = animation(resolve);
|
|
270
|
-
|
|
253
|
+
if (this.events.animationStart) {
|
|
254
|
+
this.events.animationStart.notify();
|
|
255
|
+
}
|
|
256
|
+
}).then(() => {
|
|
257
|
+
if (this.events.animationComplete) {
|
|
258
|
+
this.events.animationComplete.notify();
|
|
259
|
+
}
|
|
260
|
+
this.clearAnimation();
|
|
261
|
+
});
|
|
271
262
|
}
|
|
272
263
|
/**
|
|
273
264
|
* Stop the currently active animation.
|
|
@@ -275,8 +266,12 @@ class MotionValue {
|
|
|
275
266
|
* @public
|
|
276
267
|
*/
|
|
277
268
|
stop() {
|
|
278
|
-
if (this.stopAnimation)
|
|
269
|
+
if (this.stopAnimation) {
|
|
279
270
|
this.stopAnimation();
|
|
271
|
+
if (this.events.animationCancel) {
|
|
272
|
+
this.events.animationCancel.notify();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
280
275
|
this.clearAnimation();
|
|
281
276
|
}
|
|
282
277
|
/**
|
|
@@ -300,8 +295,7 @@ class MotionValue {
|
|
|
300
295
|
* @public
|
|
301
296
|
*/
|
|
302
297
|
destroy() {
|
|
303
|
-
this.
|
|
304
|
-
this.renderSubscribers.clear();
|
|
298
|
+
this.clearListeners();
|
|
305
299
|
this.stop();
|
|
306
300
|
}
|
|
307
301
|
}
|
|
@@ -30,7 +30,7 @@ function useMotionValue(initial) {
|
|
|
30
30
|
const { isStatic } = useContext(MotionConfigContext);
|
|
31
31
|
if (isStatic) {
|
|
32
32
|
const [, setLatest] = useState(initial);
|
|
33
|
-
useEffect(() => value.
|
|
33
|
+
useEffect(() => value.on("change", setLatest), []);
|
|
34
34
|
}
|
|
35
35
|
return value;
|
|
36
36
|
}
|
|
@@ -5,13 +5,13 @@ function useOnChange(value, callback) {
|
|
|
5
5
|
useIsomorphicLayoutEffect(() => {
|
|
6
6
|
if (isMotionValue(value)) {
|
|
7
7
|
callback(value.get());
|
|
8
|
-
return value.
|
|
8
|
+
return value.on("change", callback);
|
|
9
9
|
}
|
|
10
10
|
}, [value, callback]);
|
|
11
11
|
}
|
|
12
12
|
function useMultiOnChange(values, handler, cleanup) {
|
|
13
13
|
useIsomorphicLayoutEffect(() => {
|
|
14
|
-
const subscriptions = values.map((value) => value.
|
|
14
|
+
const subscriptions = values.map((value) => value.on("change", handler));
|
|
15
15
|
return () => {
|
|
16
16
|
subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
17
17
|
cleanup();
|
|
@@ -15,7 +15,7 @@ import { useMotionValue } from './use-motion-value.mjs';
|
|
|
15
15
|
function useVelocity(value) {
|
|
16
16
|
const velocity = useMotionValue(value.getVelocity());
|
|
17
17
|
useEffect(() => {
|
|
18
|
-
return value.
|
|
18
|
+
return value.on("velocityChange", (newVelocity) => {
|
|
19
19
|
velocity.set(newVelocity);
|
|
20
20
|
});
|
|
21
21
|
}, [value]);
|