motion-start 0.0.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/LICENSE.md +21 -0
- package/README.md +39 -0
- package/package.json +64 -0
- package/src/animation/UseAnimatedState.svelte +86 -0
- package/src/animation/UseAnimation.svelte +61 -0
- package/src/animation/animate.ts +78 -0
- package/src/animation/animation-controls.ts +101 -0
- package/src/animation/types.ts +83 -0
- package/src/animation/use-animated-state.ts +1 -0
- package/src/animation/use-animation.ts +74 -0
- package/src/animation/utils/default-transitions.ts +70 -0
- package/src/animation/utils/easing.ts +55 -0
- package/src/animation/utils/is-animatable.ts +42 -0
- package/src/animation/utils/is-animation-controls.ts +17 -0
- package/src/animation/utils/is-keyframes-target.ts +17 -0
- package/src/animation/utils/transitions.ts +218 -0
- package/src/animation/utils/variant-resolvers.ts +15 -0
- package/src/components/AnimatePresence/AnimatePresence.svelte +180 -0
- package/src/components/AnimatePresence/PresenceChild/PresenceChild.svelte +78 -0
- package/src/components/AnimatePresence/PresenceChild/index.ts +7 -0
- package/src/components/AnimatePresence/PresenceChild/types.ts +10 -0
- package/src/components/AnimatePresence/index.ts +46 -0
- package/src/components/AnimatePresence/types.ts +79 -0
- package/src/components/AnimatePresence/use-presence.ts +90 -0
- package/src/components/AnimateSharedLayout/AnimateSharedLayout.svelte +239 -0
- package/src/components/AnimateSharedLayout/index.ts +11 -0
- package/src/components/AnimateSharedLayout/types.ts +111 -0
- package/src/components/AnimateSharedLayout/utils/batcher.ts +96 -0
- package/src/components/AnimateSharedLayout/utils/crossfader.ts +260 -0
- package/src/components/AnimateSharedLayout/utils/rotate.ts +48 -0
- package/src/components/AnimateSharedLayout/utils/stack.ts +160 -0
- package/src/components/LazyMotion/LazyMotion.svelte +82 -0
- package/src/components/LazyMotion/index.ts +42 -0
- package/src/components/LazyMotion/types.ts +58 -0
- package/src/components/MotionConfig/MotionConfig.svelte +56 -0
- package/src/components/MotionConfig/MotionConfigScaleCorrection.ts +47 -0
- package/src/components/MotionConfig/index.ts +20 -0
- package/src/components/MotionDiv.svelte +8 -0
- package/src/context/DOMcontext.ts +21 -0
- package/src/context/LayoutGroupContext.ts +13 -0
- package/src/context/LazyContext.ts +18 -0
- package/src/context/MotionConfigContext.ts +48 -0
- package/src/context/MotionContext/MotionContext.svelte +27 -0
- package/src/context/MotionContext/MotionContextProvider.svelte +22 -0
- package/src/context/MotionContext/UseCreateMotionContext.svelte +34 -0
- package/src/context/MotionContext/create.ts +1 -0
- package/src/context/MotionContext/index.ts +14 -0
- package/src/context/MotionContext/utils.ts +29 -0
- package/src/context/PresenceContext.ts +26 -0
- package/src/context/ScaleCorrectionProvider.svelte +27 -0
- package/src/context/SharedLayoutContext.ts +29 -0
- package/src/events/UseDomEvent.svelte +67 -0
- package/src/events/UsePointerEvent.svelte +76 -0
- package/src/events/event-info.ts +69 -0
- package/src/events/types.ts +15 -0
- package/src/events/use-dom-event.ts +48 -0
- package/src/events/use-pointer-event.ts +29 -0
- package/src/events/utils.ts +25 -0
- package/src/gestures/PanSession.ts +298 -0
- package/src/gestures/UseFocusGesture.svelte +31 -0
- package/src/gestures/UseGestures.svelte +17 -0
- package/src/gestures/UseHoverGesture.svelte +40 -0
- package/src/gestures/UsePanGesture.svelte +58 -0
- package/src/gestures/UseTapGesture.svelte +77 -0
- package/src/gestures/drag/UseDrag.svelte +55 -0
- package/src/gestures/drag/UseDragControls.svelte +145 -0
- package/src/gestures/drag/VisualElementDragControls.ts +632 -0
- package/src/gestures/drag/types.ts +307 -0
- package/src/gestures/drag/use-drag-controls.ts +148 -0
- package/src/gestures/drag/use-drag.ts +15 -0
- package/src/gestures/drag/utils/constraints.ts +157 -0
- package/src/gestures/drag/utils/lock.ts +69 -0
- package/src/gestures/types.ts +257 -0
- package/src/gestures/use-focus-gesture.ts +16 -0
- package/src/gestures/use-gestures.ts +2 -0
- package/src/gestures/use-hover-gesture.ts +10 -0
- package/src/gestures/use-pan-gesture.ts +22 -0
- package/src/gestures/use-tap-gesture.ts +14 -0
- package/src/gestures/utils/event-type.ts +24 -0
- package/src/gestures/utils/is-node-or-child.ts +31 -0
- package/src/index.ts +104 -0
- package/src/motion/Motion.svelte +246 -0
- package/src/motion/MotionSSR.svelte +244 -0
- package/src/motion/features/AnimationState.svelte +29 -0
- package/src/motion/features/Exit.svelte +32 -0
- package/src/motion/features/UseFeatures.svelte +39 -0
- package/src/motion/features/animations.ts +22 -0
- package/src/motion/features/definitions.ts +49 -0
- package/src/motion/features/drag.ts +24 -0
- package/src/motion/features/gestures.ts +24 -0
- package/src/motion/features/layout/Animate.svelte +314 -0
- package/src/motion/features/layout/Animate.ts +9 -0
- package/src/motion/features/layout/AnimateLayoutContextProvider.svelte +14 -0
- package/src/motion/features/layout/Measure.svelte +98 -0
- package/src/motion/features/layout/Measure.ts +9 -0
- package/src/motion/features/layout/MeasureContextProvider.svelte +32 -0
- package/src/motion/features/layout/index.ts +20 -0
- package/src/motion/features/layout/types.ts +71 -0
- package/src/motion/features/layout/utils.ts +40 -0
- package/src/motion/features/types.ts +53 -0
- package/src/motion/features/use-features.ts +16 -0
- package/src/motion/index.ts +64 -0
- package/src/motion/types.ts +278 -0
- package/src/motion/utils/UseLayoutId.svelte +18 -0
- package/src/motion/utils/UseVisualElement.svelte +104 -0
- package/src/motion/utils/UseVisualState.svelte +137 -0
- package/src/motion/utils/is-forced-motion-value.ts +23 -0
- package/src/motion/utils/make-renderless-component.ts +17 -0
- package/src/motion/utils/should-inhert-variant.ts +6 -0
- package/src/motion/utils/use-motion-ref.ts +41 -0
- package/src/motion/utils/use-visual-element.ts +13 -0
- package/src/motion/utils/use-visual-state.ts +24 -0
- package/src/motion/utils/valid-prop.ts +80 -0
- package/src/render/dom/M.svelte +16 -0
- package/src/render/dom/UseRender.svelte +37 -0
- package/src/render/dom/create-motion-class.ts +12 -0
- package/src/render/dom/create-visual-element.ts +22 -0
- package/src/render/dom/featureBundle.ts +22 -0
- package/src/render/dom/motion-minimal.ts +22 -0
- package/src/render/dom/motion-proxy.ts +107 -0
- package/src/render/dom/motion.ts +62 -0
- package/src/render/dom/projection/convert-to-relative.ts +40 -0
- package/src/render/dom/projection/default-scale-correctors.ts +138 -0
- package/src/render/dom/projection/measure.ts +28 -0
- package/src/render/dom/projection/relative-set.ts +27 -0
- package/src/render/dom/projection/scale-correction.ts +22 -0
- package/src/render/dom/projection/types.ts +13 -0
- package/src/render/dom/projection/utils.ts +69 -0
- package/src/render/dom/svg-visual-element.ts +114 -0
- package/src/render/dom/types.ts +32 -0
- package/src/render/dom/use-render.ts +11 -0
- package/src/render/dom/utils/UseInitialMotionProps.svelte +26 -0
- package/src/render/dom/utils/batch-layout.ts +77 -0
- package/src/render/dom/utils/camel-to-dash.ts +20 -0
- package/src/render/dom/utils/create-config.ts +33 -0
- package/src/render/dom/utils/css-variables-conversion.ts +121 -0
- package/src/render/dom/utils/filter-props.ts +55 -0
- package/src/render/dom/utils/is-css-variable.ts +18 -0
- package/src/render/dom/utils/is-svg-component.ts +41 -0
- package/src/render/dom/utils/parse-dom-variant.ts +26 -0
- package/src/render/dom/utils/unit-conversion.ts +258 -0
- package/src/render/dom/utils/use-html-props.ts +2 -0
- package/src/render/dom/utils/use-svg-props.ts +1 -0
- package/src/render/dom/value-types/animatable-none.ts +24 -0
- package/src/render/dom/value-types/defaults.ts +30 -0
- package/src/render/dom/value-types/dimensions.ts +27 -0
- package/src/render/dom/value-types/find.ts +31 -0
- package/src/render/dom/value-types/get-as-type.ts +21 -0
- package/src/render/dom/value-types/number.ts +83 -0
- package/src/render/dom/value-types/test.ts +17 -0
- package/src/render/dom/value-types/type-auto.ts +21 -0
- package/src/render/dom/value-types/type-int.ts +23 -0
- package/src/render/dom/value-types/types.ts +8 -0
- package/src/render/html/UseHTMLProps.svelte +33 -0
- package/src/render/html/UseInitialMotionValues.svelte +27 -0
- package/src/render/html/UseStyle.svelte +47 -0
- package/src/render/html/config-motion.ts +23 -0
- package/src/render/html/supported-elements.ts +10 -0
- package/src/render/html/types.ts +64 -0
- package/src/render/html/use-props.ts +14 -0
- package/src/render/html/utils/build-projection-transform.ts +53 -0
- package/src/render/html/utils/build-styles.ts +121 -0
- package/src/render/html/utils/build-transform.ts +79 -0
- package/src/render/html/utils/create-render-state.ts +18 -0
- package/src/render/html/utils/render.ts +22 -0
- package/src/render/html/utils/scrape-motion-values.ts +26 -0
- package/src/render/html/utils/transform.ts +51 -0
- package/src/render/html/visual-element.ts +129 -0
- package/src/render/index.ts +703 -0
- package/src/render/svg/UseSVGProps.svelte +34 -0
- package/src/render/svg/config-motion.ts +51 -0
- package/src/render/svg/lowercase-elements.ts +35 -0
- package/src/render/svg/supported-elements.ts +10 -0
- package/src/render/svg/types.ts +51 -0
- package/src/render/svg/use-props.ts +14 -0
- package/src/render/svg/utils/build-attrs.ts +58 -0
- package/src/render/svg/utils/camel-case-attrs.ts +27 -0
- package/src/render/svg/utils/create-render-state.ts +17 -0
- package/src/render/svg/utils/path.ts +49 -0
- package/src/render/svg/utils/render.ts +22 -0
- package/src/render/svg/utils/scrape-motion-values.ts +26 -0
- package/src/render/svg/utils/transform-origin.ts +30 -0
- package/src/render/svg/visual-element.ts +44 -0
- package/src/render/types.ts +148 -0
- package/src/render/utils/animation-state.ts +375 -0
- package/src/render/utils/animation.ts +167 -0
- package/src/render/utils/compare-by-depth.ts +18 -0
- package/src/render/utils/flat-tree.ts +35 -0
- package/src/render/utils/is-draggable.ts +17 -0
- package/src/render/utils/lifecycles.ts +172 -0
- package/src/render/utils/motion-values.ts +59 -0
- package/src/render/utils/projection.ts +38 -0
- package/src/render/utils/setters.ts +910 -0
- package/src/render/utils/state.ts +113 -0
- package/src/render/utils/types.ts +12 -0
- package/src/render/utils/variants.ts +76 -0
- package/src/types/geometry.ts +91 -0
- package/src/types.ts +1088 -0
- package/src/utils/UseUnmountEffect.svelte +11 -0
- package/src/utils/array.ts +18 -0
- package/src/utils/each-axis.ts +15 -0
- package/src/utils/errors.ts +22 -0
- package/src/utils/fix-process-env.ts +22 -0
- package/src/utils/geometry/delta-apply.ts +162 -0
- package/src/utils/geometry/delta-calc.ts +89 -0
- package/src/utils/geometry/index.ts +83 -0
- package/src/utils/is-browser.ts +12 -0
- package/src/utils/is-numerical-string.ts +15 -0
- package/src/utils/is-ref-object.ts +16 -0
- package/src/utils/noop.ts +15 -0
- package/src/utils/resolve-value.ts +23 -0
- package/src/utils/shallow-compare.ts +23 -0
- package/src/utils/subscription-manager.ts +49 -0
- package/src/utils/time-conversion.ts +18 -0
- package/src/utils/transform.ts +120 -0
- package/src/utils/use-constant.ts +23 -0
- package/src/utils/use-cycle.ts +78 -0
- package/src/utils/use-force-update.ts +7 -0
- package/src/utils/use-isomorphic-effect.ts +8 -0
- package/src/utils/use-reduced-motion.ts +70 -0
- package/src/utils/use-unmount-effect.ts +8 -0
- package/src/value/index.ts +409 -0
- package/src/value/scroll/use-element-scroll.ts +73 -0
- package/src/value/scroll/use-viewport-scroll.ts +81 -0
- package/src/value/scroll/utils.ts +76 -0
- package/src/value/use-combine-values.ts +53 -0
- package/src/value/use-motion-template.ts +57 -0
- package/src/value/use-motion-value.ts +27 -0
- package/src/value/use-spring.ts +84 -0
- package/src/value/use-transform.ts +216 -0
- package/src/value/use-velocity.ts +44 -0
- package/src/value/utils/is-motion-value.ts +15 -0
- package/src/value/utils/resolve-motion-value.ts +29 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.0.3,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
import { fixed } from '../utils/fix-process-env.js';
|
|
6
|
+
import sync, { getFrameData } from 'framesync';
|
|
7
|
+
import { velocityPerSecond } from 'popmotion';
|
|
8
|
+
import { SubscriptionManager } from '../utils/subscription-manager.js';
|
|
9
|
+
/**
|
|
10
|
+
based on framer-motion@4.1.17,
|
|
11
|
+
Copyright (c) 2018 Framer B.V.
|
|
12
|
+
*/
|
|
13
|
+
import type { Writable, Unsubscriber } from 'svelte/store'
|
|
14
|
+
export type Transformer<T> = (v: T) => T;
|
|
15
|
+
/**
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export type Subscriber<T> = (v: T) => void;
|
|
19
|
+
/**
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export type PassiveEffect<T> = (v: T, safeSetter: (v: T) => void) => void;
|
|
23
|
+
export type StartAnimation = (complete: () => void) => (() => void) | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* `MotionValue` is used to track the state and velocity of motion values.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export class MotionValue<V = any> implements Writable<V> {
|
|
30
|
+
/**
|
|
31
|
+
* Subscribe method to make MotionValue compatible with Svelte store. Returns a unsubscribe function.
|
|
32
|
+
* Same as onChange.
|
|
33
|
+
*
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
subscribe(this: void & MotionValue<V>, subscription: Subscriber<V>): Unsubscriber {
|
|
37
|
+
return this.onChange(subscription);
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Update method to make MotionValue compatible with Svelte writable store
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
update(cb:(value: V) => V): void {
|
|
45
|
+
this.set(cb(this.get()));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The current state of the `MotionValue`.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
private current: V;
|
|
53
|
+
/**
|
|
54
|
+
* The previous state of the `MotionValue`.
|
|
55
|
+
*
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
private prev: V;
|
|
59
|
+
/**
|
|
60
|
+
* Duration, in milliseconds, since last updating frame.
|
|
61
|
+
*
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
private timeDelta = 0;
|
|
65
|
+
/**
|
|
66
|
+
* Timestamp of the last time this `MotionValue` was updated.
|
|
67
|
+
*
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
private lastUpdated = 0;
|
|
71
|
+
/**
|
|
72
|
+
* Functions to notify when the `MotionValue` updates.
|
|
73
|
+
*
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
private updateSubscribers = new SubscriptionManager()
|
|
77
|
+
/**
|
|
78
|
+
* Functions to notify when the velocity updates.
|
|
79
|
+
*
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
velocityUpdateSubscribers: SubscriptionManager<Subscriber<number>> = new SubscriptionManager();
|
|
83
|
+
/**
|
|
84
|
+
* Functions to notify when the `MotionValue` updates and `render` is set to `true`.
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
private renderSubscribers = new SubscriptionManager();
|
|
89
|
+
/**
|
|
90
|
+
* Add a passive effect to this `MotionValue`.
|
|
91
|
+
*
|
|
92
|
+
* A passive effect intercepts calls to `set`. For instance, `useSpring` adds
|
|
93
|
+
* a passive effect that attaches a `spring` to the latest
|
|
94
|
+
* set value. Hypothetically there could be a `useSmooth` that attaches an input smoothing effect.
|
|
95
|
+
*
|
|
96
|
+
* @internal
|
|
97
|
+
*/
|
|
98
|
+
private passiveEffect?: PassiveEffect<V>;
|
|
99
|
+
/**
|
|
100
|
+
* A reference to the currently-controlling Popmotion animation
|
|
101
|
+
*
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
private stopAnimation?: (() => void) | null | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Tracks whether this value can output a velocity. Currently this is only true
|
|
107
|
+
* if the value is numerical, but we might be able to widen the scope here and support
|
|
108
|
+
* other value types.
|
|
109
|
+
*
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
private canTrackVelocity = false;
|
|
113
|
+
|
|
114
|
+
private onSubscription = () => { }
|
|
115
|
+
private onUnsubscription = () => { }
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @param init - The initiating value
|
|
119
|
+
* @param startStopNotifier - a function that is called, once the first subscriber is added to this motion value.
|
|
120
|
+
* The return function is called, when the last subscriber unsubscribes.
|
|
121
|
+
*
|
|
122
|
+
* - `transformer`: A function to transform incoming values with.
|
|
123
|
+
*
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
constructor(init: V, startStopNotifier?: ()=>()=>void) {
|
|
127
|
+
this.prev = this.current = init;
|
|
128
|
+
this.canTrackVelocity = isFloat(this.current);
|
|
129
|
+
|
|
130
|
+
if (startStopNotifier) {
|
|
131
|
+
this.onSubscription = () => {
|
|
132
|
+
if (this.updateSubscribers.getSize() + this.velocityUpdateSubscribers.getSize() + this.renderSubscribers.getSize() === 0) {
|
|
133
|
+
|
|
134
|
+
const unsub = startStopNotifier()
|
|
135
|
+
this.onUnsubscription = () => { }
|
|
136
|
+
if (unsub) {
|
|
137
|
+
this.onUnsubscription = () => {
|
|
138
|
+
if (this.updateSubscribers.getSize() + this.velocityUpdateSubscribers.getSize() + this.renderSubscribers.getSize() === 0) {
|
|
139
|
+
unsub()
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Adds a function that will be notified when the `MotionValue` is updated.
|
|
150
|
+
*
|
|
151
|
+
* It returns a function that, when called, will cancel the subscription.
|
|
152
|
+
*
|
|
153
|
+
* When calling `onChange` inside a React component, it should be wrapped with the
|
|
154
|
+
* `useEffect` hook. As it returns an unsubscribe function, this should be returned
|
|
155
|
+
* from the `useEffect` function to ensure you don't add duplicate subscribers..
|
|
156
|
+
*
|
|
157
|
+
|
|
158
|
+
* @motion
|
|
159
|
+
*
|
|
160
|
+
* ```jsx
|
|
161
|
+
* <script>
|
|
162
|
+
* import { useMotionValue } from 'svelte-motion'
|
|
163
|
+
*
|
|
164
|
+
* const x = useMotionValue(0)
|
|
165
|
+
* const y = useMotionValue(0)
|
|
166
|
+
* const opacity = useMotionValue(1)
|
|
167
|
+
*
|
|
168
|
+
*
|
|
169
|
+
* function updateOpacity() {
|
|
170
|
+
* const maxXY = Math.max(x.get(), y.get())
|
|
171
|
+
* const newOpacity = transform(maxXY, [0, 100], [1, 0])
|
|
172
|
+
* opacity.set(newOpacity)
|
|
173
|
+
* }
|
|
174
|
+
*
|
|
175
|
+
* // framer-motion style:
|
|
176
|
+
* const unsubscribeX = x.onChange(updateOpacity)
|
|
177
|
+
* onDestroy(()=>{
|
|
178
|
+
* unsubscribeX()
|
|
179
|
+
* })
|
|
180
|
+
* // equivalent Svelte style. Subscription and un-subscription is automatically handled:
|
|
181
|
+
* $: updateOpacity($y)
|
|
182
|
+
* </script>
|
|
183
|
+
*
|
|
184
|
+
* <Motion let:motion style={{ x }}><div use:motion/></Motion>
|
|
185
|
+
* ```
|
|
186
|
+
*
|
|
187
|
+
* @param subscriber - A function that receives the latest value.
|
|
188
|
+
* @returns A function that, when called, will cancel this subscription.
|
|
189
|
+
*
|
|
190
|
+
* @public
|
|
191
|
+
*/
|
|
192
|
+
onChange(subscription: Subscriber<V>): () => void {
|
|
193
|
+
this.onSubscription();
|
|
194
|
+
const unsub = this.updateSubscribers.add(subscription);
|
|
195
|
+
return () => {
|
|
196
|
+
unsub()
|
|
197
|
+
this.onUnsubscription()
|
|
198
|
+
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
clearListeners(): void {
|
|
202
|
+
this.updateSubscribers.clear();
|
|
203
|
+
this.onUnsubscription()
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Adds a function that will be notified when the `MotionValue` requests a render.
|
|
207
|
+
*
|
|
208
|
+
* @param subscriber - A function that's provided the latest value.
|
|
209
|
+
* @returns A function that, when called, will cancel this subscription.
|
|
210
|
+
*
|
|
211
|
+
* @internal
|
|
212
|
+
*/
|
|
213
|
+
onRenderRequest(subscription: Subscriber<V>): () => void {
|
|
214
|
+
this.onSubscription()
|
|
215
|
+
// Render immediately
|
|
216
|
+
subscription(this.get());
|
|
217
|
+
const unsub = this.renderSubscribers.add(subscription);
|
|
218
|
+
return () => {
|
|
219
|
+
unsub()
|
|
220
|
+
this.onUnsubscription()
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Attaches a passive effect to the `MotionValue`.
|
|
225
|
+
*
|
|
226
|
+
* @internal
|
|
227
|
+
*/
|
|
228
|
+
attach(passiveEffect: PassiveEffect<V>): void {
|
|
229
|
+
this.passiveEffect = passiveEffect;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Sets the state of the `MotionValue`.
|
|
233
|
+
*
|
|
234
|
+
* @remarks
|
|
235
|
+
*
|
|
236
|
+
* ```jsx
|
|
237
|
+
* const x = useMotionValue(0)
|
|
238
|
+
* x.set(10)
|
|
239
|
+
* ```
|
|
240
|
+
*
|
|
241
|
+
* @param latest - Latest value to set.
|
|
242
|
+
* @param render - Whether to notify render subscribers. Defaults to `true`
|
|
243
|
+
*
|
|
244
|
+
* @public
|
|
245
|
+
*/
|
|
246
|
+
set(v: V, render?: boolean): void {
|
|
247
|
+
if (render === void 0) { render = true; }
|
|
248
|
+
if (!render || !this.passiveEffect) {
|
|
249
|
+
this.updateAndNotify(v, render);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
this.passiveEffect(v, this.updateAndNotify);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
updateAndNotify(v: V, render?: boolean): void {
|
|
256
|
+
if (render === void 0) { render = true; }
|
|
257
|
+
this.prev = this.current;
|
|
258
|
+
this.current = v;
|
|
259
|
+
// Update timestamp
|
|
260
|
+
var _a = getFrameData(), delta = _a.delta, timestamp = _a.timestamp;
|
|
261
|
+
if (this.lastUpdated !== timestamp) {
|
|
262
|
+
this.timeDelta = delta;
|
|
263
|
+
this.lastUpdated = timestamp;
|
|
264
|
+
sync.postRender(this.scheduleVelocityCheck);
|
|
265
|
+
}
|
|
266
|
+
// Update update subscribers
|
|
267
|
+
if (this.prev !== this.current) {
|
|
268
|
+
this.updateSubscribers.notify(this.current);
|
|
269
|
+
}
|
|
270
|
+
// Update velocity subscribers
|
|
271
|
+
if (this.velocityUpdateSubscribers.getSize()) {
|
|
272
|
+
this.velocityUpdateSubscribers.notify(this.getVelocity());
|
|
273
|
+
}
|
|
274
|
+
// Update render subscribers
|
|
275
|
+
if (render) {
|
|
276
|
+
this.renderSubscribers.notify(this.current);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Returns the latest state of `MotionValue`
|
|
281
|
+
*
|
|
282
|
+
* @returns - The latest state of `MotionValue`
|
|
283
|
+
*
|
|
284
|
+
* @public
|
|
285
|
+
*/
|
|
286
|
+
get(): V {
|
|
287
|
+
this.onSubscription()
|
|
288
|
+
const curr = this.current;
|
|
289
|
+
this.onUnsubscription()
|
|
290
|
+
return curr
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* @public
|
|
294
|
+
*/
|
|
295
|
+
getPrevious(): V {
|
|
296
|
+
return this.prev;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Returns the latest velocity of `MotionValue`
|
|
300
|
+
*
|
|
301
|
+
* @returns - The latest velocity of `MotionValue`. Returns `0` if the state is non-numerical.
|
|
302
|
+
*
|
|
303
|
+
* @public
|
|
304
|
+
*/
|
|
305
|
+
getVelocity(): number {
|
|
306
|
+
// This could be isFloat(this.prev) && isFloat(this.current), but that would be wasteful
|
|
307
|
+
this.onSubscription()
|
|
308
|
+
const vel = this.canTrackVelocity
|
|
309
|
+
? // These casts could be avoided if parseFloat would be typed better
|
|
310
|
+
velocityPerSecond(parseFloat(String(this.current)) -
|
|
311
|
+
parseFloat(String(this.prev)), this.timeDelta)
|
|
312
|
+
: 0;
|
|
313
|
+
this.onUnsubscription()
|
|
314
|
+
return vel;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Schedule a velocity check for the next frame.
|
|
318
|
+
*
|
|
319
|
+
* This is an instanced and bound function to prevent generating a new
|
|
320
|
+
* function once per frame.
|
|
321
|
+
*
|
|
322
|
+
* @internal
|
|
323
|
+
*/
|
|
324
|
+
private scheduleVelocityCheck() { return sync.postRender(this.velocityCheck); }
|
|
325
|
+
/**
|
|
326
|
+
* Updates `prev` with `current` if the value hasn't been updated this frame.
|
|
327
|
+
* This ensures velocity calculations return `0`.
|
|
328
|
+
*
|
|
329
|
+
* This is an instanced and bound function to prevent generating a new
|
|
330
|
+
* function once per frame.
|
|
331
|
+
*
|
|
332
|
+
* @internal
|
|
333
|
+
*/
|
|
334
|
+
private velocityCheck(_a: { timestamp: any; }) {
|
|
335
|
+
var timestamp = _a.timestamp;
|
|
336
|
+
if (timestamp !== this.lastUpdated) {
|
|
337
|
+
this.prev = this.current;
|
|
338
|
+
this.velocityUpdateSubscribers.notify(this.getVelocity());
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
hasAnimated: boolean = false;
|
|
342
|
+
/**
|
|
343
|
+
* Registers a new animation to control this `MotionValue`. Only one
|
|
344
|
+
* animation can drive a `MotionValue` at one time.
|
|
345
|
+
*
|
|
346
|
+
* ```jsx
|
|
347
|
+
* value.start()
|
|
348
|
+
* ```
|
|
349
|
+
*
|
|
350
|
+
* @param animation - A function that starts the provided animation
|
|
351
|
+
*
|
|
352
|
+
* @internal
|
|
353
|
+
*/
|
|
354
|
+
start(animation: StartAnimation): Promise<void> {
|
|
355
|
+
this.stop();
|
|
356
|
+
return new Promise((resolve) => {
|
|
357
|
+
this.hasAnimated = true;
|
|
358
|
+
this.stopAnimation = animation(resolve);
|
|
359
|
+
}).then(() => { return this.clearAnimation(); });
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Stop the currently active animation.
|
|
363
|
+
*
|
|
364
|
+
* @public
|
|
365
|
+
*/
|
|
366
|
+
stop(): void {
|
|
367
|
+
if (this.stopAnimation)
|
|
368
|
+
this.stopAnimation();
|
|
369
|
+
this.clearAnimation();
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Returns `true` if this value is currently animating.
|
|
373
|
+
*
|
|
374
|
+
* @public
|
|
375
|
+
*/
|
|
376
|
+
isAnimating(): boolean {
|
|
377
|
+
return !!this.stopAnimation;
|
|
378
|
+
}
|
|
379
|
+
private clearAnimation() {
|
|
380
|
+
this.stopAnimation = null;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Destroy and clean up subscribers to this `MotionValue`.
|
|
384
|
+
*
|
|
385
|
+
* The `MotionValue` hooks like `useMotionValue` and `useTransform` automatically
|
|
386
|
+
* handle the lifecycle of the returned `MotionValue`, so this method is only necessary if you've manually
|
|
387
|
+
* created a `MotionValue` via the `motionValue` function.
|
|
388
|
+
*
|
|
389
|
+
* @public
|
|
390
|
+
*/
|
|
391
|
+
destroy(): void {
|
|
392
|
+
this.updateSubscribers.clear();
|
|
393
|
+
this.renderSubscribers.clear();
|
|
394
|
+
this.stop();
|
|
395
|
+
this.onUnsubscription()
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
var isFloat = function (value: string) {
|
|
400
|
+
return !isNaN(parseFloat(value));
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* @internal
|
|
405
|
+
*/
|
|
406
|
+
export function motionValue<V>(init: V, startStopNotifier?: () => () => void): MotionValue<V> {
|
|
407
|
+
return new MotionValue(init, startStopNotifier);
|
|
408
|
+
}
|
|
409
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.1.17,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
import type { ScrollMotionValues } from "./utils";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
based on framer-motion@4.1.16,
|
|
10
|
+
Copyright (c) 2018 Framer B.V.
|
|
11
|
+
*/
|
|
12
|
+
import {
|
|
13
|
+
createScrollMotionValues,
|
|
14
|
+
createScrollUpdater,
|
|
15
|
+
} from "./utils"
|
|
16
|
+
import { addDomEvent } from "../../events/use-dom-event"
|
|
17
|
+
import type { RefObject } from "react";
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const getElementScrollOffsets = (element) => () => {
|
|
21
|
+
return {
|
|
22
|
+
xOffset: element.scrollLeft,
|
|
23
|
+
yOffset: element.scrollTop,
|
|
24
|
+
xMaxOffset: element.scrollWidth - element.offsetWidth,
|
|
25
|
+
yMaxOffset: element.scrollHeight - element.offsetHeight,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const useElementScroll = (ref: RefObject<HTMLElement>) => {
|
|
30
|
+
|
|
31
|
+
const values = <any>{}
|
|
32
|
+
|
|
33
|
+
const setScroll = async () => {
|
|
34
|
+
if (typeof window === "undefined") return ()=>{}
|
|
35
|
+
|
|
36
|
+
let times = 10
|
|
37
|
+
while ( (!ref || !ref.current) && !values.ref ){
|
|
38
|
+
if(times-- < 1){
|
|
39
|
+
return ()=>{};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
await new Promise(r=>setTimeout(()=>r(),200));
|
|
43
|
+
}
|
|
44
|
+
const element = (ref && ref.current) ? ref : values.ref;
|
|
45
|
+
|
|
46
|
+
const updateScrollValues = createScrollUpdater(
|
|
47
|
+
values,
|
|
48
|
+
getElementScrollOffsets(element)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const scrollListener = addDomEvent(
|
|
52
|
+
element,
|
|
53
|
+
"scroll",
|
|
54
|
+
updateScrollValues,
|
|
55
|
+
{ passive: true }
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
const resizeListener = addDomEvent(
|
|
59
|
+
element,
|
|
60
|
+
"resize",
|
|
61
|
+
updateScrollValues
|
|
62
|
+
)
|
|
63
|
+
return ()=>{
|
|
64
|
+
scrollListener && scrollListener()
|
|
65
|
+
resizeListener && resizeListener()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
Object.assign(values,createScrollMotionValues(setScroll));
|
|
69
|
+
|
|
70
|
+
return values as ScrollMotionValues;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//export { default as UseElementScroll } from './UseElementScroll.svelte';
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.1.17,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
import type { ScrollMotionValues } from "./utils";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
based on framer-motion@4.1.16,
|
|
10
|
+
Copyright (c) 2018 Framer B.V.
|
|
11
|
+
*/
|
|
12
|
+
import {
|
|
13
|
+
createScrollMotionValues,
|
|
14
|
+
createScrollUpdater,
|
|
15
|
+
} from "./utils"
|
|
16
|
+
import { addDomEvent } from "../../events/use-dom-event"
|
|
17
|
+
import { tick } from "svelte"
|
|
18
|
+
|
|
19
|
+
let viewportScrollValues
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
function getViewportScrollOffsets() {
|
|
23
|
+
return {
|
|
24
|
+
xOffset: window.pageXOffset,
|
|
25
|
+
yOffset: window.pageYOffset,
|
|
26
|
+
xMaxOffset: document.body.clientWidth - window.innerWidth,
|
|
27
|
+
yMaxOffset: document.body.clientHeight - window.innerHeight,
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let hasListeners = false
|
|
32
|
+
|
|
33
|
+
function addEventListeners() {
|
|
34
|
+
hasListeners = true
|
|
35
|
+
if (typeof window === "undefined") return
|
|
36
|
+
|
|
37
|
+
const updateScrollValues = createScrollUpdater(
|
|
38
|
+
viewportScrollValues,
|
|
39
|
+
getViewportScrollOffsets
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
addDomEvent(window, "scroll", updateScrollValues, { passive: true })
|
|
43
|
+
addDomEvent(window, "resize", updateScrollValues)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns MotionValues that update when the viewport scrolls:
|
|
48
|
+
*
|
|
49
|
+
* - `scrollX` — Horizontal scroll distance in pixels.
|
|
50
|
+
* - `scrollY` — Vertical scroll distance in pixels.
|
|
51
|
+
* - `scrollXProgress` — Horizontal scroll progress between `0` and `1`.
|
|
52
|
+
* - `scrollYProgress` — Vertical scroll progress between `0` and `1`.
|
|
53
|
+
*
|
|
54
|
+
* **Warning:** Setting `body` or `html` to `height: 100%` or similar will break the `Progress`
|
|
55
|
+
* values as this breaks the browser's capability to accurately measure the page length.
|
|
56
|
+
*
|
|
57
|
+
* @motion
|
|
58
|
+
*
|
|
59
|
+
* ```jsx
|
|
60
|
+
* export const MyComponent = () => {
|
|
61
|
+
* const { scrollYProgress } = useViewportScroll()
|
|
62
|
+
* return <MotionDiv style={{ scaleX: scrollYProgress }} />
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export function useViewportScroll() {
|
|
69
|
+
/**
|
|
70
|
+
* Lazy-initialise the viewport scroll values
|
|
71
|
+
*/
|
|
72
|
+
if (!viewportScrollValues) {
|
|
73
|
+
viewportScrollValues = createScrollMotionValues()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
tick().then(_=>{
|
|
77
|
+
!hasListeners && addEventListeners()
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
return viewportScrollValues as ScrollMotionValues
|
|
81
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.1.17,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
import { MotionValue } from "../index.js";
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export interface ScrollMotionValues {
|
|
10
|
+
scrollX: MotionValue<number>;
|
|
11
|
+
scrollY: MotionValue<number>;
|
|
12
|
+
scrollXProgress: MotionValue<number>;
|
|
13
|
+
scrollYProgress: MotionValue<number>;
|
|
14
|
+
}
|
|
15
|
+
export interface ScrollOffsets {
|
|
16
|
+
xOffset: number;
|
|
17
|
+
yOffset: number;
|
|
18
|
+
xMaxOffset: number;
|
|
19
|
+
yMaxOffset: number;
|
|
20
|
+
}
|
|
21
|
+
export type GetScrollOffsets = () => ScrollOffsets;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
based on framer-motion@4.0.3,
|
|
25
|
+
Copyright (c) 2018 Framer B.V.
|
|
26
|
+
*/
|
|
27
|
+
import { motionValue } from '../index.js';
|
|
28
|
+
|
|
29
|
+
function createScrollMotionValues(startStopNotifier?: any): ScrollMotionValues {
|
|
30
|
+
const hasListener = { x: false, y: false, xp: false, yp: false }
|
|
31
|
+
let stop
|
|
32
|
+
const jointNotifier = startStopNotifier ? (type) => ()=>{
|
|
33
|
+
if (!hasListener.x && !hasListener.y && !hasListener.xp && !hasListener.yp) {
|
|
34
|
+
stop = startStopNotifier();
|
|
35
|
+
}
|
|
36
|
+
hasListener[type] = true;
|
|
37
|
+
return () => {
|
|
38
|
+
hasListener[type] = false;
|
|
39
|
+
if (!hasListener.x && !hasListener.y && !hasListener.xp && !hasListener.yp) {
|
|
40
|
+
if (stop){
|
|
41
|
+
stop.then(v=>v())
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
} : ()=>() => { }
|
|
48
|
+
|
|
49
|
+
const smvs = {
|
|
50
|
+
scrollX: motionValue(0,jointNotifier("x")),
|
|
51
|
+
scrollY: motionValue(0,jointNotifier("y")),
|
|
52
|
+
scrollXProgress: motionValue(0,jointNotifier("xp")),
|
|
53
|
+
scrollYProgress: motionValue(0,jointNotifier("yp")),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return smvs;
|
|
57
|
+
}
|
|
58
|
+
function setProgress(offset, maxOffset, value) {
|
|
59
|
+
value.set(!offset || !maxOffset ? 0 : offset / maxOffset);
|
|
60
|
+
}
|
|
61
|
+
function createScrollUpdater(values: ScrollMotionValues, getOffsets: GetScrollOffsets) {
|
|
62
|
+
var update = function () {
|
|
63
|
+
var _a = getOffsets(), xOffset = _a.xOffset, yOffset = _a.yOffset, xMaxOffset = _a.xMaxOffset, yMaxOffset = _a.yMaxOffset;
|
|
64
|
+
// Set absolute positions
|
|
65
|
+
values.scrollX.set(xOffset);
|
|
66
|
+
values.scrollY.set(yOffset);
|
|
67
|
+
// Set 0-1 progress
|
|
68
|
+
setProgress(xOffset, xMaxOffset, values.scrollXProgress);
|
|
69
|
+
setProgress(yOffset, yMaxOffset, values.scrollYProgress);
|
|
70
|
+
};
|
|
71
|
+
update();
|
|
72
|
+
return update;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { createScrollMotionValues, createScrollUpdater };
|
|
76
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.1.17,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
import { MotionValue } from ".";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
based on framer-motion@4.0.3,
|
|
9
|
+
Copyright (c) 2018 Framer B.V.
|
|
10
|
+
*/
|
|
11
|
+
import sync from 'framesync';
|
|
12
|
+
import { motionValue } from '.';
|
|
13
|
+
|
|
14
|
+
export const useCombineMotionValues = <R>(values: MotionValue[], combineValues: () => R) => {
|
|
15
|
+
|
|
16
|
+
let subscriptions: Function[] = <any>[];
|
|
17
|
+
let vals = values;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const unsubscribe = ()=>{
|
|
21
|
+
subscriptions.forEach((unsubscribe) => unsubscribe())
|
|
22
|
+
}
|
|
23
|
+
const subscribe = () => {
|
|
24
|
+
subscriptions = vals.map((val) => val.onChange(handler))
|
|
25
|
+
updateValue();
|
|
26
|
+
}
|
|
27
|
+
const value = motionValue(combineValues(), () => {
|
|
28
|
+
unsubscribe()
|
|
29
|
+
subscribe()
|
|
30
|
+
return unsubscribe;
|
|
31
|
+
}) as MotionValue<R> & { reset: ( values:MotionValue[], combineValues:()=>R ) => void };
|
|
32
|
+
|
|
33
|
+
let updateValue = () => {
|
|
34
|
+
value.set(combineValues());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const handler = () => {
|
|
38
|
+
sync.update(updateValue, false, true);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
value.reset = (_values, _combineValues) => {
|
|
42
|
+
vals=_values;
|
|
43
|
+
//cleanup and reset
|
|
44
|
+
unsubscribe()
|
|
45
|
+
updateValue = () => {
|
|
46
|
+
value.set(_combineValues())
|
|
47
|
+
}
|
|
48
|
+
subscribe()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
// export { default as UseCombineMotionValues } from "./UseCombineValues.svelte";
|