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,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.1.17,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
import type { PlaybackControls } from "popmotion";
|
|
6
|
+
import type { ResolvedValues, VisualElement } from "../../../render/types";
|
|
7
|
+
import type { Transition } from "../../../types";
|
|
8
|
+
export interface Crossfader {
|
|
9
|
+
isActive(): boolean;
|
|
10
|
+
getCrossfadeState(element: VisualElement): ResolvedValues | undefined;
|
|
11
|
+
toLead(transition?: Transition): PlaybackControls;
|
|
12
|
+
fromLead(transition?: Transition): PlaybackControls;
|
|
13
|
+
setOptions(options: CrossfadeAnimationOptions): void;
|
|
14
|
+
reset(): void;
|
|
15
|
+
stop(): void;
|
|
16
|
+
getLatestValues(): ResolvedValues;
|
|
17
|
+
}
|
|
18
|
+
export interface CrossfadeAnimationOptions {
|
|
19
|
+
lead?: VisualElement;
|
|
20
|
+
follow?: VisualElement;
|
|
21
|
+
prevValues?: ResolvedValues;
|
|
22
|
+
crossfadeOpacity?: boolean;
|
|
23
|
+
preserveFollowOpacity?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
based on framer-motion@4.0.3,
|
|
29
|
+
Copyright (c) 2018 Framer B.V.
|
|
30
|
+
*/
|
|
31
|
+
import {fixed} from '../../../utils/fix-process-env.js';
|
|
32
|
+
import { __assign } from 'tslib';
|
|
33
|
+
import sync, { getFrameData } from 'framesync';
|
|
34
|
+
import { mix, progress, linear, mixColor, circOut } from 'popmotion';
|
|
35
|
+
import { animate } from '../../../animation/animate.js';
|
|
36
|
+
import { getValueTransition } from '../../../animation/utils/transitions.js';
|
|
37
|
+
import { motionValue } from '../../../value/index.js';
|
|
38
|
+
|
|
39
|
+
function createCrossfader(): Crossfader {
|
|
40
|
+
/**
|
|
41
|
+
* The current state of the crossfade as a value between 0 and 1
|
|
42
|
+
*/
|
|
43
|
+
var progress = motionValue(1);
|
|
44
|
+
var options = {
|
|
45
|
+
lead: undefined,
|
|
46
|
+
follow: undefined,
|
|
47
|
+
crossfadeOpacity: false,
|
|
48
|
+
preserveFollowOpacity: false,
|
|
49
|
+
};
|
|
50
|
+
var prevOptions = __assign({}, options);
|
|
51
|
+
var leadState = {};
|
|
52
|
+
var followState = {};
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
*/
|
|
56
|
+
var isActive = false;
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
*/
|
|
60
|
+
var finalCrossfadeFrame = null;
|
|
61
|
+
/**
|
|
62
|
+
* Framestamp of the last frame we updated values at.
|
|
63
|
+
*/
|
|
64
|
+
var prevUpdate = 0;
|
|
65
|
+
function startCrossfadeAnimation(target, transition) {
|
|
66
|
+
var lead = options.lead, follow = options.follow;
|
|
67
|
+
isActive = true;
|
|
68
|
+
finalCrossfadeFrame = null;
|
|
69
|
+
var hasUpdated = false;
|
|
70
|
+
var onUpdate = function () {
|
|
71
|
+
hasUpdated = true;
|
|
72
|
+
lead && lead.scheduleRender();
|
|
73
|
+
follow && follow.scheduleRender();
|
|
74
|
+
};
|
|
75
|
+
var onComplete = function () {
|
|
76
|
+
isActive = false;
|
|
77
|
+
/**
|
|
78
|
+
* If the crossfade animation is no longer active, flag a frame
|
|
79
|
+
* that we're still allowed to crossfade
|
|
80
|
+
*/
|
|
81
|
+
finalCrossfadeFrame = getFrameData().timestamp;
|
|
82
|
+
};
|
|
83
|
+
transition = transition && getValueTransition(transition, "crossfade");
|
|
84
|
+
return animate(progress, target, __assign(__assign({}, transition), { onUpdate: onUpdate, onComplete: function () {
|
|
85
|
+
if (!hasUpdated) {
|
|
86
|
+
progress.set(target);
|
|
87
|
+
/**
|
|
88
|
+
* If we never ran an update, for instance if this was an instant transition, fire a
|
|
89
|
+
* simulated final frame to ensure the crossfade gets applied correctly.
|
|
90
|
+
*/
|
|
91
|
+
sync.read(onComplete);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
onComplete();
|
|
95
|
+
}
|
|
96
|
+
onUpdate();
|
|
97
|
+
} }));
|
|
98
|
+
}
|
|
99
|
+
function updateCrossfade() {
|
|
100
|
+
var _a, _b;
|
|
101
|
+
/**
|
|
102
|
+
* We only want to compute the crossfade once per frame, so we
|
|
103
|
+
* compare the previous update framestamp with the current frame
|
|
104
|
+
* and early return if they're the same.
|
|
105
|
+
*/
|
|
106
|
+
var timestamp = getFrameData().timestamp;
|
|
107
|
+
var lead = options.lead, follow = options.follow;
|
|
108
|
+
if (timestamp === prevUpdate || !lead)
|
|
109
|
+
return;
|
|
110
|
+
prevUpdate = timestamp;
|
|
111
|
+
/**
|
|
112
|
+
* Merge each component's latest values into our crossfaded state
|
|
113
|
+
* before crossfading.
|
|
114
|
+
*/
|
|
115
|
+
var latestLeadValues = lead.getLatestValues();
|
|
116
|
+
Object.assign(leadState, latestLeadValues);
|
|
117
|
+
var latestFollowValues = follow
|
|
118
|
+
? follow.getLatestValues()
|
|
119
|
+
: options.prevValues;
|
|
120
|
+
Object.assign(followState, latestFollowValues);
|
|
121
|
+
var p = progress.get();
|
|
122
|
+
/**
|
|
123
|
+
* Crossfade the opacity between the two components. This will result
|
|
124
|
+
* in a different opacity for each component.
|
|
125
|
+
*/
|
|
126
|
+
var leadTargetOpacity = (_a = latestLeadValues.opacity) !== null && _a !== void 0 ? _a : 1;
|
|
127
|
+
var followTargetOpacity = (_b = latestFollowValues === null || latestFollowValues === void 0 ? void 0 : latestFollowValues.opacity) !== null && _b !== void 0 ? _b : 1;
|
|
128
|
+
if (options.crossfadeOpacity && follow) {
|
|
129
|
+
leadState.opacity = mix(
|
|
130
|
+
/**
|
|
131
|
+
* If the follow child has been completely hidden we animate
|
|
132
|
+
* this opacity from its previous opacity, but otherwise from completely transparent.
|
|
133
|
+
*/
|
|
134
|
+
follow.isVisible !== false ? 0 : followTargetOpacity, leadTargetOpacity, easeCrossfadeIn(p));
|
|
135
|
+
followState.opacity = options.preserveFollowOpacity
|
|
136
|
+
? followTargetOpacity
|
|
137
|
+
: mix(followTargetOpacity, 0, easeCrossfadeOut(p));
|
|
138
|
+
}
|
|
139
|
+
else if (!follow) {
|
|
140
|
+
leadState.opacity = mix(followTargetOpacity, leadTargetOpacity, p);
|
|
141
|
+
}
|
|
142
|
+
mixValues(leadState, followState, latestLeadValues, latestFollowValues || {}, Boolean(follow), p);
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
isActive: function () {
|
|
146
|
+
return leadState &&
|
|
147
|
+
(isActive || getFrameData().timestamp === finalCrossfadeFrame);
|
|
148
|
+
},
|
|
149
|
+
fromLead: function (transition) {
|
|
150
|
+
return startCrossfadeAnimation(0, transition);
|
|
151
|
+
},
|
|
152
|
+
toLead: function (transition) {
|
|
153
|
+
var initialProgress = 0;
|
|
154
|
+
if (!options.prevValues && !options.follow) {
|
|
155
|
+
/**
|
|
156
|
+
* If we're not coming from anywhere, start at the end of the animation.
|
|
157
|
+
*/
|
|
158
|
+
initialProgress = 1;
|
|
159
|
+
}
|
|
160
|
+
else if (prevOptions.lead === options.follow &&
|
|
161
|
+
prevOptions.follow === options.lead) {
|
|
162
|
+
/**
|
|
163
|
+
* If we're swapping follow/lead we can reverse the progress
|
|
164
|
+
*/
|
|
165
|
+
initialProgress = 1 - progress.get();
|
|
166
|
+
}
|
|
167
|
+
progress.set(initialProgress);
|
|
168
|
+
return startCrossfadeAnimation(1, transition);
|
|
169
|
+
},
|
|
170
|
+
reset: function () { return progress.set(1); },
|
|
171
|
+
stop: function () { return progress.stop(); },
|
|
172
|
+
getCrossfadeState: function (element) {
|
|
173
|
+
updateCrossfade();
|
|
174
|
+
if (element === options.lead) {
|
|
175
|
+
return leadState;
|
|
176
|
+
}
|
|
177
|
+
else if (element === options.follow) {
|
|
178
|
+
return followState;
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
setOptions: function (newOptions) {
|
|
182
|
+
prevOptions = options;
|
|
183
|
+
options = newOptions;
|
|
184
|
+
leadState = {};
|
|
185
|
+
followState = {};
|
|
186
|
+
},
|
|
187
|
+
getLatestValues: function () {
|
|
188
|
+
return leadState;
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
var easeCrossfadeIn = compress(0, 0.5, circOut);
|
|
193
|
+
var easeCrossfadeOut = compress(0.5, 0.95, linear);
|
|
194
|
+
function compress(min, max, easing) {
|
|
195
|
+
return function (p) {
|
|
196
|
+
// Could replace ifs with clamp
|
|
197
|
+
if (p < min)
|
|
198
|
+
return 0;
|
|
199
|
+
if (p > max)
|
|
200
|
+
return 1;
|
|
201
|
+
return easing(progress(min, max, p));
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
var borders = ["TopLeft", "TopRight", "BottomLeft", "BottomRight"];
|
|
205
|
+
var numBorders = borders.length;
|
|
206
|
+
function mixValues(leadState, followState, latestLeadValues, latestFollowValues, hasFollowElement, p) {
|
|
207
|
+
/**
|
|
208
|
+
* Mix border radius
|
|
209
|
+
*/
|
|
210
|
+
for (var i = 0; i < numBorders; i++) {
|
|
211
|
+
var borderLabel = "border" + borders[i] + "Radius";
|
|
212
|
+
var followRadius = getRadius(latestFollowValues, borderLabel);
|
|
213
|
+
var leadRadius = getRadius(latestLeadValues, borderLabel);
|
|
214
|
+
if (followRadius === undefined && leadRadius === undefined)
|
|
215
|
+
continue;
|
|
216
|
+
followRadius || (followRadius = 0);
|
|
217
|
+
leadRadius || (leadRadius = 0);
|
|
218
|
+
/**
|
|
219
|
+
* Currently we're only crossfading between numerical border radius.
|
|
220
|
+
* It would be possible to crossfade between percentages for a little
|
|
221
|
+
* extra bundle size.
|
|
222
|
+
*/
|
|
223
|
+
if (typeof followRadius === "number" &&
|
|
224
|
+
typeof leadRadius === "number") {
|
|
225
|
+
var radius = Math.max(mix(followRadius, leadRadius, p), 0);
|
|
226
|
+
leadState[borderLabel] = followState[borderLabel] = radius;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Mix rotation
|
|
231
|
+
*/
|
|
232
|
+
if (latestFollowValues.rotate || latestLeadValues.rotate) {
|
|
233
|
+
var rotate = mix(latestFollowValues.rotate || 0, latestLeadValues.rotate || 0, p);
|
|
234
|
+
leadState.rotate = followState.rotate = rotate;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* We only want to mix the background color if there's a follow element
|
|
238
|
+
* that we're not crossfading opacity between. For instance with switch
|
|
239
|
+
* AnimateSharedLayout animations, this helps the illusion of a continuous
|
|
240
|
+
* element being animated but also cuts down on the number of paints triggered
|
|
241
|
+
* for elements where opacity is doing that work for us.
|
|
242
|
+
*/
|
|
243
|
+
if (!hasFollowElement &&
|
|
244
|
+
latestLeadValues.backgroundColor &&
|
|
245
|
+
latestFollowValues.backgroundColor) {
|
|
246
|
+
/**
|
|
247
|
+
* This isn't ideal performance-wise as mixColor is creating a new function every frame.
|
|
248
|
+
* We could probably create a mixer that runs at the start of the animation but
|
|
249
|
+
* the idea behind the crossfader is that it runs dynamically between two potentially
|
|
250
|
+
* changing targets (ie opacity or borderRadius may be animating independently via variants)
|
|
251
|
+
*/
|
|
252
|
+
leadState.backgroundColor = followState.backgroundColor = mixColor(latestFollowValues.backgroundColor, latestLeadValues.backgroundColor)(p);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function getRadius(values, radiusName) {
|
|
256
|
+
var _a;
|
|
257
|
+
return (_a = values[radiusName]) !== null && _a !== void 0 ? _a : values.borderRadius;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { createCrossfader };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.1.17,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
import type { VisualElement } from "../../../render/types";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
based on framer-motion@4.0.3,
|
|
10
|
+
Copyright (c) 2018 Framer B.V.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { transformAxes } from '../../../render/html/utils/transform.js';
|
|
14
|
+
|
|
15
|
+
function resetRotate(child: VisualElement): void {
|
|
16
|
+
// If there's no detected rotation values, we can early return without a forced render.
|
|
17
|
+
var hasRotate = false;
|
|
18
|
+
// Keep a record of all the values we've reset
|
|
19
|
+
var resetValues = {};
|
|
20
|
+
// Check the rotate value of all axes and reset to 0
|
|
21
|
+
for (var i = 0; i < transformAxes.length; i++) {
|
|
22
|
+
var axis = transformAxes[i];
|
|
23
|
+
var key = "rotate" + axis;
|
|
24
|
+
// If this rotation doesn't exist as a motion value, then we don't
|
|
25
|
+
// need to reset it
|
|
26
|
+
if (!child.hasValue(key) || child.getStaticValue(key) === 0)
|
|
27
|
+
continue;
|
|
28
|
+
hasRotate = true;
|
|
29
|
+
// Record the rotation and then temporarily set it to 0
|
|
30
|
+
resetValues[key] = child.getStaticValue(key);
|
|
31
|
+
child.setStaticValue(key, 0);
|
|
32
|
+
}
|
|
33
|
+
// If there's no rotation values, we don't need to do any more.
|
|
34
|
+
if (!hasRotate)
|
|
35
|
+
return;
|
|
36
|
+
// Force a render of this element to apply the transform with all rotations
|
|
37
|
+
// set to 0.
|
|
38
|
+
child.syncRender();
|
|
39
|
+
// Put back all the values we reset
|
|
40
|
+
for (var key in resetValues) {
|
|
41
|
+
child.setStaticValue(key, resetValues[key]);
|
|
42
|
+
}
|
|
43
|
+
// Schedule a render for the next frame. This ensures we won't visually
|
|
44
|
+
// see the element with the reset rotate value applied.
|
|
45
|
+
child.scheduleRender();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { resetRotate };
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.1.17,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
import type { VisualElement } from "../../../render/types";
|
|
6
|
+
export type LeadAndFollow = [
|
|
7
|
+
VisualElement | undefined,
|
|
8
|
+
VisualElement | undefined
|
|
9
|
+
];
|
|
10
|
+
export interface LayoutStack {
|
|
11
|
+
add(element: VisualElement): void;
|
|
12
|
+
remove(element: VisualElement): void;
|
|
13
|
+
getLead(): VisualElement | undefined;
|
|
14
|
+
updateSnapshot(): void;
|
|
15
|
+
clearSnapshot(): void;
|
|
16
|
+
animate(element: VisualElement, crossfade: boolean): void;
|
|
17
|
+
updateLeadAndFollow(): void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
based on framer-motion@4.0.3,
|
|
23
|
+
Copyright (c) 2018 Framer B.V.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { __assign } from 'tslib';
|
|
27
|
+
import { elementDragControls } from '../../../gestures/drag/VisualElementDragControls.js';
|
|
28
|
+
import { Presence } from '../types.js';
|
|
29
|
+
import { createCrossfader } from './crossfader.js';
|
|
30
|
+
|
|
31
|
+
function layoutStack(): LayoutStack {
|
|
32
|
+
var stack = new Set();
|
|
33
|
+
var state = { leadIsExiting: false };
|
|
34
|
+
var prevState = __assign({}, state);
|
|
35
|
+
var prevValues;
|
|
36
|
+
var prevViewportBox;
|
|
37
|
+
var prevDragCursor;
|
|
38
|
+
var crossfader = createCrossfader();
|
|
39
|
+
var needsCrossfadeAnimation = false;
|
|
40
|
+
function getFollowViewportBox() {
|
|
41
|
+
return state.follow ? state.follow.prevViewportBox : prevViewportBox;
|
|
42
|
+
}
|
|
43
|
+
function getFollowLayout() {
|
|
44
|
+
var _a;
|
|
45
|
+
return (_a = state.follow) === null || _a === void 0 ? void 0 : _a.getLayoutState().layout;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
add: function (element) {
|
|
49
|
+
element.setCrossfader(crossfader);
|
|
50
|
+
stack.add(element);
|
|
51
|
+
/**
|
|
52
|
+
* Hydrate new element with previous drag position if we have one
|
|
53
|
+
*/
|
|
54
|
+
if (prevDragCursor)
|
|
55
|
+
element.prevDragCursor = prevDragCursor;
|
|
56
|
+
if (!state.lead)
|
|
57
|
+
state.lead = element;
|
|
58
|
+
},
|
|
59
|
+
remove: function (element) {
|
|
60
|
+
stack.delete(element);
|
|
61
|
+
},
|
|
62
|
+
getLead: function () { return state.lead; },
|
|
63
|
+
updateSnapshot: function () {
|
|
64
|
+
if (!state.lead)
|
|
65
|
+
return;
|
|
66
|
+
prevValues = crossfader.isActive()
|
|
67
|
+
? crossfader.getLatestValues()
|
|
68
|
+
: state.lead.getLatestValues();
|
|
69
|
+
prevViewportBox = state.lead.prevViewportBox;
|
|
70
|
+
var dragControls = elementDragControls.get(state.lead);
|
|
71
|
+
if (dragControls && dragControls.isDragging) {
|
|
72
|
+
prevDragCursor = dragControls.cursorProgress;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
clearSnapshot: function () {
|
|
76
|
+
prevDragCursor = prevViewportBox = undefined;
|
|
77
|
+
},
|
|
78
|
+
updateLeadAndFollow: function () {
|
|
79
|
+
var _a;
|
|
80
|
+
prevState = __assign({}, state);
|
|
81
|
+
var lead;
|
|
82
|
+
var follow;
|
|
83
|
+
var order = Array.from(stack);
|
|
84
|
+
for (var i = order.length; i--; i >= 0) {
|
|
85
|
+
var element = order[i];
|
|
86
|
+
if (lead)
|
|
87
|
+
follow !== null && follow !== void 0 ? follow : (follow = element);
|
|
88
|
+
lead !== null && lead !== void 0 ? lead : (lead = element);
|
|
89
|
+
if (lead && follow)
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
state.lead = lead;
|
|
93
|
+
state.follow = follow;
|
|
94
|
+
state.leadIsExiting = ((_a = state.lead) === null || _a === void 0 ? void 0 : _a.presence) === Presence.Exiting;
|
|
95
|
+
crossfader.setOptions({
|
|
96
|
+
lead: lead,
|
|
97
|
+
follow: follow,
|
|
98
|
+
prevValues: prevValues,
|
|
99
|
+
crossfadeOpacity: (follow === null || follow === void 0 ? void 0 : follow.isPresenceRoot) || (lead === null || lead === void 0 ? void 0 : lead.isPresenceRoot),
|
|
100
|
+
});
|
|
101
|
+
if (
|
|
102
|
+
// Don't crossfade if we've just animated back from lead and switched the
|
|
103
|
+
// old follow to the new lead.
|
|
104
|
+
state.lead !== prevState.follow &&
|
|
105
|
+
(prevState.lead !== state.lead ||
|
|
106
|
+
prevState.leadIsExiting !== state.leadIsExiting)) {
|
|
107
|
+
needsCrossfadeAnimation = true;
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
animate: function (child, shouldCrossfade) {
|
|
111
|
+
var _a;
|
|
112
|
+
if (shouldCrossfade === void 0) { shouldCrossfade = false; }
|
|
113
|
+
if (child === state.lead) {
|
|
114
|
+
if (shouldCrossfade) {
|
|
115
|
+
/**
|
|
116
|
+
* Point a lead to itself in case it was previously pointing
|
|
117
|
+
* to a different visual element
|
|
118
|
+
*/
|
|
119
|
+
child.pointTo(state.lead);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
child.setVisibility(true);
|
|
123
|
+
}
|
|
124
|
+
var config = {};
|
|
125
|
+
var prevParent = (_a = state.follow) === null || _a === void 0 ? void 0 : _a.getProjectionParent();
|
|
126
|
+
if (prevParent) {
|
|
127
|
+
/**
|
|
128
|
+
* We'll use this to determine if the element or its layoutId has been reparented.
|
|
129
|
+
*/
|
|
130
|
+
config.prevParent = prevParent;
|
|
131
|
+
}
|
|
132
|
+
if (child.presence === Presence.Entering) {
|
|
133
|
+
config.originBox = getFollowViewportBox();
|
|
134
|
+
}
|
|
135
|
+
else if (child.presence === Presence.Exiting) {
|
|
136
|
+
config.targetBox = getFollowLayout();
|
|
137
|
+
}
|
|
138
|
+
if (needsCrossfadeAnimation) {
|
|
139
|
+
needsCrossfadeAnimation = false;
|
|
140
|
+
var transition = child.getDefaultTransition();
|
|
141
|
+
child.presence === Presence.Entering
|
|
142
|
+
? crossfader.toLead(transition)
|
|
143
|
+
: crossfader.fromLead(transition);
|
|
144
|
+
}
|
|
145
|
+
child.notifyLayoutReady(config);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
if (shouldCrossfade) {
|
|
149
|
+
state.lead && child.pointTo(state.lead);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
child.setVisibility(false);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export { layoutStack };
|
|
160
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<!-- based on framer-motion@4.0.3,
|
|
2
|
+
Copyright (c) 2018 Framer B.V. -->
|
|
3
|
+
|
|
4
|
+
<script lang="ts">
|
|
5
|
+
import { onMount, setContext } from "svelte";
|
|
6
|
+
import { writable } from "svelte/store";
|
|
7
|
+
import { setDomContext } from "../../context/DOMcontext";
|
|
8
|
+
import type { LazyProps } from "./index.js";
|
|
9
|
+
|
|
10
|
+
import { LazyContext } from "../../context/LazyContext";
|
|
11
|
+
import { loadFeatures } from "../../motion/features/definitions";
|
|
12
|
+
|
|
13
|
+
type $$Props = LazyProps;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Used in conjunction with the `m` component to reduce bundle size.
|
|
17
|
+
*
|
|
18
|
+
* `m` is a version of the `motion` component that only loads functionality
|
|
19
|
+
* critical for the initial render.
|
|
20
|
+
*
|
|
21
|
+
* `LazyMotion` can then be used to either synchronously or asynchronously
|
|
22
|
+
* load animation and gesture support.
|
|
23
|
+
*
|
|
24
|
+
* ```jsx
|
|
25
|
+
* // Synchronous loading
|
|
26
|
+
* import { LazyMotion, m, domAnimations } from "framer-motion"
|
|
27
|
+
*
|
|
28
|
+
* function App() {
|
|
29
|
+
* return (
|
|
30
|
+
* <LazyMotion features={domAnimations}>
|
|
31
|
+
* <m.div animate={{ scale: 2 }} />
|
|
32
|
+
* </LazyMotion>
|
|
33
|
+
* )
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* // Asynchronous loading
|
|
37
|
+
* import { LazyMotion, m } from "framer-motion"
|
|
38
|
+
*
|
|
39
|
+
* function App() {
|
|
40
|
+
* return (
|
|
41
|
+
* <LazyMotion features={() => import('./path/to/domAnimations')}>
|
|
42
|
+
* <m.div animate={{ scale: 2 }} />
|
|
43
|
+
* </LazyMotion>
|
|
44
|
+
* )
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
export let features: $$Props["features"],
|
|
51
|
+
strict: $$Props["strict"] = false,
|
|
52
|
+
isCustom = false;
|
|
53
|
+
|
|
54
|
+
let _ = !isLazyBundle(features);
|
|
55
|
+
let loadedRenderer = undefined;
|
|
56
|
+
/**
|
|
57
|
+
* If this is a synchronous load, load features immediately
|
|
58
|
+
*/
|
|
59
|
+
$: if (!isLazyBundle(features, _)) {
|
|
60
|
+
const { renderer, ...loadedFeatures } = features;
|
|
61
|
+
loadedRenderer.current = renderer;
|
|
62
|
+
loadFeatures(loadedFeatures);
|
|
63
|
+
}
|
|
64
|
+
function isLazyBundle(features) {
|
|
65
|
+
return typeof features === "function";
|
|
66
|
+
}
|
|
67
|
+
onMount(() => {
|
|
68
|
+
if (isLazyBundle(features)) {
|
|
69
|
+
features().then(({ renderer, ...loadedFeatures }) => {
|
|
70
|
+
loadFeatures(loadedFeatures);
|
|
71
|
+
loadedRenderer.current = renderer;
|
|
72
|
+
setIsLoaded(true);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
let context = writable({ renderer: loadedRenderer.current, strict });
|
|
77
|
+
setContext(LazyContext, context);
|
|
78
|
+
setDomContext("Lazy", isCustom, context);
|
|
79
|
+
$: context.set({ renderer: loadedRenderer.current, strict });
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<slot />
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
based on framer-motion@4.1.17,
|
|
3
|
+
Copyright (c) 2018 Framer B.V.
|
|
4
|
+
*/
|
|
5
|
+
export type { LazyProps } from "./types";
|
|
6
|
+
/**
|
|
7
|
+
* Used in conjunction with the `m` component to reduce bundle size.
|
|
8
|
+
*
|
|
9
|
+
* `m` is a version of the `motion` component that only loads functionality
|
|
10
|
+
* critical for the initial render.
|
|
11
|
+
*
|
|
12
|
+
* `LazyMotion` can then be used to either synchronously or asynchronously
|
|
13
|
+
* load animation and gesture support.
|
|
14
|
+
*
|
|
15
|
+
* ```jsx
|
|
16
|
+
* // Synchronous loading
|
|
17
|
+
* import { LazyMotion, m, domAnimations } from "framer-motion"
|
|
18
|
+
*
|
|
19
|
+
* function App() {
|
|
20
|
+
* return (
|
|
21
|
+
* <LazyMotion features={domAnimations}>
|
|
22
|
+
* <m.div animate={{ scale: 2 }} />
|
|
23
|
+
* </LazyMotion>
|
|
24
|
+
* )
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* // Asynchronous loading
|
|
28
|
+
* import { LazyMotion, m } from "framer-motion"
|
|
29
|
+
*
|
|
30
|
+
* function App() {
|
|
31
|
+
* return (
|
|
32
|
+
* <LazyMotion features={() => import('./path/to/domAnimations')}>
|
|
33
|
+
* <m.div animate={{ scale: 2 }} />
|
|
34
|
+
* </LazyMotion>
|
|
35
|
+
* )
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export {default as LazyMotion} from './LazyMotion.svelte';
|
|
42
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
/**
|
|
3
|
+
based on framer-motion@4.1.17,
|
|
4
|
+
Copyright (c) 2018 Framer B.V.
|
|
5
|
+
*/
|
|
6
|
+
import type { FeatureBundle } from "../../motion/features/types";
|
|
7
|
+
export type LazyFeatureBundle = () => Promise<FeatureBundle>;
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export interface LazyProps {
|
|
12
|
+
// children?: React.ReactNode;
|
|
13
|
+
/**
|
|
14
|
+
* Can be used to provide a feature bundle synchronously or asynchronously.
|
|
15
|
+
*
|
|
16
|
+
* ```jsx
|
|
17
|
+
* // features.js
|
|
18
|
+
* import { domAnimations } from "framer-motion"
|
|
19
|
+
* export default domAnimations
|
|
20
|
+
*
|
|
21
|
+
* // index.js
|
|
22
|
+
* import { LazyMotion, m } from "framer-motion"
|
|
23
|
+
*
|
|
24
|
+
* const loadFeatures = import("./features.js")
|
|
25
|
+
* .then(res => res.default)
|
|
26
|
+
*
|
|
27
|
+
* function Component() {
|
|
28
|
+
* return (
|
|
29
|
+
* <LazyMotion features={loadFeatures}>
|
|
30
|
+
* <m.div animate={{ scale: 1.5 }} />
|
|
31
|
+
* </LazyMotion>
|
|
32
|
+
* )
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
features: FeatureBundle | LazyFeatureBundle;
|
|
39
|
+
/**
|
|
40
|
+
* If `true`, will throw an error if a `motion` component renders within
|
|
41
|
+
* a `LazyMotion` component.
|
|
42
|
+
*
|
|
43
|
+
* ```jsx
|
|
44
|
+
* // This component will throw an error that explains using a motion component
|
|
45
|
+
* // instead of the m component will break the benefits of code-splitting.
|
|
46
|
+
* function Component() {
|
|
47
|
+
* return (
|
|
48
|
+
* <LazyMotion features={domAnimation} strict>
|
|
49
|
+
* <MotionDiv />
|
|
50
|
+
* </LazyMotion>
|
|
51
|
+
* )
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @public
|
|
56
|
+
*/
|
|
57
|
+
strict?: boolean;
|
|
58
|
+
}
|