framer-motion 10.3.4 → 10.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/dom-entry.js +1 -1
- package/dist/cjs/index.js +135 -1958
- package/dist/cjs/{wrap-196fd3c5.js → wrap-58c66ad3.js} +3790 -1847
- package/dist/dom-entry.d.ts +43 -34
- package/dist/es/animation/animate.mjs +38 -34
- package/dist/es/animation/{create-instant-animation.mjs → animators/instant.mjs} +5 -2
- package/dist/es/animation/{js → animators/js}/driver-frameloop.mjs +2 -2
- package/dist/es/animation/{js → animators/js}/index.mjs +10 -9
- package/dist/es/animation/{waapi → animators/waapi}/create-accelerated-animation.mjs +22 -3
- package/dist/es/animation/hooks/animation-controls.mjs +4 -1
- package/dist/es/animation/hooks/use-animated-state.mjs +1 -1
- package/dist/es/animation/{index.mjs → interfaces/motion-value.mjs} +12 -12
- package/dist/es/animation/interfaces/single-value.mjs +11 -0
- package/dist/es/animation/interfaces/visual-element-target.mjs +66 -0
- package/dist/es/animation/interfaces/visual-element-variant.mjs +63 -0
- package/dist/es/animation/interfaces/visual-element.mjs +24 -0
- package/dist/es/animation/optimized-appear/start.mjs +1 -1
- package/dist/es/animation/utils/create-visual-element.mjs +32 -0
- package/dist/es/animation/utils/is-dom-keyframes.mjs +5 -0
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +2 -2
- package/dist/es/index.mjs +2 -2
- package/dist/es/projection/node/create-projection-node.mjs +5 -4
- package/dist/es/render/VisualElement.mjs +3 -0
- package/dist/es/render/dom/utils/is-svg-element.mjs +5 -0
- package/dist/es/render/store.mjs +3 -0
- package/dist/es/render/utils/animation-state.mjs +1 -1
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/utils/interpolate.mjs +6 -0
- package/dist/es/value/index.mjs +1 -1
- package/dist/es/value/use-spring.mjs +1 -1
- package/dist/framer-motion.dev.js +4948 -4872
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +57 -51
- package/dist/projection.dev.js +4982 -5008
- package/dist/three-entry.d.ts +6 -10
- package/package.json +5 -5
- package/dist/es/render/utils/animation.mjs +0 -145
- /package/dist/es/animation/{waapi → animators/waapi}/easing.mjs +0 -0
- /package/dist/es/animation/{waapi → animators/waapi}/index.mjs +0 -0
- /package/dist/es/animation/{waapi → animators/waapi}/supports.mjs +0 -0
- /package/dist/es/animation/{waapi → animators/waapi}/utils/get-final-keyframe.mjs +0 -0
package/dist/cjs/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
|
-
var wrap = require('./wrap-
|
|
6
|
+
var wrap = require('./wrap-58c66ad3.js');
|
|
7
7
|
|
|
8
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
9
|
|
|
@@ -44,9 +44,7 @@ const MotionContext = React.createContext({});
|
|
|
44
44
|
*/
|
|
45
45
|
const PresenceContext = React.createContext(null);
|
|
46
46
|
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const useIsomorphicLayoutEffect = isBrowser ? React.useLayoutEffect : React.useEffect;
|
|
47
|
+
const useIsomorphicLayoutEffect = wrap.isBrowser ? React.useLayoutEffect : React.useEffect;
|
|
50
48
|
|
|
51
49
|
const LazyContext = React.createContext({ strict: false });
|
|
52
50
|
|
|
@@ -103,11 +101,6 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
|
|
|
103
101
|
return visualElement;
|
|
104
102
|
}
|
|
105
103
|
|
|
106
|
-
function isRefObject(ref) {
|
|
107
|
-
return (typeof ref === "object" &&
|
|
108
|
-
Object.prototype.hasOwnProperty.call(ref, "current"));
|
|
109
|
-
}
|
|
110
|
-
|
|
111
104
|
/**
|
|
112
105
|
* Creates a ref function that, when called, hydrates the provided
|
|
113
106
|
* external ref and VisualElement.
|
|
@@ -124,7 +117,7 @@ function useMotionRef(visualState, visualElement, externalRef) {
|
|
|
124
117
|
if (typeof externalRef === "function") {
|
|
125
118
|
externalRef(instance);
|
|
126
119
|
}
|
|
127
|
-
else if (isRefObject(externalRef)) {
|
|
120
|
+
else if (wrap.isRefObject(externalRef)) {
|
|
128
121
|
externalRef.current = instance;
|
|
129
122
|
}
|
|
130
123
|
}
|
|
@@ -137,44 +130,14 @@ function useMotionRef(visualState, visualElement, externalRef) {
|
|
|
137
130
|
[visualElement]);
|
|
138
131
|
}
|
|
139
132
|
|
|
140
|
-
/**
|
|
141
|
-
* Decides if the supplied variable is variant label
|
|
142
|
-
*/
|
|
143
|
-
function isVariantLabel(v) {
|
|
144
|
-
return typeof v === "string" || Array.isArray(v);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function isAnimationControls(v) {
|
|
148
|
-
return typeof v === "object" && typeof v.start === "function";
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const variantPriorityOrder = [
|
|
152
|
-
"animate",
|
|
153
|
-
"whileInView",
|
|
154
|
-
"whileFocus",
|
|
155
|
-
"whileHover",
|
|
156
|
-
"whileTap",
|
|
157
|
-
"whileDrag",
|
|
158
|
-
"exit",
|
|
159
|
-
];
|
|
160
|
-
const variantProps = ["initial", ...variantPriorityOrder];
|
|
161
|
-
|
|
162
|
-
function isControllingVariants(props) {
|
|
163
|
-
return (isAnimationControls(props.animate) ||
|
|
164
|
-
variantProps.some((name) => isVariantLabel(props[name])));
|
|
165
|
-
}
|
|
166
|
-
function isVariantNode(props) {
|
|
167
|
-
return Boolean(isControllingVariants(props) || props.variants);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
133
|
function getCurrentTreeVariants(props, context) {
|
|
171
|
-
if (isControllingVariants(props)) {
|
|
134
|
+
if (wrap.isControllingVariants(props)) {
|
|
172
135
|
const { initial, animate } = props;
|
|
173
136
|
return {
|
|
174
|
-
initial: initial === false || isVariantLabel(initial)
|
|
137
|
+
initial: initial === false || wrap.isVariantLabel(initial)
|
|
175
138
|
? initial
|
|
176
139
|
: undefined,
|
|
177
|
-
animate: isVariantLabel(animate) ? animate : undefined,
|
|
140
|
+
animate: wrap.isVariantLabel(animate) ? animate : undefined,
|
|
178
141
|
};
|
|
179
142
|
}
|
|
180
143
|
return props.inherit !== false ? context : {};
|
|
@@ -188,37 +151,10 @@ function variantLabelsAsDependency(prop) {
|
|
|
188
151
|
return Array.isArray(prop) ? prop.join(" ") : prop;
|
|
189
152
|
}
|
|
190
153
|
|
|
191
|
-
const featureProps = {
|
|
192
|
-
animation: [
|
|
193
|
-
"animate",
|
|
194
|
-
"variants",
|
|
195
|
-
"whileHover",
|
|
196
|
-
"whileTap",
|
|
197
|
-
"exit",
|
|
198
|
-
"whileInView",
|
|
199
|
-
"whileFocus",
|
|
200
|
-
"whileDrag",
|
|
201
|
-
],
|
|
202
|
-
exit: ["exit"],
|
|
203
|
-
drag: ["drag", "dragControls"],
|
|
204
|
-
focus: ["whileFocus"],
|
|
205
|
-
hover: ["whileHover", "onHoverStart", "onHoverEnd"],
|
|
206
|
-
tap: ["whileTap", "onTap", "onTapStart", "onTapCancel"],
|
|
207
|
-
pan: ["onPan", "onPanStart", "onPanSessionStart", "onPanEnd"],
|
|
208
|
-
inView: ["whileInView", "onViewportEnter", "onViewportLeave"],
|
|
209
|
-
layout: ["layout", "layoutId"],
|
|
210
|
-
};
|
|
211
|
-
const featureDefinitions = {};
|
|
212
|
-
for (const key in featureProps) {
|
|
213
|
-
featureDefinitions[key] = {
|
|
214
|
-
isEnabled: (props) => featureProps[key].some((name) => !!props[name]),
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
154
|
function loadFeatures(features) {
|
|
219
155
|
for (const key in features) {
|
|
220
|
-
featureDefinitions[key] = {
|
|
221
|
-
...featureDefinitions[key],
|
|
156
|
+
wrap.featureDefinitions[key] = {
|
|
157
|
+
...wrap.featureDefinitions[key],
|
|
222
158
|
...features[key],
|
|
223
159
|
};
|
|
224
160
|
}
|
|
@@ -312,7 +248,7 @@ function createMotionComponent({ preloadedFeatures, createVisualElement, useRend
|
|
|
312
248
|
*/
|
|
313
249
|
const projectionId = isStatic ? undefined : useProjectionId();
|
|
314
250
|
const visualState = useVisualState(props, isStatic);
|
|
315
|
-
if (!isStatic && isBrowser) {
|
|
251
|
+
if (!isStatic && wrap.isBrowser) {
|
|
316
252
|
/**
|
|
317
253
|
* Create a VisualElement for this component. A VisualElement provides a common
|
|
318
254
|
* interface to renderer-specific APIs (ie DOM/Three.js etc) as well as
|
|
@@ -454,140 +390,6 @@ function isSVGComponent(Component) {
|
|
|
454
390
|
return false;
|
|
455
391
|
}
|
|
456
392
|
|
|
457
|
-
const scaleCorrectors = {};
|
|
458
|
-
function addScaleCorrector(correctors) {
|
|
459
|
-
Object.assign(scaleCorrectors, correctors);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
function isForcedMotionValue(key, { layout, layoutId }) {
|
|
463
|
-
return (wrap.transformProps.has(key) ||
|
|
464
|
-
key.startsWith("origin") ||
|
|
465
|
-
((layout || layoutId !== undefined) &&
|
|
466
|
-
(!!scaleCorrectors[key] || key === "opacity")));
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
const translateAlias = {
|
|
470
|
-
x: "translateX",
|
|
471
|
-
y: "translateY",
|
|
472
|
-
z: "translateZ",
|
|
473
|
-
transformPerspective: "perspective",
|
|
474
|
-
};
|
|
475
|
-
const numTransforms = wrap.transformPropOrder.length;
|
|
476
|
-
/**
|
|
477
|
-
* Build a CSS transform style from individual x/y/scale etc properties.
|
|
478
|
-
*
|
|
479
|
-
* This outputs with a default order of transforms/scales/rotations, this can be customised by
|
|
480
|
-
* providing a transformTemplate function.
|
|
481
|
-
*/
|
|
482
|
-
function buildTransform(transform, { enableHardwareAcceleration = true, allowTransformNone = true, }, transformIsDefault, transformTemplate) {
|
|
483
|
-
// The transform string we're going to build into.
|
|
484
|
-
let transformString = "";
|
|
485
|
-
/**
|
|
486
|
-
* Loop over all possible transforms in order, adding the ones that
|
|
487
|
-
* are present to the transform string.
|
|
488
|
-
*/
|
|
489
|
-
for (let i = 0; i < numTransforms; i++) {
|
|
490
|
-
const key = wrap.transformPropOrder[i];
|
|
491
|
-
if (transform[key] !== undefined) {
|
|
492
|
-
const transformName = translateAlias[key] || key;
|
|
493
|
-
transformString += `${transformName}(${transform[key]}) `;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
if (enableHardwareAcceleration && !transform.z) {
|
|
497
|
-
transformString += "translateZ(0)";
|
|
498
|
-
}
|
|
499
|
-
transformString = transformString.trim();
|
|
500
|
-
// If we have a custom `transform` template, pass our transform values and
|
|
501
|
-
// generated transformString to that before returning
|
|
502
|
-
if (transformTemplate) {
|
|
503
|
-
transformString = transformTemplate(transform, transformIsDefault ? "" : transformString);
|
|
504
|
-
}
|
|
505
|
-
else if (allowTransformNone && transformIsDefault) {
|
|
506
|
-
transformString = "none";
|
|
507
|
-
}
|
|
508
|
-
return transformString;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
|
|
512
|
-
const isCSSVariableName = checkStringStartsWith("--");
|
|
513
|
-
const isCSSVariableToken = checkStringStartsWith("var(--");
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* Provided a value and a ValueType, returns the value as that value type.
|
|
517
|
-
*/
|
|
518
|
-
const getValueAsType = (value, type) => {
|
|
519
|
-
return type && typeof value === "number"
|
|
520
|
-
? type.transform(value)
|
|
521
|
-
: value;
|
|
522
|
-
};
|
|
523
|
-
|
|
524
|
-
function buildHTMLStyles(state, latestValues, options, transformTemplate) {
|
|
525
|
-
const { style, vars, transform, transformOrigin } = state;
|
|
526
|
-
// Track whether we encounter any transform or transformOrigin values.
|
|
527
|
-
let hasTransform = false;
|
|
528
|
-
let hasTransformOrigin = false;
|
|
529
|
-
// Does the calculated transform essentially equal "none"?
|
|
530
|
-
let transformIsNone = true;
|
|
531
|
-
/**
|
|
532
|
-
* Loop over all our latest animated values and decide whether to handle them
|
|
533
|
-
* as a style or CSS variable.
|
|
534
|
-
*
|
|
535
|
-
* Transforms and transform origins are kept seperately for further processing.
|
|
536
|
-
*/
|
|
537
|
-
for (const key in latestValues) {
|
|
538
|
-
const value = latestValues[key];
|
|
539
|
-
/**
|
|
540
|
-
* If this is a CSS variable we don't do any further processing.
|
|
541
|
-
*/
|
|
542
|
-
if (isCSSVariableName(key)) {
|
|
543
|
-
vars[key] = value;
|
|
544
|
-
continue;
|
|
545
|
-
}
|
|
546
|
-
// Convert the value to its default value type, ie 0 -> "0px"
|
|
547
|
-
const valueType = wrap.numberValueTypes[key];
|
|
548
|
-
const valueAsType = getValueAsType(value, valueType);
|
|
549
|
-
if (wrap.transformProps.has(key)) {
|
|
550
|
-
// If this is a transform, flag to enable further transform processing
|
|
551
|
-
hasTransform = true;
|
|
552
|
-
transform[key] = valueAsType;
|
|
553
|
-
// If we already know we have a non-default transform, early return
|
|
554
|
-
if (!transformIsNone)
|
|
555
|
-
continue;
|
|
556
|
-
// Otherwise check to see if this is a default transform
|
|
557
|
-
if (value !== (valueType.default || 0))
|
|
558
|
-
transformIsNone = false;
|
|
559
|
-
}
|
|
560
|
-
else if (key.startsWith("origin")) {
|
|
561
|
-
// If this is a transform origin, flag and enable further transform-origin processing
|
|
562
|
-
hasTransformOrigin = true;
|
|
563
|
-
transformOrigin[key] = valueAsType;
|
|
564
|
-
}
|
|
565
|
-
else {
|
|
566
|
-
style[key] = valueAsType;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
if (!latestValues.transform) {
|
|
570
|
-
if (hasTransform || transformTemplate) {
|
|
571
|
-
style.transform = buildTransform(state.transform, options, transformIsNone, transformTemplate);
|
|
572
|
-
}
|
|
573
|
-
else if (style.transform) {
|
|
574
|
-
/**
|
|
575
|
-
* If we have previously created a transform but currently don't have any,
|
|
576
|
-
* reset transform style to none.
|
|
577
|
-
*/
|
|
578
|
-
style.transform = "none";
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
/**
|
|
582
|
-
* Build a transformOrigin style. Uses the same defaults as the browser for
|
|
583
|
-
* undefined origins.
|
|
584
|
-
*/
|
|
585
|
-
if (hasTransformOrigin) {
|
|
586
|
-
const { originX = "50%", originY = "50%", originZ = 0, } = transformOrigin;
|
|
587
|
-
style.transformOrigin = `${originX} ${originY} ${originZ}`;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
|
|
591
393
|
const createHtmlRenderState = () => ({
|
|
592
394
|
style: {},
|
|
593
395
|
transform: {},
|
|
@@ -597,7 +399,7 @@ const createHtmlRenderState = () => ({
|
|
|
597
399
|
|
|
598
400
|
function copyRawValuesOnly(target, source, props) {
|
|
599
401
|
for (const key in source) {
|
|
600
|
-
if (!wrap.isMotionValue(source[key]) && !isForcedMotionValue(key, props)) {
|
|
402
|
+
if (!wrap.isMotionValue(source[key]) && !wrap.isForcedMotionValue(key, props)) {
|
|
601
403
|
target[key] = source[key];
|
|
602
404
|
}
|
|
603
405
|
}
|
|
@@ -605,7 +407,7 @@ function copyRawValuesOnly(target, source, props) {
|
|
|
605
407
|
function useInitialMotionValues({ transformTemplate }, visualState, isStatic) {
|
|
606
408
|
return React.useMemo(() => {
|
|
607
409
|
const state = createHtmlRenderState();
|
|
608
|
-
buildHTMLStyles(state, visualState, { enableHardwareAcceleration: !isStatic }, transformTemplate);
|
|
410
|
+
wrap.buildHTMLStyles(state, visualState, { enableHardwareAcceleration: !isStatic }, transformTemplate);
|
|
609
411
|
return Object.assign({}, state.vars, state.style);
|
|
610
412
|
}, [visualState]);
|
|
611
413
|
}
|
|
@@ -757,106 +559,15 @@ function filterProps(props, isDom, forwardMotionProps) {
|
|
|
757
559
|
return filteredProps;
|
|
758
560
|
}
|
|
759
561
|
|
|
760
|
-
function calcOrigin$1(origin, offset, size) {
|
|
761
|
-
return typeof origin === "string"
|
|
762
|
-
? origin
|
|
763
|
-
: wrap.px.transform(offset + size * origin);
|
|
764
|
-
}
|
|
765
|
-
/**
|
|
766
|
-
* The SVG transform origin defaults are different to CSS and is less intuitive,
|
|
767
|
-
* so we use the measured dimensions of the SVG to reconcile these.
|
|
768
|
-
*/
|
|
769
|
-
function calcSVGTransformOrigin(dimensions, originX, originY) {
|
|
770
|
-
const pxOriginX = calcOrigin$1(originX, dimensions.x, dimensions.width);
|
|
771
|
-
const pxOriginY = calcOrigin$1(originY, dimensions.y, dimensions.height);
|
|
772
|
-
return `${pxOriginX} ${pxOriginY}`;
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
const dashKeys = {
|
|
776
|
-
offset: "stroke-dashoffset",
|
|
777
|
-
array: "stroke-dasharray",
|
|
778
|
-
};
|
|
779
|
-
const camelKeys = {
|
|
780
|
-
offset: "strokeDashoffset",
|
|
781
|
-
array: "strokeDasharray",
|
|
782
|
-
};
|
|
783
|
-
/**
|
|
784
|
-
* Build SVG path properties. Uses the path's measured length to convert
|
|
785
|
-
* our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset
|
|
786
|
-
* and stroke-dasharray attributes.
|
|
787
|
-
*
|
|
788
|
-
* This function is mutative to reduce per-frame GC.
|
|
789
|
-
*/
|
|
790
|
-
function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
|
|
791
|
-
// Normalise path length by setting SVG attribute pathLength to 1
|
|
792
|
-
attrs.pathLength = 1;
|
|
793
|
-
// We use dash case when setting attributes directly to the DOM node and camel case
|
|
794
|
-
// when defining props on a React component.
|
|
795
|
-
const keys = useDashCase ? dashKeys : camelKeys;
|
|
796
|
-
// Build the dash offset
|
|
797
|
-
attrs[keys.offset] = wrap.px.transform(-offset);
|
|
798
|
-
// Build the dash array
|
|
799
|
-
const pathLength = wrap.px.transform(length);
|
|
800
|
-
const pathSpacing = wrap.px.transform(spacing);
|
|
801
|
-
attrs[keys.array] = `${pathLength} ${pathSpacing}`;
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
/**
|
|
805
|
-
* Build SVG visual attrbutes, like cx and style.transform
|
|
806
|
-
*/
|
|
807
|
-
function buildSVGAttrs(state, { attrX, attrY, originX, originY, pathLength, pathSpacing = 1, pathOffset = 0,
|
|
808
|
-
// This is object creation, which we try to avoid per-frame.
|
|
809
|
-
...latest }, options, isSVGTag, transformTemplate) {
|
|
810
|
-
buildHTMLStyles(state, latest, options, transformTemplate);
|
|
811
|
-
/**
|
|
812
|
-
* For svg tags we just want to make sure viewBox is animatable and treat all the styles
|
|
813
|
-
* as normal HTML tags.
|
|
814
|
-
*/
|
|
815
|
-
if (isSVGTag) {
|
|
816
|
-
if (state.style.viewBox) {
|
|
817
|
-
state.attrs.viewBox = state.style.viewBox;
|
|
818
|
-
}
|
|
819
|
-
return;
|
|
820
|
-
}
|
|
821
|
-
state.attrs = state.style;
|
|
822
|
-
state.style = {};
|
|
823
|
-
const { attrs, style, dimensions } = state;
|
|
824
|
-
/**
|
|
825
|
-
* However, we apply transforms as CSS transforms. So if we detect a transform we take it from attrs
|
|
826
|
-
* and copy it into style.
|
|
827
|
-
*/
|
|
828
|
-
if (attrs.transform) {
|
|
829
|
-
if (dimensions)
|
|
830
|
-
style.transform = attrs.transform;
|
|
831
|
-
delete attrs.transform;
|
|
832
|
-
}
|
|
833
|
-
// Parse transformOrigin
|
|
834
|
-
if (dimensions &&
|
|
835
|
-
(originX !== undefined || originY !== undefined || style.transform)) {
|
|
836
|
-
style.transformOrigin = calcSVGTransformOrigin(dimensions, originX !== undefined ? originX : 0.5, originY !== undefined ? originY : 0.5);
|
|
837
|
-
}
|
|
838
|
-
// Treat x/y not as shortcuts but as actual attributes
|
|
839
|
-
if (attrX !== undefined)
|
|
840
|
-
attrs.x = attrX;
|
|
841
|
-
if (attrY !== undefined)
|
|
842
|
-
attrs.y = attrY;
|
|
843
|
-
// Build SVG path if one has been defined
|
|
844
|
-
if (pathLength !== undefined) {
|
|
845
|
-
buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
|
|
849
562
|
const createSvgRenderState = () => ({
|
|
850
563
|
...createHtmlRenderState(),
|
|
851
564
|
attrs: {},
|
|
852
565
|
});
|
|
853
566
|
|
|
854
|
-
const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
|
|
855
|
-
|
|
856
567
|
function useSVGProps(props, visualState, _isStatic, Component) {
|
|
857
568
|
const visualProps = React.useMemo(() => {
|
|
858
569
|
const state = createSvgRenderState();
|
|
859
|
-
buildSVGAttrs(state, visualState, { enableHardwareAcceleration: false }, isSVGTag(Component), props.transformTemplate);
|
|
570
|
+
wrap.buildSVGAttrs(state, visualState, { enableHardwareAcceleration: false }, wrap.isSVGTag(Component), props.transformTemplate);
|
|
860
571
|
return {
|
|
861
572
|
...state.attrs,
|
|
862
573
|
style: { ...state.style },
|
|
@@ -900,116 +611,6 @@ function createUseRender(forwardMotionProps = false) {
|
|
|
900
611
|
return useRender;
|
|
901
612
|
}
|
|
902
613
|
|
|
903
|
-
/**
|
|
904
|
-
* Convert camelCase to dash-case properties.
|
|
905
|
-
*/
|
|
906
|
-
const camelToDash = (str) => str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
907
|
-
|
|
908
|
-
function renderHTML(element, { style, vars }, styleProp, projection) {
|
|
909
|
-
Object.assign(element.style, style, projection && projection.getProjectionStyles(styleProp));
|
|
910
|
-
// Loop over any CSS variables and assign those.
|
|
911
|
-
for (const key in vars) {
|
|
912
|
-
element.style.setProperty(key, vars[key]);
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
/**
|
|
917
|
-
* A set of attribute names that are always read/written as camel case.
|
|
918
|
-
*/
|
|
919
|
-
const camelCaseAttributes = new Set([
|
|
920
|
-
"baseFrequency",
|
|
921
|
-
"diffuseConstant",
|
|
922
|
-
"kernelMatrix",
|
|
923
|
-
"kernelUnitLength",
|
|
924
|
-
"keySplines",
|
|
925
|
-
"keyTimes",
|
|
926
|
-
"limitingConeAngle",
|
|
927
|
-
"markerHeight",
|
|
928
|
-
"markerWidth",
|
|
929
|
-
"numOctaves",
|
|
930
|
-
"targetX",
|
|
931
|
-
"targetY",
|
|
932
|
-
"surfaceScale",
|
|
933
|
-
"specularConstant",
|
|
934
|
-
"specularExponent",
|
|
935
|
-
"stdDeviation",
|
|
936
|
-
"tableValues",
|
|
937
|
-
"viewBox",
|
|
938
|
-
"gradientTransform",
|
|
939
|
-
"pathLength",
|
|
940
|
-
"startOffset",
|
|
941
|
-
"textLength",
|
|
942
|
-
"lengthAdjust",
|
|
943
|
-
]);
|
|
944
|
-
|
|
945
|
-
function renderSVG(element, renderState, _styleProp, projection) {
|
|
946
|
-
renderHTML(element, renderState, undefined, projection);
|
|
947
|
-
for (const key in renderState.attrs) {
|
|
948
|
-
element.setAttribute(!camelCaseAttributes.has(key) ? camelToDash(key) : key, renderState.attrs[key]);
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
function scrapeMotionValuesFromProps$1(props, prevProps) {
|
|
953
|
-
const { style } = props;
|
|
954
|
-
const newValues = {};
|
|
955
|
-
for (const key in style) {
|
|
956
|
-
if (wrap.isMotionValue(style[key]) ||
|
|
957
|
-
(prevProps.style && wrap.isMotionValue(prevProps.style[key])) ||
|
|
958
|
-
isForcedMotionValue(key, props)) {
|
|
959
|
-
newValues[key] = style[key];
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
return newValues;
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
function scrapeMotionValuesFromProps(props, prevProps) {
|
|
966
|
-
const newValues = scrapeMotionValuesFromProps$1(props, prevProps);
|
|
967
|
-
for (const key in props) {
|
|
968
|
-
if (wrap.isMotionValue(props[key]) || wrap.isMotionValue(prevProps[key])) {
|
|
969
|
-
const targetKey = key === "x" || key === "y" ? "attr" + key.toUpperCase() : key;
|
|
970
|
-
newValues[targetKey] = props[key];
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
return newValues;
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
function resolveVariantFromProps(props, definition, custom, currentValues = {}, currentVelocity = {}) {
|
|
977
|
-
/**
|
|
978
|
-
* If the variant definition is a function, resolve.
|
|
979
|
-
*/
|
|
980
|
-
if (typeof definition === "function") {
|
|
981
|
-
definition = definition(custom !== undefined ? custom : props.custom, currentValues, currentVelocity);
|
|
982
|
-
}
|
|
983
|
-
/**
|
|
984
|
-
* If the variant definition is a variant label, or
|
|
985
|
-
* the function returned a variant label, resolve.
|
|
986
|
-
*/
|
|
987
|
-
if (typeof definition === "string") {
|
|
988
|
-
definition = props.variants && props.variants[definition];
|
|
989
|
-
}
|
|
990
|
-
/**
|
|
991
|
-
* At this point we've resolved both functions and variant labels,
|
|
992
|
-
* but the resolved variant label might itself have been a function.
|
|
993
|
-
* If so, resolve. This can only have returned a valid target object.
|
|
994
|
-
*/
|
|
995
|
-
if (typeof definition === "function") {
|
|
996
|
-
definition = definition(custom !== undefined ? custom : props.custom, currentValues, currentVelocity);
|
|
997
|
-
}
|
|
998
|
-
return definition;
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
const isKeyframesTarget = (v) => {
|
|
1002
|
-
return Array.isArray(v);
|
|
1003
|
-
};
|
|
1004
|
-
|
|
1005
|
-
const isCustomValue = (v) => {
|
|
1006
|
-
return Boolean(v && typeof v === "object" && v.mix && v.toValue);
|
|
1007
|
-
};
|
|
1008
|
-
const resolveFinalValueInKeyframes = (v) => {
|
|
1009
|
-
// TODO maybe throw if v.length - 1 is placeholder token?
|
|
1010
|
-
return isKeyframesTarget(v) ? v[v.length - 1] || 0 : v;
|
|
1011
|
-
};
|
|
1012
|
-
|
|
1013
614
|
/**
|
|
1014
615
|
* If the provided value is a MotionValue, this returns the actual value, otherwise just the value itself
|
|
1015
616
|
*
|
|
@@ -1017,7 +618,7 @@ const resolveFinalValueInKeyframes = (v) => {
|
|
|
1017
618
|
*/
|
|
1018
619
|
function resolveMotionValue(value) {
|
|
1019
620
|
const unwrappedValue = wrap.isMotionValue(value) ? value.get() : value;
|
|
1020
|
-
return isCustomValue(unwrappedValue)
|
|
621
|
+
return wrap.isCustomValue(unwrappedValue)
|
|
1021
622
|
? unwrappedValue.toValue()
|
|
1022
623
|
: unwrappedValue;
|
|
1023
624
|
}
|
|
@@ -1045,11 +646,11 @@ function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
|
|
|
1045
646
|
values[key] = resolveMotionValue(motionValues[key]);
|
|
1046
647
|
}
|
|
1047
648
|
let { initial, animate } = props;
|
|
1048
|
-
const isControllingVariants
|
|
1049
|
-
const isVariantNode
|
|
649
|
+
const isControllingVariants = wrap.isControllingVariants(props);
|
|
650
|
+
const isVariantNode = wrap.isVariantNode(props);
|
|
1050
651
|
if (context &&
|
|
1051
|
-
isVariantNode
|
|
1052
|
-
!isControllingVariants
|
|
652
|
+
isVariantNode &&
|
|
653
|
+
!isControllingVariants &&
|
|
1053
654
|
props.inherit !== false) {
|
|
1054
655
|
if (initial === undefined)
|
|
1055
656
|
initial = context.initial;
|
|
@@ -1063,10 +664,10 @@ function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
|
|
|
1063
664
|
const variantToSet = isInitialAnimationBlocked ? animate : initial;
|
|
1064
665
|
if (variantToSet &&
|
|
1065
666
|
typeof variantToSet !== "boolean" &&
|
|
1066
|
-
!isAnimationControls(variantToSet)) {
|
|
667
|
+
!wrap.isAnimationControls(variantToSet)) {
|
|
1067
668
|
const list = Array.isArray(variantToSet) ? variantToSet : [variantToSet];
|
|
1068
669
|
list.forEach((definition) => {
|
|
1069
|
-
const resolved = resolveVariantFromProps(props, definition);
|
|
670
|
+
const resolved = wrap.resolveVariantFromProps(props, definition);
|
|
1070
671
|
if (!resolved)
|
|
1071
672
|
return;
|
|
1072
673
|
const { transitionEnd, transition, ...target } = resolved;
|
|
@@ -1095,7 +696,7 @@ function makeLatestValues(props, context, presenceContext, scrapeMotionValues) {
|
|
|
1095
696
|
|
|
1096
697
|
const svgMotionConfig = {
|
|
1097
698
|
useVisualState: makeUseVisualState({
|
|
1098
|
-
scrapeMotionValuesFromProps: scrapeMotionValuesFromProps,
|
|
699
|
+
scrapeMotionValuesFromProps: wrap.scrapeMotionValuesFromProps,
|
|
1099
700
|
createRenderState: createSvgRenderState,
|
|
1100
701
|
onMount: (props, instance, { renderState, latestValues }) => {
|
|
1101
702
|
try {
|
|
@@ -1114,15 +715,15 @@ const svgMotionConfig = {
|
|
|
1114
715
|
height: 0,
|
|
1115
716
|
};
|
|
1116
717
|
}
|
|
1117
|
-
buildSVGAttrs(renderState, latestValues, { enableHardwareAcceleration: false }, isSVGTag(instance.tagName), props.transformTemplate);
|
|
1118
|
-
renderSVG(instance, renderState);
|
|
718
|
+
wrap.buildSVGAttrs(renderState, latestValues, { enableHardwareAcceleration: false }, wrap.isSVGTag(instance.tagName), props.transformTemplate);
|
|
719
|
+
wrap.renderSVG(instance, renderState);
|
|
1119
720
|
},
|
|
1120
721
|
}),
|
|
1121
722
|
};
|
|
1122
723
|
|
|
1123
724
|
const htmlMotionConfig = {
|
|
1124
725
|
useVisualState: makeUseVisualState({
|
|
1125
|
-
scrapeMotionValuesFromProps: scrapeMotionValuesFromProps$1,
|
|
726
|
+
scrapeMotionValuesFromProps: wrap.scrapeMotionValuesFromProps$1,
|
|
1126
727
|
createRenderState: createHtmlRenderState,
|
|
1127
728
|
}),
|
|
1128
729
|
};
|
|
@@ -1571,209 +1172,8 @@ function shallowCompare(next, prev) {
|
|
|
1571
1172
|
return true;
|
|
1572
1173
|
}
|
|
1573
1174
|
|
|
1574
|
-
/**
|
|
1575
|
-
* Check if value is a numerical string, ie a string that is purely a number eg "100" or "-100.1"
|
|
1576
|
-
*/
|
|
1577
|
-
const isNumericalString = (v) => /^\-?\d*\.?\d+$/.test(v);
|
|
1578
|
-
|
|
1579
|
-
/**
|
|
1580
|
-
* Check if the value is a zero value string like "0px" or "0%"
|
|
1581
|
-
*/
|
|
1582
|
-
const isZeroValueString = (v) => /^0[^.\s]+$/.test(v);
|
|
1583
|
-
|
|
1584
|
-
/**
|
|
1585
|
-
* Tests a provided value against a ValueType
|
|
1586
|
-
*/
|
|
1587
|
-
const testValueType = (v) => (type) => type.test(v);
|
|
1588
|
-
|
|
1589
|
-
/**
|
|
1590
|
-
* ValueType for "auto"
|
|
1591
|
-
*/
|
|
1592
|
-
const auto = {
|
|
1593
|
-
test: (v) => v === "auto",
|
|
1594
|
-
parse: (v) => v,
|
|
1595
|
-
};
|
|
1596
|
-
|
|
1597
|
-
/**
|
|
1598
|
-
* A list of value types commonly used for dimensions
|
|
1599
|
-
*/
|
|
1600
|
-
const dimensionValueTypes = [wrap.number, wrap.px, wrap.percent, wrap.degrees, wrap.vw, wrap.vh, auto];
|
|
1601
|
-
/**
|
|
1602
|
-
* Tests a dimensional value against the list of dimension ValueTypes
|
|
1603
|
-
*/
|
|
1604
|
-
const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
|
|
1605
|
-
|
|
1606
|
-
/**
|
|
1607
|
-
* A list of all ValueTypes
|
|
1608
|
-
*/
|
|
1609
|
-
const valueTypes = [...dimensionValueTypes, wrap.color, wrap.complex];
|
|
1610
|
-
/**
|
|
1611
|
-
* Tests a value against the list of ValueTypes
|
|
1612
|
-
*/
|
|
1613
|
-
const findValueType = (v) => valueTypes.find(testValueType(v));
|
|
1614
|
-
|
|
1615
|
-
/**
|
|
1616
|
-
* Creates an object containing the latest state of every MotionValue on a VisualElement
|
|
1617
|
-
*/
|
|
1618
|
-
function getCurrent(visualElement) {
|
|
1619
|
-
const current = {};
|
|
1620
|
-
visualElement.values.forEach((value, key) => (current[key] = value.get()));
|
|
1621
|
-
return current;
|
|
1622
|
-
}
|
|
1623
|
-
/**
|
|
1624
|
-
* Creates an object containing the latest velocity of every MotionValue on a VisualElement
|
|
1625
|
-
*/
|
|
1626
|
-
function getVelocity$1(visualElement) {
|
|
1627
|
-
const velocity = {};
|
|
1628
|
-
visualElement.values.forEach((value, key) => (velocity[key] = value.getVelocity()));
|
|
1629
|
-
return velocity;
|
|
1630
|
-
}
|
|
1631
|
-
function resolveVariant(visualElement, definition, custom) {
|
|
1632
|
-
const props = visualElement.getProps();
|
|
1633
|
-
return resolveVariantFromProps(props, definition, custom !== undefined ? custom : props.custom, getCurrent(visualElement), getVelocity$1(visualElement));
|
|
1634
|
-
}
|
|
1635
|
-
|
|
1636
|
-
/**
|
|
1637
|
-
* Set VisualElement's MotionValue, creating a new MotionValue for it if
|
|
1638
|
-
* it doesn't exist.
|
|
1639
|
-
*/
|
|
1640
|
-
function setMotionValue(visualElement, key, value) {
|
|
1641
|
-
if (visualElement.hasValue(key)) {
|
|
1642
|
-
visualElement.getValue(key).set(value);
|
|
1643
|
-
}
|
|
1644
|
-
else {
|
|
1645
|
-
visualElement.addValue(key, wrap.motionValue(value));
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
function setTarget(visualElement, definition) {
|
|
1649
|
-
const resolved = resolveVariant(visualElement, definition);
|
|
1650
|
-
let { transitionEnd = {}, transition = {}, ...target } = resolved ? visualElement.makeTargetAnimatable(resolved, false) : {};
|
|
1651
|
-
target = { ...target, ...transitionEnd };
|
|
1652
|
-
for (const key in target) {
|
|
1653
|
-
const value = resolveFinalValueInKeyframes(target[key]);
|
|
1654
|
-
setMotionValue(visualElement, key, value);
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
|
-
function setVariants(visualElement, variantLabels) {
|
|
1658
|
-
const reversedLabels = [...variantLabels].reverse();
|
|
1659
|
-
reversedLabels.forEach((key) => {
|
|
1660
|
-
const variant = visualElement.getVariant(key);
|
|
1661
|
-
variant && setTarget(visualElement, variant);
|
|
1662
|
-
if (visualElement.variantChildren) {
|
|
1663
|
-
visualElement.variantChildren.forEach((child) => {
|
|
1664
|
-
setVariants(child, variantLabels);
|
|
1665
|
-
});
|
|
1666
|
-
}
|
|
1667
|
-
});
|
|
1668
|
-
}
|
|
1669
|
-
function setValues(visualElement, definition) {
|
|
1670
|
-
if (Array.isArray(definition)) {
|
|
1671
|
-
return setVariants(visualElement, definition);
|
|
1672
|
-
}
|
|
1673
|
-
else if (typeof definition === "string") {
|
|
1674
|
-
return setVariants(visualElement, [definition]);
|
|
1675
|
-
}
|
|
1676
|
-
else {
|
|
1677
|
-
setTarget(visualElement, definition);
|
|
1678
|
-
}
|
|
1679
|
-
}
|
|
1680
|
-
function checkTargetForNewValues(visualElement, target, origin) {
|
|
1681
|
-
var _a, _b;
|
|
1682
|
-
const newValueKeys = Object.keys(target).filter((key) => !visualElement.hasValue(key));
|
|
1683
|
-
const numNewValues = newValueKeys.length;
|
|
1684
|
-
if (!numNewValues)
|
|
1685
|
-
return;
|
|
1686
|
-
for (let i = 0; i < numNewValues; i++) {
|
|
1687
|
-
const key = newValueKeys[i];
|
|
1688
|
-
const targetValue = target[key];
|
|
1689
|
-
let value = null;
|
|
1690
|
-
/**
|
|
1691
|
-
* If the target is a series of keyframes, we can use the first value
|
|
1692
|
-
* in the array. If this first value is null, we'll still need to read from the DOM.
|
|
1693
|
-
*/
|
|
1694
|
-
if (Array.isArray(targetValue)) {
|
|
1695
|
-
value = targetValue[0];
|
|
1696
|
-
}
|
|
1697
|
-
/**
|
|
1698
|
-
* If the target isn't keyframes, or the first keyframe was null, we need to
|
|
1699
|
-
* first check if an origin value was explicitly defined in the transition as "from",
|
|
1700
|
-
* if not read the value from the DOM. As an absolute fallback, take the defined target value.
|
|
1701
|
-
*/
|
|
1702
|
-
if (value === null) {
|
|
1703
|
-
value = (_b = (_a = origin[key]) !== null && _a !== void 0 ? _a : visualElement.readValue(key)) !== null && _b !== void 0 ? _b : target[key];
|
|
1704
|
-
}
|
|
1705
|
-
/**
|
|
1706
|
-
* If value is still undefined or null, ignore it. Preferably this would throw,
|
|
1707
|
-
* but this was causing issues in Framer.
|
|
1708
|
-
*/
|
|
1709
|
-
if (value === undefined || value === null)
|
|
1710
|
-
continue;
|
|
1711
|
-
if (typeof value === "string" &&
|
|
1712
|
-
(isNumericalString(value) || isZeroValueString(value))) {
|
|
1713
|
-
// If this is a number read as a string, ie "0" or "200", convert it to a number
|
|
1714
|
-
value = parseFloat(value);
|
|
1715
|
-
}
|
|
1716
|
-
else if (!findValueType(value) && wrap.complex.test(targetValue)) {
|
|
1717
|
-
value = wrap.getAnimatableNone(key, targetValue);
|
|
1718
|
-
}
|
|
1719
|
-
visualElement.addValue(key, wrap.motionValue(value, { owner: visualElement }));
|
|
1720
|
-
if (origin[key] === undefined) {
|
|
1721
|
-
origin[key] = value;
|
|
1722
|
-
}
|
|
1723
|
-
if (value !== null)
|
|
1724
|
-
visualElement.setBaseTarget(key, value);
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
function getOriginFromTransition(key, transition) {
|
|
1728
|
-
if (!transition)
|
|
1729
|
-
return;
|
|
1730
|
-
const valueTransition = transition[key] || transition["default"] || transition;
|
|
1731
|
-
return valueTransition.from;
|
|
1732
|
-
}
|
|
1733
|
-
function getOrigin(target, transition, visualElement) {
|
|
1734
|
-
const origin = {};
|
|
1735
|
-
for (const key in target) {
|
|
1736
|
-
const transitionOrigin = getOriginFromTransition(key, transition);
|
|
1737
|
-
if (transitionOrigin !== undefined) {
|
|
1738
|
-
origin[key] = transitionOrigin;
|
|
1739
|
-
}
|
|
1740
|
-
else {
|
|
1741
|
-
const value = visualElement.getValue(key);
|
|
1742
|
-
if (value) {
|
|
1743
|
-
origin[key] = value.get();
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
return origin;
|
|
1748
|
-
}
|
|
1749
|
-
|
|
1750
|
-
function isWillChangeMotionValue(value) {
|
|
1751
|
-
return Boolean(wrap.isMotionValue(value) && value.add);
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
const optimizedAppearDataId = "framerAppearId";
|
|
1755
|
-
const optimizedAppearDataAttribute = "data-" + camelToDash(optimizedAppearDataId);
|
|
1756
|
-
|
|
1757
|
-
function animateVisualElement(visualElement, definition, options = {}) {
|
|
1758
|
-
visualElement.notify("AnimationStart", definition);
|
|
1759
|
-
let animation;
|
|
1760
|
-
if (Array.isArray(definition)) {
|
|
1761
|
-
const animations = definition.map((variant) => animateVariant(visualElement, variant, options));
|
|
1762
|
-
animation = Promise.all(animations);
|
|
1763
|
-
}
|
|
1764
|
-
else if (typeof definition === "string") {
|
|
1765
|
-
animation = animateVariant(visualElement, definition, options);
|
|
1766
|
-
}
|
|
1767
|
-
else {
|
|
1768
|
-
const resolvedDefinition = typeof definition === "function"
|
|
1769
|
-
? resolveVariant(visualElement, definition, options.custom)
|
|
1770
|
-
: definition;
|
|
1771
|
-
animation = animateTarget(visualElement, resolvedDefinition, options);
|
|
1772
|
-
}
|
|
1773
|
-
return animation.then(() => visualElement.notify("AnimationComplete", definition));
|
|
1774
|
-
}
|
|
1775
1175
|
function animateVariant(visualElement, variant, options = {}) {
|
|
1776
|
-
const resolved = resolveVariant(visualElement, variant, options.custom);
|
|
1176
|
+
const resolved = wrap.resolveVariant(visualElement, variant, options.custom);
|
|
1777
1177
|
let { transition = visualElement.getDefaultTransition() || {} } = resolved || {};
|
|
1778
1178
|
if (options.transitionOverride) {
|
|
1779
1179
|
transition = options.transitionOverride;
|
|
@@ -1783,7 +1183,7 @@ function animateVariant(visualElement, variant, options = {}) {
|
|
|
1783
1183
|
* Otherwise, we resolve a Promise immediately for a composable no-op.
|
|
1784
1184
|
*/
|
|
1785
1185
|
const getAnimation = resolved
|
|
1786
|
-
? () => animateTarget(visualElement, resolved, options)
|
|
1186
|
+
? () => Promise.all(wrap.animateTarget(visualElement, resolved, options))
|
|
1787
1187
|
: () => Promise.resolve();
|
|
1788
1188
|
/**
|
|
1789
1189
|
* If we have children, create a callback that runs all their animations.
|
|
@@ -1804,57 +1204,12 @@ function animateVariant(visualElement, variant, options = {}) {
|
|
|
1804
1204
|
const [first, last] = when === "beforeChildren"
|
|
1805
1205
|
? [getAnimation, getChildAnimations]
|
|
1806
1206
|
: [getChildAnimations, getAnimation];
|
|
1807
|
-
return first().then(last);
|
|
1207
|
+
return first().then(() => last());
|
|
1808
1208
|
}
|
|
1809
1209
|
else {
|
|
1810
1210
|
return Promise.all([getAnimation(), getChildAnimations(options.delay)]);
|
|
1811
1211
|
}
|
|
1812
1212
|
}
|
|
1813
|
-
/**
|
|
1814
|
-
* @internal
|
|
1815
|
-
*/
|
|
1816
|
-
function animateTarget(visualElement, definition, { delay = 0, transitionOverride, type } = {}) {
|
|
1817
|
-
let { transition = visualElement.getDefaultTransition(), transitionEnd, ...target } = visualElement.makeTargetAnimatable(definition);
|
|
1818
|
-
const willChange = visualElement.getValue("willChange");
|
|
1819
|
-
if (transitionOverride)
|
|
1820
|
-
transition = transitionOverride;
|
|
1821
|
-
const animations = [];
|
|
1822
|
-
const animationTypeState = type &&
|
|
1823
|
-
visualElement.animationState &&
|
|
1824
|
-
visualElement.animationState.getState()[type];
|
|
1825
|
-
for (const key in target) {
|
|
1826
|
-
const value = visualElement.getValue(key);
|
|
1827
|
-
const valueTarget = target[key];
|
|
1828
|
-
if (!value ||
|
|
1829
|
-
valueTarget === undefined ||
|
|
1830
|
-
(animationTypeState &&
|
|
1831
|
-
shouldBlockAnimation(animationTypeState, key))) {
|
|
1832
|
-
continue;
|
|
1833
|
-
}
|
|
1834
|
-
const valueTransition = { delay, elapsed: 0, ...transition };
|
|
1835
|
-
/**
|
|
1836
|
-
* If this is the first time a value is being animated, check
|
|
1837
|
-
* to see if we're handling off from an existing animation.
|
|
1838
|
-
*/
|
|
1839
|
-
if (window.HandoffAppearAnimations && !value.hasAnimated) {
|
|
1840
|
-
const appearId = visualElement.getProps()[optimizedAppearDataAttribute];
|
|
1841
|
-
if (appearId) {
|
|
1842
|
-
valueTransition.elapsed = window.HandoffAppearAnimations(appearId, key, value, wrap.sync);
|
|
1843
|
-
}
|
|
1844
|
-
}
|
|
1845
|
-
let animation = value.start(wrap.createMotionValueAnimation(key, value, valueTarget, visualElement.shouldReduceMotion && wrap.transformProps.has(key)
|
|
1846
|
-
? { type: false }
|
|
1847
|
-
: valueTransition));
|
|
1848
|
-
if (isWillChangeMotionValue(willChange)) {
|
|
1849
|
-
willChange.add(key);
|
|
1850
|
-
animation = animation.then(() => willChange.remove(key));
|
|
1851
|
-
}
|
|
1852
|
-
animations.push(animation);
|
|
1853
|
-
}
|
|
1854
|
-
return Promise.all(animations).then(() => {
|
|
1855
|
-
transitionEnd && setTarget(visualElement, transitionEnd);
|
|
1856
|
-
});
|
|
1857
|
-
}
|
|
1858
1213
|
function animateChildren(visualElement, variant, delayChildren = 0, staggerChildren = 0, staggerDirection = 1, options) {
|
|
1859
1214
|
const animations = [];
|
|
1860
1215
|
const maxStaggerDuration = (visualElement.variantChildren.size - 1) * staggerChildren;
|
|
@@ -1872,26 +1227,31 @@ function animateChildren(visualElement, variant, delayChildren = 0, staggerChild
|
|
|
1872
1227
|
});
|
|
1873
1228
|
return Promise.all(animations);
|
|
1874
1229
|
}
|
|
1875
|
-
function stopAnimation(visualElement) {
|
|
1876
|
-
visualElement.values.forEach((value) => value.stop());
|
|
1877
|
-
}
|
|
1878
1230
|
function sortByTreeOrder(a, b) {
|
|
1879
1231
|
return a.sortNodePosition(b);
|
|
1880
1232
|
}
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1233
|
+
|
|
1234
|
+
function animateVisualElement(visualElement, definition, options = {}) {
|
|
1235
|
+
visualElement.notify("AnimationStart", definition);
|
|
1236
|
+
let animation;
|
|
1237
|
+
if (Array.isArray(definition)) {
|
|
1238
|
+
const animations = definition.map((variant) => animateVariant(visualElement, variant, options));
|
|
1239
|
+
animation = Promise.all(animations);
|
|
1240
|
+
}
|
|
1241
|
+
else if (typeof definition === "string") {
|
|
1242
|
+
animation = animateVariant(visualElement, definition, options);
|
|
1243
|
+
}
|
|
1244
|
+
else {
|
|
1245
|
+
const resolvedDefinition = typeof definition === "function"
|
|
1246
|
+
? wrap.resolveVariant(visualElement, definition, options.custom)
|
|
1247
|
+
: definition;
|
|
1248
|
+
animation = Promise.all(wrap.animateTarget(visualElement, resolvedDefinition, options));
|
|
1249
|
+
}
|
|
1250
|
+
return animation.then(() => visualElement.notify("AnimationComplete", definition));
|
|
1891
1251
|
}
|
|
1892
1252
|
|
|
1893
|
-
const reversePriorityOrder = [...variantPriorityOrder].reverse();
|
|
1894
|
-
const numAnimationTypes = variantPriorityOrder.length;
|
|
1253
|
+
const reversePriorityOrder = [...wrap.variantPriorityOrder].reverse();
|
|
1254
|
+
const numAnimationTypes = wrap.variantPriorityOrder.length;
|
|
1895
1255
|
function animateList(visualElement) {
|
|
1896
1256
|
return (animations) => Promise.all(animations.map(({ animation, options }) => animateVisualElement(visualElement, animation, options)));
|
|
1897
1257
|
}
|
|
@@ -1904,7 +1264,7 @@ function createAnimationState(visualElement) {
|
|
|
1904
1264
|
* each active animation type into an object of resolved values for it.
|
|
1905
1265
|
*/
|
|
1906
1266
|
const buildResolvedTypeValues = (acc, definition) => {
|
|
1907
|
-
const resolved = resolveVariant(visualElement, definition);
|
|
1267
|
+
const resolved = wrap.resolveVariant(visualElement, definition);
|
|
1908
1268
|
if (resolved) {
|
|
1909
1269
|
const { transition, transitionEnd, ...target } = resolved;
|
|
1910
1270
|
acc = { ...acc, ...target, ...transitionEnd };
|
|
@@ -1962,7 +1322,7 @@ function createAnimationState(visualElement) {
|
|
|
1962
1322
|
const type = reversePriorityOrder[i];
|
|
1963
1323
|
const typeState = state[type];
|
|
1964
1324
|
const prop = props[type] !== undefined ? props[type] : context[type];
|
|
1965
|
-
const propIsVariant = isVariantLabel(prop);
|
|
1325
|
+
const propIsVariant = wrap.isVariantLabel(prop);
|
|
1966
1326
|
/**
|
|
1967
1327
|
* If this type has *just* changed isActive status, set activeDelta
|
|
1968
1328
|
* to that status. Otherwise set to null.
|
|
@@ -1997,7 +1357,7 @@ function createAnimationState(visualElement) {
|
|
|
1997
1357
|
// If we didn't and don't have any defined prop for this animation type
|
|
1998
1358
|
(!prop && !typeState.prevProp) ||
|
|
1999
1359
|
// Or if the prop doesn't define an animation
|
|
2000
|
-
isAnimationControls(prop) ||
|
|
1360
|
+
wrap.isAnimationControls(prop) ||
|
|
2001
1361
|
typeof prop === "boolean") {
|
|
2002
1362
|
continue;
|
|
2003
1363
|
}
|
|
@@ -2060,7 +1420,7 @@ function createAnimationState(visualElement) {
|
|
|
2060
1420
|
* If both values are keyframes, we need to shallow compare them to
|
|
2061
1421
|
* detect whether any value has changed. If it has, we animate it.
|
|
2062
1422
|
*/
|
|
2063
|
-
if (isKeyframesTarget(next) && isKeyframesTarget(prev)) {
|
|
1423
|
+
if (wrap.isKeyframesTarget(next) && wrap.isKeyframesTarget(prev)) {
|
|
2064
1424
|
if (!shallowCompare(next, prev) || variantDidChange) {
|
|
2065
1425
|
markToAnimate(key);
|
|
2066
1426
|
}
|
|
@@ -2213,7 +1573,7 @@ class AnimationFeature extends Feature {
|
|
|
2213
1573
|
updateAnimationControlsSubscription() {
|
|
2214
1574
|
const { animate } = this.node.getProps();
|
|
2215
1575
|
this.unmount();
|
|
2216
|
-
if (isAnimationControls(animate)) {
|
|
1576
|
+
if (wrap.isAnimationControls(animate)) {
|
|
2217
1577
|
this.unmount = animate.subscribe(this.node);
|
|
2218
1578
|
}
|
|
2219
1579
|
}
|
|
@@ -2566,212 +1926,10 @@ function resolvePointElastic(dragElastic, label) {
|
|
|
2566
1926
|
: dragElastic[label] || 0;
|
|
2567
1927
|
}
|
|
2568
1928
|
|
|
2569
|
-
const createAxisDelta = () => ({
|
|
2570
|
-
translate: 0,
|
|
2571
|
-
scale: 1,
|
|
2572
|
-
origin: 0,
|
|
2573
|
-
originPoint: 0,
|
|
2574
|
-
});
|
|
2575
|
-
const createDelta = () => ({
|
|
2576
|
-
x: createAxisDelta(),
|
|
2577
|
-
y: createAxisDelta(),
|
|
2578
|
-
});
|
|
2579
|
-
const createAxis = () => ({ min: 0, max: 0 });
|
|
2580
|
-
const createBox = () => ({
|
|
2581
|
-
x: createAxis(),
|
|
2582
|
-
y: createAxis(),
|
|
2583
|
-
});
|
|
2584
|
-
|
|
2585
1929
|
function eachAxis(callback) {
|
|
2586
1930
|
return [callback("x"), callback("y")];
|
|
2587
1931
|
}
|
|
2588
1932
|
|
|
2589
|
-
/**
|
|
2590
|
-
* Bounding boxes tend to be defined as top, left, right, bottom. For various operations
|
|
2591
|
-
* it's easier to consider each axis individually. This function returns a bounding box
|
|
2592
|
-
* as a map of single-axis min/max values.
|
|
2593
|
-
*/
|
|
2594
|
-
function convertBoundingBoxToBox({ top, left, right, bottom, }) {
|
|
2595
|
-
return {
|
|
2596
|
-
x: { min: left, max: right },
|
|
2597
|
-
y: { min: top, max: bottom },
|
|
2598
|
-
};
|
|
2599
|
-
}
|
|
2600
|
-
function convertBoxToBoundingBox({ x, y }) {
|
|
2601
|
-
return { top: y.min, right: x.max, bottom: y.max, left: x.min };
|
|
2602
|
-
}
|
|
2603
|
-
/**
|
|
2604
|
-
* Applies a TransformPoint function to a bounding box. TransformPoint is usually a function
|
|
2605
|
-
* provided by Framer to allow measured points to be corrected for device scaling. This is used
|
|
2606
|
-
* when measuring DOM elements and DOM event points.
|
|
2607
|
-
*/
|
|
2608
|
-
function transformBoxPoints(point, transformPoint) {
|
|
2609
|
-
if (!transformPoint)
|
|
2610
|
-
return point;
|
|
2611
|
-
const topLeft = transformPoint({ x: point.left, y: point.top });
|
|
2612
|
-
const bottomRight = transformPoint({ x: point.right, y: point.bottom });
|
|
2613
|
-
return {
|
|
2614
|
-
top: topLeft.y,
|
|
2615
|
-
left: topLeft.x,
|
|
2616
|
-
bottom: bottomRight.y,
|
|
2617
|
-
right: bottomRight.x,
|
|
2618
|
-
};
|
|
2619
|
-
}
|
|
2620
|
-
|
|
2621
|
-
function isIdentityScale(scale) {
|
|
2622
|
-
return scale === undefined || scale === 1;
|
|
2623
|
-
}
|
|
2624
|
-
function hasScale({ scale, scaleX, scaleY }) {
|
|
2625
|
-
return (!isIdentityScale(scale) ||
|
|
2626
|
-
!isIdentityScale(scaleX) ||
|
|
2627
|
-
!isIdentityScale(scaleY));
|
|
2628
|
-
}
|
|
2629
|
-
function hasTransform(values) {
|
|
2630
|
-
return (hasScale(values) ||
|
|
2631
|
-
has2DTranslate(values) ||
|
|
2632
|
-
values.z ||
|
|
2633
|
-
values.rotate ||
|
|
2634
|
-
values.rotateX ||
|
|
2635
|
-
values.rotateY);
|
|
2636
|
-
}
|
|
2637
|
-
function has2DTranslate(values) {
|
|
2638
|
-
return is2DTranslate(values.x) || is2DTranslate(values.y);
|
|
2639
|
-
}
|
|
2640
|
-
function is2DTranslate(value) {
|
|
2641
|
-
return value && value !== "0%";
|
|
2642
|
-
}
|
|
2643
|
-
|
|
2644
|
-
/**
|
|
2645
|
-
* Scales a point based on a factor and an originPoint
|
|
2646
|
-
*/
|
|
2647
|
-
function scalePoint(point, scale, originPoint) {
|
|
2648
|
-
const distanceFromOrigin = point - originPoint;
|
|
2649
|
-
const scaled = scale * distanceFromOrigin;
|
|
2650
|
-
return originPoint + scaled;
|
|
2651
|
-
}
|
|
2652
|
-
/**
|
|
2653
|
-
* Applies a translate/scale delta to a point
|
|
2654
|
-
*/
|
|
2655
|
-
function applyPointDelta(point, translate, scale, originPoint, boxScale) {
|
|
2656
|
-
if (boxScale !== undefined) {
|
|
2657
|
-
point = scalePoint(point, boxScale, originPoint);
|
|
2658
|
-
}
|
|
2659
|
-
return scalePoint(point, scale, originPoint) + translate;
|
|
2660
|
-
}
|
|
2661
|
-
/**
|
|
2662
|
-
* Applies a translate/scale delta to an axis
|
|
2663
|
-
*/
|
|
2664
|
-
function applyAxisDelta(axis, translate = 0, scale = 1, originPoint, boxScale) {
|
|
2665
|
-
axis.min = applyPointDelta(axis.min, translate, scale, originPoint, boxScale);
|
|
2666
|
-
axis.max = applyPointDelta(axis.max, translate, scale, originPoint, boxScale);
|
|
2667
|
-
}
|
|
2668
|
-
/**
|
|
2669
|
-
* Applies a translate/scale delta to a box
|
|
2670
|
-
*/
|
|
2671
|
-
function applyBoxDelta(box, { x, y }) {
|
|
2672
|
-
applyAxisDelta(box.x, x.translate, x.scale, x.originPoint);
|
|
2673
|
-
applyAxisDelta(box.y, y.translate, y.scale, y.originPoint);
|
|
2674
|
-
}
|
|
2675
|
-
/**
|
|
2676
|
-
* Apply a tree of deltas to a box. We do this to calculate the effect of all the transforms
|
|
2677
|
-
* in a tree upon our box before then calculating how to project it into our desired viewport-relative box
|
|
2678
|
-
*
|
|
2679
|
-
* This is the final nested loop within updateLayoutDelta for future refactoring
|
|
2680
|
-
*/
|
|
2681
|
-
function applyTreeDeltas(box, treeScale, treePath, isSharedTransition = false) {
|
|
2682
|
-
const treeLength = treePath.length;
|
|
2683
|
-
if (!treeLength)
|
|
2684
|
-
return;
|
|
2685
|
-
// Reset the treeScale
|
|
2686
|
-
treeScale.x = treeScale.y = 1;
|
|
2687
|
-
let node;
|
|
2688
|
-
let delta;
|
|
2689
|
-
for (let i = 0; i < treeLength; i++) {
|
|
2690
|
-
node = treePath[i];
|
|
2691
|
-
delta = node.projectionDelta;
|
|
2692
|
-
/**
|
|
2693
|
-
* TODO: Prefer to remove this, but currently we have motion components with
|
|
2694
|
-
* display: contents in Framer.
|
|
2695
|
-
*/
|
|
2696
|
-
const instance = node.instance;
|
|
2697
|
-
if (instance &&
|
|
2698
|
-
instance.style &&
|
|
2699
|
-
instance.style.display === "contents") {
|
|
2700
|
-
continue;
|
|
2701
|
-
}
|
|
2702
|
-
if (isSharedTransition &&
|
|
2703
|
-
node.options.layoutScroll &&
|
|
2704
|
-
node.scroll &&
|
|
2705
|
-
node !== node.root) {
|
|
2706
|
-
transformBox(box, {
|
|
2707
|
-
x: -node.scroll.offset.x,
|
|
2708
|
-
y: -node.scroll.offset.y,
|
|
2709
|
-
});
|
|
2710
|
-
}
|
|
2711
|
-
if (delta) {
|
|
2712
|
-
// Incoporate each ancestor's scale into a culmulative treeScale for this component
|
|
2713
|
-
treeScale.x *= delta.x.scale;
|
|
2714
|
-
treeScale.y *= delta.y.scale;
|
|
2715
|
-
// Apply each ancestor's calculated delta into this component's recorded layout box
|
|
2716
|
-
applyBoxDelta(box, delta);
|
|
2717
|
-
}
|
|
2718
|
-
if (isSharedTransition && hasTransform(node.latestValues)) {
|
|
2719
|
-
transformBox(box, node.latestValues);
|
|
2720
|
-
}
|
|
2721
|
-
}
|
|
2722
|
-
/**
|
|
2723
|
-
* Snap tree scale back to 1 if it's within a non-perceivable threshold.
|
|
2724
|
-
* This will help reduce useless scales getting rendered.
|
|
2725
|
-
*/
|
|
2726
|
-
treeScale.x = snapToDefault(treeScale.x);
|
|
2727
|
-
treeScale.y = snapToDefault(treeScale.y);
|
|
2728
|
-
}
|
|
2729
|
-
function snapToDefault(scale) {
|
|
2730
|
-
if (Number.isInteger(scale))
|
|
2731
|
-
return scale;
|
|
2732
|
-
return scale > 1.0000000000001 || scale < 0.999999999999 ? scale : 1;
|
|
2733
|
-
}
|
|
2734
|
-
function translateAxis(axis, distance) {
|
|
2735
|
-
axis.min = axis.min + distance;
|
|
2736
|
-
axis.max = axis.max + distance;
|
|
2737
|
-
}
|
|
2738
|
-
/**
|
|
2739
|
-
* Apply a transform to an axis from the latest resolved motion values.
|
|
2740
|
-
* This function basically acts as a bridge between a flat motion value map
|
|
2741
|
-
* and applyAxisDelta
|
|
2742
|
-
*/
|
|
2743
|
-
function transformAxis(axis, transforms, [key, scaleKey, originKey]) {
|
|
2744
|
-
const axisOrigin = transforms[originKey] !== undefined ? transforms[originKey] : 0.5;
|
|
2745
|
-
const originPoint = wrap.mix(axis.min, axis.max, axisOrigin);
|
|
2746
|
-
// Apply the axis delta to the final axis
|
|
2747
|
-
applyAxisDelta(axis, transforms[key], transforms[scaleKey], originPoint, transforms.scale);
|
|
2748
|
-
}
|
|
2749
|
-
/**
|
|
2750
|
-
* The names of the motion values we want to apply as translation, scale and origin.
|
|
2751
|
-
*/
|
|
2752
|
-
const xKeys$1 = ["x", "scaleX", "originX"];
|
|
2753
|
-
const yKeys$1 = ["y", "scaleY", "originY"];
|
|
2754
|
-
/**
|
|
2755
|
-
* Apply a transform to a box from the latest resolved motion values.
|
|
2756
|
-
*/
|
|
2757
|
-
function transformBox(box, transform) {
|
|
2758
|
-
transformAxis(box.x, transform, xKeys$1);
|
|
2759
|
-
transformAxis(box.y, transform, yKeys$1);
|
|
2760
|
-
}
|
|
2761
|
-
|
|
2762
|
-
function measureViewportBox(instance, transformPoint) {
|
|
2763
|
-
return convertBoundingBoxToBox(transformBoxPoints(instance.getBoundingClientRect(), transformPoint));
|
|
2764
|
-
}
|
|
2765
|
-
function measurePageBox(element, rootProjectionNode, transformPagePoint) {
|
|
2766
|
-
const viewportBox = measureViewportBox(element, transformPagePoint);
|
|
2767
|
-
const { scroll } = rootProjectionNode;
|
|
2768
|
-
if (scroll) {
|
|
2769
|
-
translateAxis(viewportBox.x, scroll.offset.x);
|
|
2770
|
-
translateAxis(viewportBox.y, scroll.offset.y);
|
|
2771
|
-
}
|
|
2772
|
-
return viewportBox;
|
|
2773
|
-
}
|
|
2774
|
-
|
|
2775
1933
|
const elementDragControls = new WeakMap();
|
|
2776
1934
|
/**
|
|
2777
1935
|
*
|
|
@@ -2794,7 +1952,7 @@ class VisualElementDragControls {
|
|
|
2794
1952
|
/**
|
|
2795
1953
|
* The per-axis resolved elastic values.
|
|
2796
1954
|
*/
|
|
2797
|
-
this.elastic = createBox();
|
|
1955
|
+
this.elastic = wrap.createBox();
|
|
2798
1956
|
this.visualElement = visualElement;
|
|
2799
1957
|
}
|
|
2800
1958
|
start(originEvent, { snapToCursor = false } = {}) {
|
|
@@ -2941,7 +2099,7 @@ class VisualElementDragControls {
|
|
|
2941
2099
|
const { dragConstraints, dragElastic } = this.getProps();
|
|
2942
2100
|
const { layout } = this.visualElement.projection || {};
|
|
2943
2101
|
const prevConstraints = this.constraints;
|
|
2944
|
-
if (dragConstraints && isRefObject(dragConstraints)) {
|
|
2102
|
+
if (dragConstraints && wrap.isRefObject(dragConstraints)) {
|
|
2945
2103
|
if (!this.constraints) {
|
|
2946
2104
|
this.constraints = this.resolveRefConstraints();
|
|
2947
2105
|
}
|
|
@@ -2972,7 +2130,7 @@ class VisualElementDragControls {
|
|
|
2972
2130
|
}
|
|
2973
2131
|
resolveRefConstraints() {
|
|
2974
2132
|
const { dragConstraints: constraints, onMeasureDragConstraints } = this.getProps();
|
|
2975
|
-
if (!constraints || !isRefObject(constraints))
|
|
2133
|
+
if (!constraints || !wrap.isRefObject(constraints))
|
|
2976
2134
|
return false;
|
|
2977
2135
|
const constraintsElement = constraints.current;
|
|
2978
2136
|
wrap.invariant(constraintsElement !== null, "If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.");
|
|
@@ -2980,17 +2138,17 @@ class VisualElementDragControls {
|
|
|
2980
2138
|
// TODO
|
|
2981
2139
|
if (!projection || !projection.layout)
|
|
2982
2140
|
return false;
|
|
2983
|
-
const constraintsBox = measurePageBox(constraintsElement, projection.root, this.visualElement.getTransformPagePoint());
|
|
2141
|
+
const constraintsBox = wrap.measurePageBox(constraintsElement, projection.root, this.visualElement.getTransformPagePoint());
|
|
2984
2142
|
let measuredConstraints = calcViewportConstraints(projection.layout.layoutBox, constraintsBox);
|
|
2985
2143
|
/**
|
|
2986
2144
|
* If there's an onMeasureDragConstraints listener we call it and
|
|
2987
2145
|
* if different constraints are returned, set constraints to that
|
|
2988
2146
|
*/
|
|
2989
2147
|
if (onMeasureDragConstraints) {
|
|
2990
|
-
const userConstraints = onMeasureDragConstraints(convertBoxToBoundingBox(measuredConstraints));
|
|
2148
|
+
const userConstraints = onMeasureDragConstraints(wrap.convertBoxToBoundingBox(measuredConstraints));
|
|
2991
2149
|
this.hasMutatedConstraints = !!userConstraints;
|
|
2992
2150
|
if (userConstraints) {
|
|
2993
|
-
measuredConstraints = convertBoundingBoxToBox(userConstraints);
|
|
2151
|
+
measuredConstraints = wrap.convertBoundingBoxToBox(userConstraints);
|
|
2994
2152
|
}
|
|
2995
2153
|
}
|
|
2996
2154
|
return measuredConstraints;
|
|
@@ -3034,7 +2192,7 @@ class VisualElementDragControls {
|
|
|
3034
2192
|
}
|
|
3035
2193
|
startAxisValueAnimation(axis, transition) {
|
|
3036
2194
|
const axisValue = this.getAxisMotionValue(axis);
|
|
3037
|
-
return axisValue.start(wrap.
|
|
2195
|
+
return axisValue.start(wrap.animateMotionValue(axis, axisValue, 0, transition));
|
|
3038
2196
|
}
|
|
3039
2197
|
stopAnimation() {
|
|
3040
2198
|
eachAxis((axis) => this.getAxisMotionValue(axis).stop());
|
|
@@ -3077,7 +2235,7 @@ class VisualElementDragControls {
|
|
|
3077
2235
|
return;
|
|
3078
2236
|
const { drag, dragConstraints } = this.getProps();
|
|
3079
2237
|
const { projection } = this.visualElement;
|
|
3080
|
-
if (!isRefObject(dragConstraints) || !projection || !this.constraints)
|
|
2238
|
+
if (!wrap.isRefObject(dragConstraints) || !projection || !this.constraints)
|
|
3081
2239
|
return;
|
|
3082
2240
|
/**
|
|
3083
2241
|
* Stop current animations as there can be visual glitching if we try to do
|
|
@@ -3135,7 +2293,7 @@ class VisualElementDragControls {
|
|
|
3135
2293
|
});
|
|
3136
2294
|
const measureDragConstraints = () => {
|
|
3137
2295
|
const { dragConstraints } = this.getProps();
|
|
3138
|
-
if (isRefObject(dragConstraints)) {
|
|
2296
|
+
if (wrap.isRefObject(dragConstraints)) {
|
|
3139
2297
|
this.constraints = this.resolveRefConstraints();
|
|
3140
2298
|
}
|
|
3141
2299
|
};
|
|
@@ -3381,9 +2539,9 @@ function copyBoxInto(box, originBox) {
|
|
|
3381
2539
|
*/
|
|
3382
2540
|
function removePointDelta(point, translate, scale, originPoint, boxScale) {
|
|
3383
2541
|
point -= translate;
|
|
3384
|
-
point = scalePoint(point, 1 / scale, originPoint);
|
|
2542
|
+
point = wrap.scalePoint(point, 1 / scale, originPoint);
|
|
3385
2543
|
if (boxScale !== undefined) {
|
|
3386
|
-
point = scalePoint(point, 1 / boxScale, originPoint);
|
|
2544
|
+
point = wrap.scalePoint(point, 1 / boxScale, originPoint);
|
|
3387
2545
|
}
|
|
3388
2546
|
return point;
|
|
3389
2547
|
}
|
|
@@ -3795,8 +2953,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
3795
2953
|
mount(instance, isLayoutDirty = false) {
|
|
3796
2954
|
if (this.instance)
|
|
3797
2955
|
return;
|
|
3798
|
-
this.isSVG =
|
|
3799
|
-
instance instanceof SVGElement && instance.tagName !== "svg";
|
|
2956
|
+
this.isSVG = wrap.isSVGElement(instance);
|
|
3800
2957
|
this.instance = instance;
|
|
3801
2958
|
const { layoutId, layout, visualElement } = this.options;
|
|
3802
2959
|
if (visualElement && !visualElement.current) {
|
|
@@ -4054,7 +3211,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4054
3211
|
}
|
|
4055
3212
|
const prevLayout = this.layout;
|
|
4056
3213
|
this.layout = this.measure(false);
|
|
4057
|
-
this.layoutCorrected = createBox();
|
|
3214
|
+
this.layoutCorrected = wrap.createBox();
|
|
4058
3215
|
this.isLayoutDirty = false;
|
|
4059
3216
|
this.projectionDelta = undefined;
|
|
4060
3217
|
this.notifyListeners("measure", this.layout.layoutBox);
|
|
@@ -4090,7 +3247,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4090
3247
|
const transformTemplateHasChanged = transformTemplateValue !== this.prevTransformTemplateValue;
|
|
4091
3248
|
if (isResetRequested &&
|
|
4092
3249
|
(hasProjection ||
|
|
4093
|
-
hasTransform(this.latestValues) ||
|
|
3250
|
+
wrap.hasTransform(this.latestValues) ||
|
|
4094
3251
|
transformTemplateHasChanged)) {
|
|
4095
3252
|
resetTransform(this.instance, transformTemplateValue);
|
|
4096
3253
|
this.shouldResetTransform = false;
|
|
@@ -4120,18 +3277,18 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4120
3277
|
measurePageBox() {
|
|
4121
3278
|
const { visualElement } = this.options;
|
|
4122
3279
|
if (!visualElement)
|
|
4123
|
-
return createBox();
|
|
3280
|
+
return wrap.createBox();
|
|
4124
3281
|
const box = visualElement.measureViewportBox();
|
|
4125
3282
|
// Remove viewport scroll to give page-relative coordinates
|
|
4126
3283
|
const { scroll } = this.root;
|
|
4127
3284
|
if (scroll) {
|
|
4128
|
-
translateAxis(box.x, scroll.offset.x);
|
|
4129
|
-
translateAxis(box.y, scroll.offset.y);
|
|
3285
|
+
wrap.translateAxis(box.x, scroll.offset.x);
|
|
3286
|
+
wrap.translateAxis(box.y, scroll.offset.y);
|
|
4130
3287
|
}
|
|
4131
3288
|
return box;
|
|
4132
3289
|
}
|
|
4133
3290
|
removeElementScroll(box) {
|
|
4134
|
-
const boxWithoutScroll = createBox();
|
|
3291
|
+
const boxWithoutScroll = wrap.createBox();
|
|
4135
3292
|
copyBoxInto(boxWithoutScroll, box);
|
|
4136
3293
|
/**
|
|
4137
3294
|
* Performance TODO: Keep a cumulative scroll offset down the tree
|
|
@@ -4153,18 +3310,18 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4153
3310
|
* to the measured bounding box.
|
|
4154
3311
|
*/
|
|
4155
3312
|
if (rootScroll) {
|
|
4156
|
-
translateAxis(boxWithoutScroll.x, -rootScroll.offset.x);
|
|
4157
|
-
translateAxis(boxWithoutScroll.y, -rootScroll.offset.y);
|
|
3313
|
+
wrap.translateAxis(boxWithoutScroll.x, -rootScroll.offset.x);
|
|
3314
|
+
wrap.translateAxis(boxWithoutScroll.y, -rootScroll.offset.y);
|
|
4158
3315
|
}
|
|
4159
3316
|
}
|
|
4160
|
-
translateAxis(boxWithoutScroll.x, scroll.offset.x);
|
|
4161
|
-
translateAxis(boxWithoutScroll.y, scroll.offset.y);
|
|
3317
|
+
wrap.translateAxis(boxWithoutScroll.x, scroll.offset.x);
|
|
3318
|
+
wrap.translateAxis(boxWithoutScroll.y, scroll.offset.y);
|
|
4162
3319
|
}
|
|
4163
3320
|
}
|
|
4164
3321
|
return boxWithoutScroll;
|
|
4165
3322
|
}
|
|
4166
3323
|
applyTransform(box, transformOnly = false) {
|
|
4167
|
-
const withTransforms = createBox();
|
|
3324
|
+
const withTransforms = wrap.createBox();
|
|
4168
3325
|
copyBoxInto(withTransforms, box);
|
|
4169
3326
|
for (let i = 0; i < this.path.length; i++) {
|
|
4170
3327
|
const node = this.path[i];
|
|
@@ -4172,36 +3329,36 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4172
3329
|
node.options.layoutScroll &&
|
|
4173
3330
|
node.scroll &&
|
|
4174
3331
|
node !== node.root) {
|
|
4175
|
-
transformBox(withTransforms, {
|
|
3332
|
+
wrap.transformBox(withTransforms, {
|
|
4176
3333
|
x: -node.scroll.offset.x,
|
|
4177
3334
|
y: -node.scroll.offset.y,
|
|
4178
3335
|
});
|
|
4179
3336
|
}
|
|
4180
|
-
if (!hasTransform(node.latestValues))
|
|
3337
|
+
if (!wrap.hasTransform(node.latestValues))
|
|
4181
3338
|
continue;
|
|
4182
|
-
transformBox(withTransforms, node.latestValues);
|
|
3339
|
+
wrap.transformBox(withTransforms, node.latestValues);
|
|
4183
3340
|
}
|
|
4184
|
-
if (hasTransform(this.latestValues)) {
|
|
4185
|
-
transformBox(withTransforms, this.latestValues);
|
|
3341
|
+
if (wrap.hasTransform(this.latestValues)) {
|
|
3342
|
+
wrap.transformBox(withTransforms, this.latestValues);
|
|
4186
3343
|
}
|
|
4187
3344
|
return withTransforms;
|
|
4188
3345
|
}
|
|
4189
3346
|
removeTransform(box) {
|
|
4190
|
-
const boxWithoutTransform = createBox();
|
|
3347
|
+
const boxWithoutTransform = wrap.createBox();
|
|
4191
3348
|
copyBoxInto(boxWithoutTransform, box);
|
|
4192
3349
|
for (let i = 0; i < this.path.length; i++) {
|
|
4193
3350
|
const node = this.path[i];
|
|
4194
3351
|
if (!node.instance)
|
|
4195
3352
|
continue;
|
|
4196
|
-
if (!hasTransform(node.latestValues))
|
|
3353
|
+
if (!wrap.hasTransform(node.latestValues))
|
|
4197
3354
|
continue;
|
|
4198
|
-
hasScale(node.latestValues) && node.updateSnapshot();
|
|
4199
|
-
const sourceBox = createBox();
|
|
3355
|
+
wrap.hasScale(node.latestValues) && node.updateSnapshot();
|
|
3356
|
+
const sourceBox = wrap.createBox();
|
|
4200
3357
|
const nodeBox = node.measurePageBox();
|
|
4201
3358
|
copyBoxInto(sourceBox, nodeBox);
|
|
4202
3359
|
removeBoxTransforms(boxWithoutTransform, node.latestValues, node.snapshot ? node.snapshot.layoutBox : undefined, sourceBox);
|
|
4203
3360
|
}
|
|
4204
|
-
if (hasTransform(this.latestValues)) {
|
|
3361
|
+
if (wrap.hasTransform(this.latestValues)) {
|
|
4205
3362
|
removeBoxTransforms(boxWithoutTransform, this.latestValues);
|
|
4206
3363
|
}
|
|
4207
3364
|
return boxWithoutTransform;
|
|
@@ -4268,8 +3425,8 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4268
3425
|
const relativeParent = this.getClosestProjectingParent();
|
|
4269
3426
|
if (relativeParent && relativeParent.layout) {
|
|
4270
3427
|
this.relativeParent = relativeParent;
|
|
4271
|
-
this.relativeTarget = createBox();
|
|
4272
|
-
this.relativeTargetOrigin = createBox();
|
|
3428
|
+
this.relativeTarget = wrap.createBox();
|
|
3429
|
+
this.relativeTargetOrigin = wrap.createBox();
|
|
4273
3430
|
calcRelativePosition(this.relativeTargetOrigin, this.layout.layoutBox, relativeParent.layout.layoutBox);
|
|
4274
3431
|
copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
|
|
4275
3432
|
}
|
|
@@ -4287,8 +3444,8 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4287
3444
|
* Lazy-init target data structure
|
|
4288
3445
|
*/
|
|
4289
3446
|
if (!this.target) {
|
|
4290
|
-
this.target = createBox();
|
|
4291
|
-
this.targetWithTransforms = createBox();
|
|
3447
|
+
this.target = wrap.createBox();
|
|
3448
|
+
this.targetWithTransforms = wrap.createBox();
|
|
4292
3449
|
}
|
|
4293
3450
|
/**
|
|
4294
3451
|
* If we've got a relative box for this component, resolve it into a target relative to the parent.
|
|
@@ -4320,7 +3477,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4320
3477
|
else {
|
|
4321
3478
|
copyBoxInto(this.target, this.layout.layoutBox);
|
|
4322
3479
|
}
|
|
4323
|
-
applyBoxDelta(this.target, this.targetDelta);
|
|
3480
|
+
wrap.applyBoxDelta(this.target, this.targetDelta);
|
|
4324
3481
|
}
|
|
4325
3482
|
else {
|
|
4326
3483
|
/**
|
|
@@ -4340,8 +3497,8 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4340
3497
|
!relativeParent.options.layoutScroll &&
|
|
4341
3498
|
relativeParent.target) {
|
|
4342
3499
|
this.relativeParent = relativeParent;
|
|
4343
|
-
this.relativeTarget = createBox();
|
|
4344
|
-
this.relativeTargetOrigin = createBox();
|
|
3500
|
+
this.relativeTarget = wrap.createBox();
|
|
3501
|
+
this.relativeTargetOrigin = wrap.createBox();
|
|
4345
3502
|
calcRelativePosition(this.relativeTargetOrigin, this.target, relativeParent.target);
|
|
4346
3503
|
copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
|
|
4347
3504
|
}
|
|
@@ -4356,8 +3513,8 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4356
3513
|
}
|
|
4357
3514
|
getClosestProjectingParent() {
|
|
4358
3515
|
if (!this.parent ||
|
|
4359
|
-
hasScale(this.parent.latestValues) ||
|
|
4360
|
-
has2DTranslate(this.parent.latestValues)) {
|
|
3516
|
+
wrap.hasScale(this.parent.latestValues) ||
|
|
3517
|
+
wrap.has2DTranslate(this.parent.latestValues)) {
|
|
4361
3518
|
return undefined;
|
|
4362
3519
|
}
|
|
4363
3520
|
if (this.parent.isProjecting()) {
|
|
@@ -4424,13 +3581,13 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4424
3581
|
* Apply all the parent deltas to this box to produce the corrected box. This
|
|
4425
3582
|
* is the layout box, as it will appear on screen as a result of the transforms of its parents.
|
|
4426
3583
|
*/
|
|
4427
|
-
applyTreeDeltas(this.layoutCorrected, this.treeScale, this.path, isShared);
|
|
3584
|
+
wrap.applyTreeDeltas(this.layoutCorrected, this.treeScale, this.path, isShared);
|
|
4428
3585
|
const { target } = lead;
|
|
4429
3586
|
if (!target)
|
|
4430
3587
|
return;
|
|
4431
3588
|
if (!this.projectionDelta) {
|
|
4432
|
-
this.projectionDelta = createDelta();
|
|
4433
|
-
this.projectionDeltaWithTransform = createDelta();
|
|
3589
|
+
this.projectionDelta = wrap.createDelta();
|
|
3590
|
+
this.projectionDeltaWithTransform = wrap.createDelta();
|
|
4434
3591
|
}
|
|
4435
3592
|
const prevTreeScaleX = this.treeScale.x;
|
|
4436
3593
|
const prevTreeScaleY = this.treeScale.y;
|
|
@@ -4482,13 +3639,13 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4482
3639
|
? snapshot.latestValues
|
|
4483
3640
|
: {};
|
|
4484
3641
|
const mixedValues = { ...this.latestValues };
|
|
4485
|
-
const targetDelta = createDelta();
|
|
3642
|
+
const targetDelta = wrap.createDelta();
|
|
4486
3643
|
if (!this.relativeParent ||
|
|
4487
3644
|
!this.relativeParent.options.layoutRoot) {
|
|
4488
3645
|
this.relativeTarget = this.relativeTargetOrigin = undefined;
|
|
4489
3646
|
}
|
|
4490
3647
|
this.attemptToResolveRelativeTarget = !hasOnlyRelativeTargetChanged;
|
|
4491
|
-
const relativeLayout = createBox();
|
|
3648
|
+
const relativeLayout = wrap.createBox();
|
|
4492
3649
|
const snapshotSource = snapshot ? snapshot.source : undefined;
|
|
4493
3650
|
const layoutSource = this.layout ? this.layout.source : undefined;
|
|
4494
3651
|
const isSharedLayoutAnimation = snapshotSource !== layoutSource;
|
|
@@ -4521,7 +3678,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4521
3678
|
this.isProjectionDirty = false;
|
|
4522
3679
|
}
|
|
4523
3680
|
if (!prevRelativeTarget)
|
|
4524
|
-
prevRelativeTarget = createBox();
|
|
3681
|
+
prevRelativeTarget = wrap.createBox();
|
|
4525
3682
|
copyBoxInto(prevRelativeTarget, this.relativeTarget);
|
|
4526
3683
|
}
|
|
4527
3684
|
if (isSharedLayoutAnimation) {
|
|
@@ -4551,8 +3708,9 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4551
3708
|
*/
|
|
4552
3709
|
this.pendingAnimation = wrap.sync.update(() => {
|
|
4553
3710
|
globalProjectionState.hasAnimatedSinceResize = true;
|
|
4554
|
-
this.currentAnimation = wrap.
|
|
3711
|
+
this.currentAnimation = wrap.animateSingleValue(0, animationTarget, {
|
|
4555
3712
|
...options,
|
|
3713
|
+
// keyframes: [0, animationTarget],÷
|
|
4556
3714
|
onUpdate: (latest) => {
|
|
4557
3715
|
this.mixTargetDelta(latest);
|
|
4558
3716
|
options.onUpdate && options.onUpdate(latest);
|
|
@@ -4602,7 +3760,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4602
3760
|
this.layout &&
|
|
4603
3761
|
layout &&
|
|
4604
3762
|
shouldAnimatePositionOnly(this.options.animationType, this.layout.layoutBox, layout.layoutBox)) {
|
|
4605
|
-
target = this.target || createBox();
|
|
3763
|
+
target = this.target || wrap.createBox();
|
|
4606
3764
|
const xLength = calcLength(this.layout.layoutBox.x);
|
|
4607
3765
|
target.x.min = lead.target.x.min;
|
|
4608
3766
|
target.x.max = target.x.min + xLength;
|
|
@@ -4616,7 +3774,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4616
3774
|
* This is the final box that we will then project into by calculating a transform delta and
|
|
4617
3775
|
* applying it to the corrected box.
|
|
4618
3776
|
*/
|
|
4619
|
-
transformBox(targetWithTransforms, latestValues);
|
|
3777
|
+
wrap.transformBox(targetWithTransforms, latestValues);
|
|
4620
3778
|
/**
|
|
4621
3779
|
* Update the delta between the corrected box and the final target box, after
|
|
4622
3780
|
* user-set transforms are applied to it. This will be used by the renderer to
|
|
@@ -4753,7 +3911,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4753
3911
|
emptyStyles.pointerEvents =
|
|
4754
3912
|
resolveMotionValue(styleProp.pointerEvents) || "";
|
|
4755
3913
|
}
|
|
4756
|
-
if (this.hasProjected && !hasTransform(this.latestValues)) {
|
|
3914
|
+
if (this.hasProjected && !wrap.hasTransform(this.latestValues)) {
|
|
4757
3915
|
emptyStyles.transform = transformTemplate
|
|
4758
3916
|
? transformTemplate({}, "")
|
|
4759
3917
|
: "none";
|
|
@@ -4798,10 +3956,10 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
4798
3956
|
/**
|
|
4799
3957
|
* Apply scale correction
|
|
4800
3958
|
*/
|
|
4801
|
-
for (const key in scaleCorrectors) {
|
|
3959
|
+
for (const key in wrap.scaleCorrectors) {
|
|
4802
3960
|
if (valuesToRender[key] === undefined)
|
|
4803
3961
|
continue;
|
|
4804
|
-
const { correct, applyTo } = scaleCorrectors[key];
|
|
3962
|
+
const { correct, applyTo } = wrap.scaleCorrectors[key];
|
|
4805
3963
|
/**
|
|
4806
3964
|
* Only apply scale correction to the value if we have an
|
|
4807
3965
|
* active projection transform. Otherwise these values become
|
|
@@ -4879,9 +4037,9 @@ function notifyLayoutUpdate(node) {
|
|
|
4879
4037
|
axisSnapshot.max = axisSnapshot.min + length;
|
|
4880
4038
|
});
|
|
4881
4039
|
}
|
|
4882
|
-
const layoutDelta = createDelta();
|
|
4040
|
+
const layoutDelta = wrap.createDelta();
|
|
4883
4041
|
calcBoxDelta(layoutDelta, layout, snapshot.layoutBox);
|
|
4884
|
-
const visualDelta = createDelta();
|
|
4042
|
+
const visualDelta = wrap.createDelta();
|
|
4885
4043
|
if (isShared) {
|
|
4886
4044
|
calcBoxDelta(visualDelta, node.applyTransform(measuredLayout, true), snapshot.measuredBox);
|
|
4887
4045
|
}
|
|
@@ -4899,9 +4057,9 @@ function notifyLayoutUpdate(node) {
|
|
|
4899
4057
|
if (relativeParent && !relativeParent.resumeFrom) {
|
|
4900
4058
|
const { snapshot: parentSnapshot, layout: parentLayout } = relativeParent;
|
|
4901
4059
|
if (parentSnapshot && parentLayout) {
|
|
4902
|
-
const relativeSnapshot = createBox();
|
|
4060
|
+
const relativeSnapshot = wrap.createBox();
|
|
4903
4061
|
calcRelativePosition(relativeSnapshot, snapshot.layoutBox, parentSnapshot.layoutBox);
|
|
4904
|
-
const relativeLayout = createBox();
|
|
4062
|
+
const relativeLayout = wrap.createBox();
|
|
4905
4063
|
calcRelativePosition(relativeLayout, layout, parentLayout.layoutBox);
|
|
4906
4064
|
if (!boxEquals(relativeSnapshot, relativeLayout)) {
|
|
4907
4065
|
hasRelativeTargetChanged = true;
|
|
@@ -5140,89 +4298,6 @@ const correctBorderRadius = {
|
|
|
5140
4298
|
},
|
|
5141
4299
|
};
|
|
5142
4300
|
|
|
5143
|
-
/**
|
|
5144
|
-
* Parse Framer's special CSS variable format into a CSS token and a fallback.
|
|
5145
|
-
*
|
|
5146
|
-
* ```
|
|
5147
|
-
* `var(--foo, #fff)` => [`--foo`, '#fff']
|
|
5148
|
-
* ```
|
|
5149
|
-
*
|
|
5150
|
-
* @param current
|
|
5151
|
-
*/
|
|
5152
|
-
const cssVariableRegex = /var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/;
|
|
5153
|
-
function parseCSSVariable(current) {
|
|
5154
|
-
const match = cssVariableRegex.exec(current);
|
|
5155
|
-
if (!match)
|
|
5156
|
-
return [,];
|
|
5157
|
-
const [, token, fallback] = match;
|
|
5158
|
-
return [token, fallback];
|
|
5159
|
-
}
|
|
5160
|
-
const maxDepth = 4;
|
|
5161
|
-
function getVariableValue(current, element, depth = 1) {
|
|
5162
|
-
wrap.invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`);
|
|
5163
|
-
const [token, fallback] = parseCSSVariable(current);
|
|
5164
|
-
// No CSS variable detected
|
|
5165
|
-
if (!token)
|
|
5166
|
-
return;
|
|
5167
|
-
// Attempt to read this CSS variable off the element
|
|
5168
|
-
const resolved = window.getComputedStyle(element).getPropertyValue(token);
|
|
5169
|
-
if (resolved) {
|
|
5170
|
-
return resolved.trim();
|
|
5171
|
-
}
|
|
5172
|
-
else if (isCSSVariableToken(fallback)) {
|
|
5173
|
-
// The fallback might itself be a CSS variable, in which case we attempt to resolve it too.
|
|
5174
|
-
return getVariableValue(fallback, element, depth + 1);
|
|
5175
|
-
}
|
|
5176
|
-
else {
|
|
5177
|
-
return fallback;
|
|
5178
|
-
}
|
|
5179
|
-
}
|
|
5180
|
-
/**
|
|
5181
|
-
* Resolve CSS variables from
|
|
5182
|
-
*
|
|
5183
|
-
* @internal
|
|
5184
|
-
*/
|
|
5185
|
-
function resolveCSSVariables(visualElement, { ...target }, transitionEnd) {
|
|
5186
|
-
const element = visualElement.current;
|
|
5187
|
-
if (!(element instanceof Element))
|
|
5188
|
-
return { target, transitionEnd };
|
|
5189
|
-
// If `transitionEnd` isn't `undefined`, clone it. We could clone `target` and `transitionEnd`
|
|
5190
|
-
// only if they change but I think this reads clearer and this isn't a performance-critical path.
|
|
5191
|
-
if (transitionEnd) {
|
|
5192
|
-
transitionEnd = { ...transitionEnd };
|
|
5193
|
-
}
|
|
5194
|
-
// Go through existing `MotionValue`s and ensure any existing CSS variables are resolved
|
|
5195
|
-
visualElement.values.forEach((value) => {
|
|
5196
|
-
const current = value.get();
|
|
5197
|
-
if (!isCSSVariableToken(current))
|
|
5198
|
-
return;
|
|
5199
|
-
const resolved = getVariableValue(current, element);
|
|
5200
|
-
if (resolved)
|
|
5201
|
-
value.set(resolved);
|
|
5202
|
-
});
|
|
5203
|
-
// Cycle through every target property and resolve CSS variables. Currently
|
|
5204
|
-
// we only read single-var properties like `var(--foo)`, not `calc(var(--foo) + 20px)`
|
|
5205
|
-
for (const key in target) {
|
|
5206
|
-
const current = target[key];
|
|
5207
|
-
if (!isCSSVariableToken(current))
|
|
5208
|
-
continue;
|
|
5209
|
-
const resolved = getVariableValue(current, element);
|
|
5210
|
-
if (!resolved)
|
|
5211
|
-
continue;
|
|
5212
|
-
// Clone target if it hasn't already been
|
|
5213
|
-
target[key] = resolved;
|
|
5214
|
-
if (!transitionEnd)
|
|
5215
|
-
transitionEnd = {};
|
|
5216
|
-
// If the user hasn't already set this key on `transitionEnd`, set it to the unresolved
|
|
5217
|
-
// CSS variable. This will ensure that after the animation the component will reflect
|
|
5218
|
-
// changes in the value of the CSS variable.
|
|
5219
|
-
if (transitionEnd[key] === undefined) {
|
|
5220
|
-
transitionEnd[key] = current;
|
|
5221
|
-
}
|
|
5222
|
-
}
|
|
5223
|
-
return { target, transitionEnd };
|
|
5224
|
-
}
|
|
5225
|
-
|
|
5226
4301
|
const varToken = "_$css";
|
|
5227
4302
|
const correctBoxShadow = {
|
|
5228
4303
|
correct: (latest, { treeScale, projectionDelta }) => {
|
|
@@ -5233,7 +4308,7 @@ const correctBoxShadow = {
|
|
|
5233
4308
|
const containsCSSVariables = latest.includes("var(");
|
|
5234
4309
|
const cssVariables = [];
|
|
5235
4310
|
if (containsCSSVariables) {
|
|
5236
|
-
latest = latest.replace(cssVariableRegex, (match) => {
|
|
4311
|
+
latest = latest.replace(wrap.cssVariableRegex, (match) => {
|
|
5237
4312
|
cssVariables.push(match);
|
|
5238
4313
|
return varToken;
|
|
5239
4314
|
});
|
|
@@ -5275,873 +4350,6 @@ const correctBoxShadow = {
|
|
|
5275
4350
|
},
|
|
5276
4351
|
};
|
|
5277
4352
|
|
|
5278
|
-
const positionalKeys = new Set([
|
|
5279
|
-
"width",
|
|
5280
|
-
"height",
|
|
5281
|
-
"top",
|
|
5282
|
-
"left",
|
|
5283
|
-
"right",
|
|
5284
|
-
"bottom",
|
|
5285
|
-
"x",
|
|
5286
|
-
"y",
|
|
5287
|
-
]);
|
|
5288
|
-
const isPositionalKey = (key) => positionalKeys.has(key);
|
|
5289
|
-
const hasPositionalKey = (target) => {
|
|
5290
|
-
return Object.keys(target).some(isPositionalKey);
|
|
5291
|
-
};
|
|
5292
|
-
const isNumOrPxType = (v) => v === wrap.number || v === wrap.px;
|
|
5293
|
-
const getPosFromMatrix = (matrix, pos) => parseFloat(matrix.split(", ")[pos]);
|
|
5294
|
-
const getTranslateFromMatrix = (pos2, pos3) => (_bbox, { transform }) => {
|
|
5295
|
-
if (transform === "none" || !transform)
|
|
5296
|
-
return 0;
|
|
5297
|
-
const matrix3d = transform.match(/^matrix3d\((.+)\)$/);
|
|
5298
|
-
if (matrix3d) {
|
|
5299
|
-
return getPosFromMatrix(matrix3d[1], pos3);
|
|
5300
|
-
}
|
|
5301
|
-
else {
|
|
5302
|
-
const matrix = transform.match(/^matrix\((.+)\)$/);
|
|
5303
|
-
if (matrix) {
|
|
5304
|
-
return getPosFromMatrix(matrix[1], pos2);
|
|
5305
|
-
}
|
|
5306
|
-
else {
|
|
5307
|
-
return 0;
|
|
5308
|
-
}
|
|
5309
|
-
}
|
|
5310
|
-
};
|
|
5311
|
-
const transformKeys = new Set(["x", "y", "z"]);
|
|
5312
|
-
const nonTranslationalTransformKeys = wrap.transformPropOrder.filter((key) => !transformKeys.has(key));
|
|
5313
|
-
function removeNonTranslationalTransform(visualElement) {
|
|
5314
|
-
const removedTransforms = [];
|
|
5315
|
-
nonTranslationalTransformKeys.forEach((key) => {
|
|
5316
|
-
const value = visualElement.getValue(key);
|
|
5317
|
-
if (value !== undefined) {
|
|
5318
|
-
removedTransforms.push([key, value.get()]);
|
|
5319
|
-
value.set(key.startsWith("scale") ? 1 : 0);
|
|
5320
|
-
}
|
|
5321
|
-
});
|
|
5322
|
-
// Apply changes to element before measurement
|
|
5323
|
-
if (removedTransforms.length)
|
|
5324
|
-
visualElement.render();
|
|
5325
|
-
return removedTransforms;
|
|
5326
|
-
}
|
|
5327
|
-
const positionalValues = {
|
|
5328
|
-
// Dimensions
|
|
5329
|
-
width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) => x.max - x.min - parseFloat(paddingLeft) - parseFloat(paddingRight),
|
|
5330
|
-
height: ({ y }, { paddingTop = "0", paddingBottom = "0" }) => y.max - y.min - parseFloat(paddingTop) - parseFloat(paddingBottom),
|
|
5331
|
-
top: (_bbox, { top }) => parseFloat(top),
|
|
5332
|
-
left: (_bbox, { left }) => parseFloat(left),
|
|
5333
|
-
bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
|
|
5334
|
-
right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
|
|
5335
|
-
// Transform
|
|
5336
|
-
x: getTranslateFromMatrix(4, 13),
|
|
5337
|
-
y: getTranslateFromMatrix(5, 14),
|
|
5338
|
-
};
|
|
5339
|
-
const convertChangedValueTypes = (target, visualElement, changedKeys) => {
|
|
5340
|
-
const originBbox = visualElement.measureViewportBox();
|
|
5341
|
-
const element = visualElement.current;
|
|
5342
|
-
const elementComputedStyle = getComputedStyle(element);
|
|
5343
|
-
const { display } = elementComputedStyle;
|
|
5344
|
-
const origin = {};
|
|
5345
|
-
// If the element is currently set to display: "none", make it visible before
|
|
5346
|
-
// measuring the target bounding box
|
|
5347
|
-
if (display === "none") {
|
|
5348
|
-
visualElement.setStaticValue("display", target.display || "block");
|
|
5349
|
-
}
|
|
5350
|
-
/**
|
|
5351
|
-
* Record origins before we render and update styles
|
|
5352
|
-
*/
|
|
5353
|
-
changedKeys.forEach((key) => {
|
|
5354
|
-
origin[key] = positionalValues[key](originBbox, elementComputedStyle);
|
|
5355
|
-
});
|
|
5356
|
-
// Apply the latest values (as set in checkAndConvertChangedValueTypes)
|
|
5357
|
-
visualElement.render();
|
|
5358
|
-
const targetBbox = visualElement.measureViewportBox();
|
|
5359
|
-
changedKeys.forEach((key) => {
|
|
5360
|
-
// Restore styles to their **calculated computed style**, not their actual
|
|
5361
|
-
// originally set style. This allows us to animate between equivalent pixel units.
|
|
5362
|
-
const value = visualElement.getValue(key);
|
|
5363
|
-
value && value.jump(origin[key]);
|
|
5364
|
-
target[key] = positionalValues[key](targetBbox, elementComputedStyle);
|
|
5365
|
-
});
|
|
5366
|
-
return target;
|
|
5367
|
-
};
|
|
5368
|
-
const checkAndConvertChangedValueTypes = (visualElement, target, origin = {}, transitionEnd = {}) => {
|
|
5369
|
-
target = { ...target };
|
|
5370
|
-
transitionEnd = { ...transitionEnd };
|
|
5371
|
-
const targetPositionalKeys = Object.keys(target).filter(isPositionalKey);
|
|
5372
|
-
// We want to remove any transform values that could affect the element's bounding box before
|
|
5373
|
-
// it's measured. We'll reapply these later.
|
|
5374
|
-
let removedTransformValues = [];
|
|
5375
|
-
let hasAttemptedToRemoveTransformValues = false;
|
|
5376
|
-
const changedValueTypeKeys = [];
|
|
5377
|
-
targetPositionalKeys.forEach((key) => {
|
|
5378
|
-
const value = visualElement.getValue(key);
|
|
5379
|
-
if (!visualElement.hasValue(key))
|
|
5380
|
-
return;
|
|
5381
|
-
let from = origin[key];
|
|
5382
|
-
let fromType = findDimensionValueType(from);
|
|
5383
|
-
const to = target[key];
|
|
5384
|
-
let toType;
|
|
5385
|
-
// TODO: The current implementation of this basically throws an error
|
|
5386
|
-
// if you try and do value conversion via keyframes. There's probably
|
|
5387
|
-
// a way of doing this but the performance implications would need greater scrutiny,
|
|
5388
|
-
// as it'd be doing multiple resize-remeasure operations.
|
|
5389
|
-
if (isKeyframesTarget(to)) {
|
|
5390
|
-
const numKeyframes = to.length;
|
|
5391
|
-
const fromIndex = to[0] === null ? 1 : 0;
|
|
5392
|
-
from = to[fromIndex];
|
|
5393
|
-
fromType = findDimensionValueType(from);
|
|
5394
|
-
for (let i = fromIndex; i < numKeyframes; i++) {
|
|
5395
|
-
if (!toType) {
|
|
5396
|
-
toType = findDimensionValueType(to[i]);
|
|
5397
|
-
wrap.invariant(toType === fromType ||
|
|
5398
|
-
(isNumOrPxType(fromType) && isNumOrPxType(toType)), "Keyframes must be of the same dimension as the current value");
|
|
5399
|
-
}
|
|
5400
|
-
else {
|
|
5401
|
-
wrap.invariant(findDimensionValueType(to[i]) === toType, "All keyframes must be of the same type");
|
|
5402
|
-
}
|
|
5403
|
-
}
|
|
5404
|
-
}
|
|
5405
|
-
else {
|
|
5406
|
-
toType = findDimensionValueType(to);
|
|
5407
|
-
}
|
|
5408
|
-
if (fromType !== toType) {
|
|
5409
|
-
// If they're both just number or px, convert them both to numbers rather than
|
|
5410
|
-
// relying on resize/remeasure to convert (which is wasteful in this situation)
|
|
5411
|
-
if (isNumOrPxType(fromType) && isNumOrPxType(toType)) {
|
|
5412
|
-
const current = value.get();
|
|
5413
|
-
if (typeof current === "string") {
|
|
5414
|
-
value.set(parseFloat(current));
|
|
5415
|
-
}
|
|
5416
|
-
if (typeof to === "string") {
|
|
5417
|
-
target[key] = parseFloat(to);
|
|
5418
|
-
}
|
|
5419
|
-
else if (Array.isArray(to) && toType === wrap.px) {
|
|
5420
|
-
target[key] = to.map(parseFloat);
|
|
5421
|
-
}
|
|
5422
|
-
}
|
|
5423
|
-
else if ((fromType === null || fromType === void 0 ? void 0 : fromType.transform) &&
|
|
5424
|
-
(toType === null || toType === void 0 ? void 0 : toType.transform) &&
|
|
5425
|
-
(from === 0 || to === 0)) {
|
|
5426
|
-
// If one or the other value is 0, it's safe to coerce it to the
|
|
5427
|
-
// type of the other without measurement
|
|
5428
|
-
if (from === 0) {
|
|
5429
|
-
value.set(toType.transform(from));
|
|
5430
|
-
}
|
|
5431
|
-
else {
|
|
5432
|
-
target[key] = fromType.transform(to);
|
|
5433
|
-
}
|
|
5434
|
-
}
|
|
5435
|
-
else {
|
|
5436
|
-
// If we're going to do value conversion via DOM measurements, we first
|
|
5437
|
-
// need to remove non-positional transform values that could affect the bbox measurements.
|
|
5438
|
-
if (!hasAttemptedToRemoveTransformValues) {
|
|
5439
|
-
removedTransformValues =
|
|
5440
|
-
removeNonTranslationalTransform(visualElement);
|
|
5441
|
-
hasAttemptedToRemoveTransformValues = true;
|
|
5442
|
-
}
|
|
5443
|
-
changedValueTypeKeys.push(key);
|
|
5444
|
-
transitionEnd[key] =
|
|
5445
|
-
transitionEnd[key] !== undefined
|
|
5446
|
-
? transitionEnd[key]
|
|
5447
|
-
: target[key];
|
|
5448
|
-
value.jump(to);
|
|
5449
|
-
}
|
|
5450
|
-
}
|
|
5451
|
-
});
|
|
5452
|
-
if (changedValueTypeKeys.length) {
|
|
5453
|
-
const scrollY = changedValueTypeKeys.indexOf("height") >= 0
|
|
5454
|
-
? window.pageYOffset
|
|
5455
|
-
: null;
|
|
5456
|
-
const convertedTarget = convertChangedValueTypes(target, visualElement, changedValueTypeKeys);
|
|
5457
|
-
// If we removed transform values, reapply them before the next render
|
|
5458
|
-
if (removedTransformValues.length) {
|
|
5459
|
-
removedTransformValues.forEach(([key, value]) => {
|
|
5460
|
-
visualElement.getValue(key).set(value);
|
|
5461
|
-
});
|
|
5462
|
-
}
|
|
5463
|
-
// Reapply original values
|
|
5464
|
-
visualElement.render();
|
|
5465
|
-
// Restore scroll position
|
|
5466
|
-
if (isBrowser && scrollY !== null) {
|
|
5467
|
-
window.scrollTo({ top: scrollY });
|
|
5468
|
-
}
|
|
5469
|
-
return { target: convertedTarget, transitionEnd };
|
|
5470
|
-
}
|
|
5471
|
-
else {
|
|
5472
|
-
return { target, transitionEnd };
|
|
5473
|
-
}
|
|
5474
|
-
};
|
|
5475
|
-
/**
|
|
5476
|
-
* Convert value types for x/y/width/height/top/left/bottom/right
|
|
5477
|
-
*
|
|
5478
|
-
* Allows animation between `'auto'` -> `'100%'` or `0` -> `'calc(50% - 10vw)'`
|
|
5479
|
-
*
|
|
5480
|
-
* @internal
|
|
5481
|
-
*/
|
|
5482
|
-
function unitConversion(visualElement, target, origin, transitionEnd) {
|
|
5483
|
-
return hasPositionalKey(target)
|
|
5484
|
-
? checkAndConvertChangedValueTypes(visualElement, target, origin, transitionEnd)
|
|
5485
|
-
: { target, transitionEnd };
|
|
5486
|
-
}
|
|
5487
|
-
|
|
5488
|
-
/**
|
|
5489
|
-
* Parse a DOM variant to make it animatable. This involves resolving CSS variables
|
|
5490
|
-
* and ensuring animations like "20%" => "calc(50vw)" are performed in pixels.
|
|
5491
|
-
*/
|
|
5492
|
-
const parseDomVariant = (visualElement, target, origin, transitionEnd) => {
|
|
5493
|
-
const resolved = resolveCSSVariables(visualElement, target, transitionEnd);
|
|
5494
|
-
target = resolved.target;
|
|
5495
|
-
transitionEnd = resolved.transitionEnd;
|
|
5496
|
-
return unitConversion(visualElement, target, origin, transitionEnd);
|
|
5497
|
-
};
|
|
5498
|
-
|
|
5499
|
-
// Does this device prefer reduced motion? Returns `null` server-side.
|
|
5500
|
-
const prefersReducedMotion = { current: null };
|
|
5501
|
-
const hasReducedMotionListener = { current: false };
|
|
5502
|
-
|
|
5503
|
-
function initPrefersReducedMotion() {
|
|
5504
|
-
hasReducedMotionListener.current = true;
|
|
5505
|
-
if (!isBrowser)
|
|
5506
|
-
return;
|
|
5507
|
-
if (window.matchMedia) {
|
|
5508
|
-
const motionMediaQuery = window.matchMedia("(prefers-reduced-motion)");
|
|
5509
|
-
const setReducedMotionPreferences = () => (prefersReducedMotion.current = motionMediaQuery.matches);
|
|
5510
|
-
motionMediaQuery.addListener(setReducedMotionPreferences);
|
|
5511
|
-
setReducedMotionPreferences();
|
|
5512
|
-
}
|
|
5513
|
-
else {
|
|
5514
|
-
prefersReducedMotion.current = false;
|
|
5515
|
-
}
|
|
5516
|
-
}
|
|
5517
|
-
|
|
5518
|
-
function updateMotionValuesFromProps(element, next, prev) {
|
|
5519
|
-
const { willChange } = next;
|
|
5520
|
-
for (const key in next) {
|
|
5521
|
-
const nextValue = next[key];
|
|
5522
|
-
const prevValue = prev[key];
|
|
5523
|
-
if (wrap.isMotionValue(nextValue)) {
|
|
5524
|
-
/**
|
|
5525
|
-
* If this is a motion value found in props or style, we want to add it
|
|
5526
|
-
* to our visual element's motion value map.
|
|
5527
|
-
*/
|
|
5528
|
-
element.addValue(key, nextValue);
|
|
5529
|
-
if (isWillChangeMotionValue(willChange)) {
|
|
5530
|
-
willChange.add(key);
|
|
5531
|
-
}
|
|
5532
|
-
/**
|
|
5533
|
-
* Check the version of the incoming motion value with this version
|
|
5534
|
-
* and warn against mismatches.
|
|
5535
|
-
*/
|
|
5536
|
-
if (process.env.NODE_ENV === "development") {
|
|
5537
|
-
wrap.warnOnce(nextValue.version === "10.3.4", `Attempting to mix Framer Motion versions ${nextValue.version} with 10.3.4 may not work as expected.`);
|
|
5538
|
-
}
|
|
5539
|
-
}
|
|
5540
|
-
else if (wrap.isMotionValue(prevValue)) {
|
|
5541
|
-
/**
|
|
5542
|
-
* If we're swapping from a motion value to a static value,
|
|
5543
|
-
* create a new motion value from that
|
|
5544
|
-
*/
|
|
5545
|
-
element.addValue(key, wrap.motionValue(nextValue, { owner: element }));
|
|
5546
|
-
if (isWillChangeMotionValue(willChange)) {
|
|
5547
|
-
willChange.remove(key);
|
|
5548
|
-
}
|
|
5549
|
-
}
|
|
5550
|
-
else if (prevValue !== nextValue) {
|
|
5551
|
-
/**
|
|
5552
|
-
* If this is a flat value that has changed, update the motion value
|
|
5553
|
-
* or create one if it doesn't exist. We only want to do this if we're
|
|
5554
|
-
* not handling the value with our animation state.
|
|
5555
|
-
*/
|
|
5556
|
-
if (element.hasValue(key)) {
|
|
5557
|
-
const existingValue = element.getValue(key);
|
|
5558
|
-
// TODO: Only update values that aren't being animated or even looked at
|
|
5559
|
-
!existingValue.hasAnimated && existingValue.set(nextValue);
|
|
5560
|
-
}
|
|
5561
|
-
else {
|
|
5562
|
-
const latestValue = element.getStaticValue(key);
|
|
5563
|
-
element.addValue(key, wrap.motionValue(latestValue !== undefined ? latestValue : nextValue, { owner: element }));
|
|
5564
|
-
}
|
|
5565
|
-
}
|
|
5566
|
-
}
|
|
5567
|
-
// Handle removed values
|
|
5568
|
-
for (const key in prev) {
|
|
5569
|
-
if (next[key] === undefined)
|
|
5570
|
-
element.removeValue(key);
|
|
5571
|
-
}
|
|
5572
|
-
return next;
|
|
5573
|
-
}
|
|
5574
|
-
|
|
5575
|
-
const featureNames = Object.keys(featureDefinitions);
|
|
5576
|
-
const numFeatures = featureNames.length;
|
|
5577
|
-
const propEventHandlers = [
|
|
5578
|
-
"AnimationStart",
|
|
5579
|
-
"AnimationComplete",
|
|
5580
|
-
"Update",
|
|
5581
|
-
"BeforeLayoutMeasure",
|
|
5582
|
-
"LayoutMeasure",
|
|
5583
|
-
"LayoutAnimationStart",
|
|
5584
|
-
"LayoutAnimationComplete",
|
|
5585
|
-
];
|
|
5586
|
-
const numVariantProps = variantProps.length;
|
|
5587
|
-
/**
|
|
5588
|
-
* A VisualElement is an imperative abstraction around UI elements such as
|
|
5589
|
-
* HTMLElement, SVGElement, Three.Object3D etc.
|
|
5590
|
-
*/
|
|
5591
|
-
class VisualElement {
|
|
5592
|
-
constructor({ parent, props, presenceContext, reducedMotionConfig, visualState, }, options = {}) {
|
|
5593
|
-
/**
|
|
5594
|
-
* A reference to the current underlying Instance, e.g. a HTMLElement
|
|
5595
|
-
* or Three.Mesh etc.
|
|
5596
|
-
*/
|
|
5597
|
-
this.current = null;
|
|
5598
|
-
/**
|
|
5599
|
-
* A set containing references to this VisualElement's children.
|
|
5600
|
-
*/
|
|
5601
|
-
this.children = new Set();
|
|
5602
|
-
/**
|
|
5603
|
-
* Determine what role this visual element should take in the variant tree.
|
|
5604
|
-
*/
|
|
5605
|
-
this.isVariantNode = false;
|
|
5606
|
-
this.isControllingVariants = false;
|
|
5607
|
-
/**
|
|
5608
|
-
* Decides whether this VisualElement should animate in reduced motion
|
|
5609
|
-
* mode.
|
|
5610
|
-
*
|
|
5611
|
-
* TODO: This is currently set on every individual VisualElement but feels
|
|
5612
|
-
* like it could be set globally.
|
|
5613
|
-
*/
|
|
5614
|
-
this.shouldReduceMotion = null;
|
|
5615
|
-
/**
|
|
5616
|
-
* A map of all motion values attached to this visual element. Motion
|
|
5617
|
-
* values are source of truth for any given animated value. A motion
|
|
5618
|
-
* value might be provided externally by the component via props.
|
|
5619
|
-
*/
|
|
5620
|
-
this.values = new Map();
|
|
5621
|
-
/**
|
|
5622
|
-
* Cleanup functions for active features (hover/tap/exit etc)
|
|
5623
|
-
*/
|
|
5624
|
-
this.features = {};
|
|
5625
|
-
/**
|
|
5626
|
-
* A map of every subscription that binds the provided or generated
|
|
5627
|
-
* motion values onChange listeners to this visual element.
|
|
5628
|
-
*/
|
|
5629
|
-
this.valueSubscriptions = new Map();
|
|
5630
|
-
/**
|
|
5631
|
-
* A reference to the previously-provided motion values as returned
|
|
5632
|
-
* from scrapeMotionValuesFromProps. We use the keys in here to determine
|
|
5633
|
-
* if any motion values need to be removed after props are updated.
|
|
5634
|
-
*/
|
|
5635
|
-
this.prevMotionValues = {};
|
|
5636
|
-
/**
|
|
5637
|
-
* An object containing a SubscriptionManager for each active event.
|
|
5638
|
-
*/
|
|
5639
|
-
this.events = {};
|
|
5640
|
-
/**
|
|
5641
|
-
* An object containing an unsubscribe function for each prop event subscription.
|
|
5642
|
-
* For example, every "Update" event can have multiple subscribers via
|
|
5643
|
-
* VisualElement.on(), but only one of those can be defined via the onUpdate prop.
|
|
5644
|
-
*/
|
|
5645
|
-
this.propEventSubscriptions = {};
|
|
5646
|
-
this.notifyUpdate = () => this.notify("Update", this.latestValues);
|
|
5647
|
-
this.render = () => {
|
|
5648
|
-
if (!this.current)
|
|
5649
|
-
return;
|
|
5650
|
-
this.triggerBuild();
|
|
5651
|
-
this.renderInstance(this.current, this.renderState, this.props.style, this.projection);
|
|
5652
|
-
};
|
|
5653
|
-
this.scheduleRender = () => wrap.sync.render(this.render, false, true);
|
|
5654
|
-
const { latestValues, renderState } = visualState;
|
|
5655
|
-
this.latestValues = latestValues;
|
|
5656
|
-
this.baseTarget = { ...latestValues };
|
|
5657
|
-
this.initialValues = props.initial ? { ...latestValues } : {};
|
|
5658
|
-
this.renderState = renderState;
|
|
5659
|
-
this.parent = parent;
|
|
5660
|
-
this.props = props;
|
|
5661
|
-
this.presenceContext = presenceContext;
|
|
5662
|
-
this.depth = parent ? parent.depth + 1 : 0;
|
|
5663
|
-
this.reducedMotionConfig = reducedMotionConfig;
|
|
5664
|
-
this.options = options;
|
|
5665
|
-
this.isControllingVariants = isControllingVariants(props);
|
|
5666
|
-
this.isVariantNode = isVariantNode(props);
|
|
5667
|
-
if (this.isVariantNode) {
|
|
5668
|
-
this.variantChildren = new Set();
|
|
5669
|
-
}
|
|
5670
|
-
this.manuallyAnimateOnMount = Boolean(parent && parent.current);
|
|
5671
|
-
/**
|
|
5672
|
-
* Any motion values that are provided to the element when created
|
|
5673
|
-
* aren't yet bound to the element, as this would technically be impure.
|
|
5674
|
-
* However, we iterate through the motion values and set them to the
|
|
5675
|
-
* initial values for this component.
|
|
5676
|
-
*
|
|
5677
|
-
* TODO: This is impure and we should look at changing this to run on mount.
|
|
5678
|
-
* Doing so will break some tests but this isn't neccessarily a breaking change,
|
|
5679
|
-
* more a reflection of the test.
|
|
5680
|
-
*/
|
|
5681
|
-
const { willChange, ...initialMotionValues } = this.scrapeMotionValuesFromProps(props, {});
|
|
5682
|
-
for (const key in initialMotionValues) {
|
|
5683
|
-
const value = initialMotionValues[key];
|
|
5684
|
-
if (latestValues[key] !== undefined && wrap.isMotionValue(value)) {
|
|
5685
|
-
value.set(latestValues[key], false);
|
|
5686
|
-
if (isWillChangeMotionValue(willChange)) {
|
|
5687
|
-
willChange.add(key);
|
|
5688
|
-
}
|
|
5689
|
-
}
|
|
5690
|
-
}
|
|
5691
|
-
}
|
|
5692
|
-
/**
|
|
5693
|
-
* This method takes React props and returns found MotionValues. For example, HTML
|
|
5694
|
-
* MotionValues will be found within the style prop, whereas for Three.js within attribute arrays.
|
|
5695
|
-
*
|
|
5696
|
-
* This isn't an abstract method as it needs calling in the constructor, but it is
|
|
5697
|
-
* intended to be one.
|
|
5698
|
-
*/
|
|
5699
|
-
scrapeMotionValuesFromProps(_props, _prevProps) {
|
|
5700
|
-
return {};
|
|
5701
|
-
}
|
|
5702
|
-
mount(instance) {
|
|
5703
|
-
this.current = instance;
|
|
5704
|
-
if (this.projection) {
|
|
5705
|
-
this.projection.mount(instance);
|
|
5706
|
-
}
|
|
5707
|
-
if (this.parent && this.isVariantNode && !this.isControllingVariants) {
|
|
5708
|
-
this.removeFromVariantTree = this.parent.addVariantChild(this);
|
|
5709
|
-
}
|
|
5710
|
-
this.values.forEach((value, key) => this.bindToMotionValue(key, value));
|
|
5711
|
-
if (!hasReducedMotionListener.current) {
|
|
5712
|
-
initPrefersReducedMotion();
|
|
5713
|
-
}
|
|
5714
|
-
this.shouldReduceMotion =
|
|
5715
|
-
this.reducedMotionConfig === "never"
|
|
5716
|
-
? false
|
|
5717
|
-
: this.reducedMotionConfig === "always"
|
|
5718
|
-
? true
|
|
5719
|
-
: prefersReducedMotion.current;
|
|
5720
|
-
if (process.env.NODE_ENV !== "production") {
|
|
5721
|
-
wrap.warnOnce(this.shouldReduceMotion !== true, "You have Reduced Motion enabled on your device. Animations may not appear as expected.");
|
|
5722
|
-
}
|
|
5723
|
-
if (this.parent)
|
|
5724
|
-
this.parent.children.add(this);
|
|
5725
|
-
this.update(this.props, this.presenceContext);
|
|
5726
|
-
}
|
|
5727
|
-
unmount() {
|
|
5728
|
-
this.projection && this.projection.unmount();
|
|
5729
|
-
wrap.cancelSync.update(this.notifyUpdate);
|
|
5730
|
-
wrap.cancelSync.render(this.render);
|
|
5731
|
-
this.valueSubscriptions.forEach((remove) => remove());
|
|
5732
|
-
this.removeFromVariantTree && this.removeFromVariantTree();
|
|
5733
|
-
this.parent && this.parent.children.delete(this);
|
|
5734
|
-
for (const key in this.events) {
|
|
5735
|
-
this.events[key].clear();
|
|
5736
|
-
}
|
|
5737
|
-
for (const key in this.features) {
|
|
5738
|
-
this.features[key].unmount();
|
|
5739
|
-
}
|
|
5740
|
-
this.current = null;
|
|
5741
|
-
}
|
|
5742
|
-
bindToMotionValue(key, value) {
|
|
5743
|
-
const valueIsTransform = wrap.transformProps.has(key);
|
|
5744
|
-
const removeOnChange = value.on("change", (latestValue) => {
|
|
5745
|
-
this.latestValues[key] = latestValue;
|
|
5746
|
-
this.props.onUpdate &&
|
|
5747
|
-
wrap.sync.update(this.notifyUpdate, false, true);
|
|
5748
|
-
if (valueIsTransform && this.projection) {
|
|
5749
|
-
this.projection.isTransformDirty = true;
|
|
5750
|
-
}
|
|
5751
|
-
});
|
|
5752
|
-
const removeOnRenderRequest = value.on("renderRequest", this.scheduleRender);
|
|
5753
|
-
this.valueSubscriptions.set(key, () => {
|
|
5754
|
-
removeOnChange();
|
|
5755
|
-
removeOnRenderRequest();
|
|
5756
|
-
});
|
|
5757
|
-
}
|
|
5758
|
-
sortNodePosition(other) {
|
|
5759
|
-
/**
|
|
5760
|
-
* If these nodes aren't even of the same type we can't compare their depth.
|
|
5761
|
-
*/
|
|
5762
|
-
if (!this.current ||
|
|
5763
|
-
!this.sortInstanceNodePosition ||
|
|
5764
|
-
this.type !== other.type) {
|
|
5765
|
-
return 0;
|
|
5766
|
-
}
|
|
5767
|
-
return this.sortInstanceNodePosition(this.current, other.current);
|
|
5768
|
-
}
|
|
5769
|
-
loadFeatures({ children, ...renderedProps }, isStrict, preloadedFeatures, projectionId, initialLayoutGroupConfig) {
|
|
5770
|
-
let ProjectionNodeConstructor;
|
|
5771
|
-
let MeasureLayout;
|
|
5772
|
-
/**
|
|
5773
|
-
* If we're in development mode, check to make sure we're not rendering a motion component
|
|
5774
|
-
* as a child of LazyMotion, as this will break the file-size benefits of using it.
|
|
5775
|
-
*/
|
|
5776
|
-
if (process.env.NODE_ENV !== "production" &&
|
|
5777
|
-
preloadedFeatures &&
|
|
5778
|
-
isStrict) {
|
|
5779
|
-
const strictMessage = "You have rendered a `motion` component within a `LazyMotion` component. This will break tree shaking. Import and render a `m` component instead.";
|
|
5780
|
-
renderedProps.ignoreStrict
|
|
5781
|
-
? wrap.warning(false, strictMessage)
|
|
5782
|
-
: wrap.invariant(false, strictMessage);
|
|
5783
|
-
}
|
|
5784
|
-
for (let i = 0; i < numFeatures; i++) {
|
|
5785
|
-
const name = featureNames[i];
|
|
5786
|
-
const { isEnabled, Feature: FeatureConstructor, ProjectionNode, MeasureLayout: MeasureLayoutComponent, } = featureDefinitions[name];
|
|
5787
|
-
if (ProjectionNode)
|
|
5788
|
-
ProjectionNodeConstructor = ProjectionNode;
|
|
5789
|
-
if (isEnabled(renderedProps)) {
|
|
5790
|
-
if (!this.features[name] && FeatureConstructor) {
|
|
5791
|
-
this.features[name] = new FeatureConstructor(this);
|
|
5792
|
-
}
|
|
5793
|
-
if (MeasureLayoutComponent) {
|
|
5794
|
-
MeasureLayout = MeasureLayoutComponent;
|
|
5795
|
-
}
|
|
5796
|
-
}
|
|
5797
|
-
}
|
|
5798
|
-
if (!this.projection && ProjectionNodeConstructor) {
|
|
5799
|
-
this.projection = new ProjectionNodeConstructor(projectionId, this.latestValues, this.parent && this.parent.projection);
|
|
5800
|
-
const { layoutId, layout, drag, dragConstraints, layoutScroll, layoutRoot, } = renderedProps;
|
|
5801
|
-
this.projection.setOptions({
|
|
5802
|
-
layoutId,
|
|
5803
|
-
layout,
|
|
5804
|
-
alwaysMeasureLayout: Boolean(drag) ||
|
|
5805
|
-
(dragConstraints && isRefObject(dragConstraints)),
|
|
5806
|
-
visualElement: this,
|
|
5807
|
-
scheduleRender: () => this.scheduleRender(),
|
|
5808
|
-
/**
|
|
5809
|
-
* TODO: Update options in an effect. This could be tricky as it'll be too late
|
|
5810
|
-
* to update by the time layout animations run.
|
|
5811
|
-
* We also need to fix this safeToRemove by linking it up to the one returned by usePresence,
|
|
5812
|
-
* ensuring it gets called if there's no potential layout animations.
|
|
5813
|
-
*
|
|
5814
|
-
*/
|
|
5815
|
-
animationType: typeof layout === "string" ? layout : "both",
|
|
5816
|
-
initialPromotionConfig: initialLayoutGroupConfig,
|
|
5817
|
-
layoutScroll,
|
|
5818
|
-
layoutRoot,
|
|
5819
|
-
});
|
|
5820
|
-
}
|
|
5821
|
-
return MeasureLayout;
|
|
5822
|
-
}
|
|
5823
|
-
updateFeatures() {
|
|
5824
|
-
for (const key in this.features) {
|
|
5825
|
-
const feature = this.features[key];
|
|
5826
|
-
if (feature.isMounted) {
|
|
5827
|
-
feature.update(this.props, this.prevProps);
|
|
5828
|
-
}
|
|
5829
|
-
else {
|
|
5830
|
-
feature.mount();
|
|
5831
|
-
feature.isMounted = true;
|
|
5832
|
-
}
|
|
5833
|
-
}
|
|
5834
|
-
}
|
|
5835
|
-
triggerBuild() {
|
|
5836
|
-
this.build(this.renderState, this.latestValues, this.options, this.props);
|
|
5837
|
-
}
|
|
5838
|
-
/**
|
|
5839
|
-
* Measure the current viewport box with or without transforms.
|
|
5840
|
-
* Only measures axis-aligned boxes, rotate and skew must be manually
|
|
5841
|
-
* removed with a re-render to work.
|
|
5842
|
-
*/
|
|
5843
|
-
measureViewportBox() {
|
|
5844
|
-
return this.current
|
|
5845
|
-
? this.measureInstanceViewportBox(this.current, this.props)
|
|
5846
|
-
: createBox();
|
|
5847
|
-
}
|
|
5848
|
-
getStaticValue(key) {
|
|
5849
|
-
return this.latestValues[key];
|
|
5850
|
-
}
|
|
5851
|
-
setStaticValue(key, value) {
|
|
5852
|
-
this.latestValues[key] = value;
|
|
5853
|
-
}
|
|
5854
|
-
/**
|
|
5855
|
-
* Make a target animatable by Popmotion. For instance, if we're
|
|
5856
|
-
* trying to animate width from 100px to 100vw we need to measure 100vw
|
|
5857
|
-
* in pixels to determine what we really need to animate to. This is also
|
|
5858
|
-
* pluggable to support Framer's custom value types like Color,
|
|
5859
|
-
* and CSS variables.
|
|
5860
|
-
*/
|
|
5861
|
-
makeTargetAnimatable(target, canMutate = true) {
|
|
5862
|
-
return this.makeTargetAnimatableFromInstance(target, this.props, canMutate);
|
|
5863
|
-
}
|
|
5864
|
-
/**
|
|
5865
|
-
* Update the provided props. Ensure any newly-added motion values are
|
|
5866
|
-
* added to our map, old ones removed, and listeners updated.
|
|
5867
|
-
*/
|
|
5868
|
-
update(props, presenceContext) {
|
|
5869
|
-
if (props.transformTemplate || this.props.transformTemplate) {
|
|
5870
|
-
this.scheduleRender();
|
|
5871
|
-
}
|
|
5872
|
-
this.prevProps = this.props;
|
|
5873
|
-
this.props = props;
|
|
5874
|
-
this.prevPresenceContext = this.presenceContext;
|
|
5875
|
-
this.presenceContext = presenceContext;
|
|
5876
|
-
/**
|
|
5877
|
-
* Update prop event handlers ie onAnimationStart, onAnimationComplete
|
|
5878
|
-
*/
|
|
5879
|
-
for (let i = 0; i < propEventHandlers.length; i++) {
|
|
5880
|
-
const key = propEventHandlers[i];
|
|
5881
|
-
if (this.propEventSubscriptions[key]) {
|
|
5882
|
-
this.propEventSubscriptions[key]();
|
|
5883
|
-
delete this.propEventSubscriptions[key];
|
|
5884
|
-
}
|
|
5885
|
-
const listener = props["on" + key];
|
|
5886
|
-
if (listener) {
|
|
5887
|
-
this.propEventSubscriptions[key] = this.on(key, listener);
|
|
5888
|
-
}
|
|
5889
|
-
}
|
|
5890
|
-
this.prevMotionValues = updateMotionValuesFromProps(this, this.scrapeMotionValuesFromProps(props, this.prevProps), this.prevMotionValues);
|
|
5891
|
-
if (this.handleChildMotionValue) {
|
|
5892
|
-
this.handleChildMotionValue();
|
|
5893
|
-
}
|
|
5894
|
-
}
|
|
5895
|
-
getProps() {
|
|
5896
|
-
return this.props;
|
|
5897
|
-
}
|
|
5898
|
-
/**
|
|
5899
|
-
* Returns the variant definition with a given name.
|
|
5900
|
-
*/
|
|
5901
|
-
getVariant(name) {
|
|
5902
|
-
return this.props.variants ? this.props.variants[name] : undefined;
|
|
5903
|
-
}
|
|
5904
|
-
/**
|
|
5905
|
-
* Returns the defined default transition on this component.
|
|
5906
|
-
*/
|
|
5907
|
-
getDefaultTransition() {
|
|
5908
|
-
return this.props.transition;
|
|
5909
|
-
}
|
|
5910
|
-
getTransformPagePoint() {
|
|
5911
|
-
return this.props.transformPagePoint;
|
|
5912
|
-
}
|
|
5913
|
-
getClosestVariantNode() {
|
|
5914
|
-
return this.isVariantNode
|
|
5915
|
-
? this
|
|
5916
|
-
: this.parent
|
|
5917
|
-
? this.parent.getClosestVariantNode()
|
|
5918
|
-
: undefined;
|
|
5919
|
-
}
|
|
5920
|
-
getVariantContext(startAtParent = false) {
|
|
5921
|
-
if (startAtParent) {
|
|
5922
|
-
return this.parent ? this.parent.getVariantContext() : undefined;
|
|
5923
|
-
}
|
|
5924
|
-
if (!this.isControllingVariants) {
|
|
5925
|
-
const context = this.parent
|
|
5926
|
-
? this.parent.getVariantContext() || {}
|
|
5927
|
-
: {};
|
|
5928
|
-
if (this.props.initial !== undefined) {
|
|
5929
|
-
context.initial = this.props.initial;
|
|
5930
|
-
}
|
|
5931
|
-
return context;
|
|
5932
|
-
}
|
|
5933
|
-
const context = {};
|
|
5934
|
-
for (let i = 0; i < numVariantProps; i++) {
|
|
5935
|
-
const name = variantProps[i];
|
|
5936
|
-
const prop = this.props[name];
|
|
5937
|
-
if (isVariantLabel(prop) || prop === false) {
|
|
5938
|
-
context[name] = prop;
|
|
5939
|
-
}
|
|
5940
|
-
}
|
|
5941
|
-
return context;
|
|
5942
|
-
}
|
|
5943
|
-
/**
|
|
5944
|
-
* Add a child visual element to our set of children.
|
|
5945
|
-
*/
|
|
5946
|
-
addVariantChild(child) {
|
|
5947
|
-
const closestVariantNode = this.getClosestVariantNode();
|
|
5948
|
-
if (closestVariantNode) {
|
|
5949
|
-
closestVariantNode.variantChildren &&
|
|
5950
|
-
closestVariantNode.variantChildren.add(child);
|
|
5951
|
-
return () => closestVariantNode.variantChildren.delete(child);
|
|
5952
|
-
}
|
|
5953
|
-
}
|
|
5954
|
-
/**
|
|
5955
|
-
* Add a motion value and bind it to this visual element.
|
|
5956
|
-
*/
|
|
5957
|
-
addValue(key, value) {
|
|
5958
|
-
// Remove existing value if it exists
|
|
5959
|
-
if (value !== this.values.get(key)) {
|
|
5960
|
-
this.removeValue(key);
|
|
5961
|
-
this.bindToMotionValue(key, value);
|
|
5962
|
-
}
|
|
5963
|
-
this.values.set(key, value);
|
|
5964
|
-
this.latestValues[key] = value.get();
|
|
5965
|
-
}
|
|
5966
|
-
/**
|
|
5967
|
-
* Remove a motion value and unbind any active subscriptions.
|
|
5968
|
-
*/
|
|
5969
|
-
removeValue(key) {
|
|
5970
|
-
this.values.delete(key);
|
|
5971
|
-
const unsubscribe = this.valueSubscriptions.get(key);
|
|
5972
|
-
if (unsubscribe) {
|
|
5973
|
-
unsubscribe();
|
|
5974
|
-
this.valueSubscriptions.delete(key);
|
|
5975
|
-
}
|
|
5976
|
-
delete this.latestValues[key];
|
|
5977
|
-
this.removeValueFromRenderState(key, this.renderState);
|
|
5978
|
-
}
|
|
5979
|
-
/**
|
|
5980
|
-
* Check whether we have a motion value for this key
|
|
5981
|
-
*/
|
|
5982
|
-
hasValue(key) {
|
|
5983
|
-
return this.values.has(key);
|
|
5984
|
-
}
|
|
5985
|
-
getValue(key, defaultValue) {
|
|
5986
|
-
if (this.props.values && this.props.values[key]) {
|
|
5987
|
-
return this.props.values[key];
|
|
5988
|
-
}
|
|
5989
|
-
let value = this.values.get(key);
|
|
5990
|
-
if (value === undefined && defaultValue !== undefined) {
|
|
5991
|
-
value = wrap.motionValue(defaultValue, { owner: this });
|
|
5992
|
-
this.addValue(key, value);
|
|
5993
|
-
}
|
|
5994
|
-
return value;
|
|
5995
|
-
}
|
|
5996
|
-
/**
|
|
5997
|
-
* If we're trying to animate to a previously unencountered value,
|
|
5998
|
-
* we need to check for it in our state and as a last resort read it
|
|
5999
|
-
* directly from the instance (which might have performance implications).
|
|
6000
|
-
*/
|
|
6001
|
-
readValue(key) {
|
|
6002
|
-
return this.latestValues[key] !== undefined || !this.current
|
|
6003
|
-
? this.latestValues[key]
|
|
6004
|
-
: this.readValueFromInstance(this.current, key, this.options);
|
|
6005
|
-
}
|
|
6006
|
-
/**
|
|
6007
|
-
* Set the base target to later animate back to. This is currently
|
|
6008
|
-
* only hydrated on creation and when we first read a value.
|
|
6009
|
-
*/
|
|
6010
|
-
setBaseTarget(key, value) {
|
|
6011
|
-
this.baseTarget[key] = value;
|
|
6012
|
-
}
|
|
6013
|
-
/**
|
|
6014
|
-
* Find the base target for a value thats been removed from all animation
|
|
6015
|
-
* props.
|
|
6016
|
-
*/
|
|
6017
|
-
getBaseTarget(key) {
|
|
6018
|
-
var _a;
|
|
6019
|
-
const { initial } = this.props;
|
|
6020
|
-
const valueFromInitial = typeof initial === "string" || typeof initial === "object"
|
|
6021
|
-
? (_a = resolveVariantFromProps(this.props, initial)) === null || _a === void 0 ? void 0 : _a[key]
|
|
6022
|
-
: undefined;
|
|
6023
|
-
/**
|
|
6024
|
-
* If this value still exists in the current initial variant, read that.
|
|
6025
|
-
*/
|
|
6026
|
-
if (initial && valueFromInitial !== undefined) {
|
|
6027
|
-
return valueFromInitial;
|
|
6028
|
-
}
|
|
6029
|
-
/**
|
|
6030
|
-
* Alternatively, if this VisualElement config has defined a getBaseTarget
|
|
6031
|
-
* so we can read the value from an alternative source, try that.
|
|
6032
|
-
*/
|
|
6033
|
-
const target = this.getBaseTargetFromProps(this.props, key);
|
|
6034
|
-
if (target !== undefined && !wrap.isMotionValue(target))
|
|
6035
|
-
return target;
|
|
6036
|
-
/**
|
|
6037
|
-
* If the value was initially defined on initial, but it doesn't any more,
|
|
6038
|
-
* return undefined. Otherwise return the value as initially read from the DOM.
|
|
6039
|
-
*/
|
|
6040
|
-
return this.initialValues[key] !== undefined &&
|
|
6041
|
-
valueFromInitial === undefined
|
|
6042
|
-
? undefined
|
|
6043
|
-
: this.baseTarget[key];
|
|
6044
|
-
}
|
|
6045
|
-
on(eventName, callback) {
|
|
6046
|
-
if (!this.events[eventName]) {
|
|
6047
|
-
this.events[eventName] = new wrap.SubscriptionManager();
|
|
6048
|
-
}
|
|
6049
|
-
return this.events[eventName].add(callback);
|
|
6050
|
-
}
|
|
6051
|
-
notify(eventName, ...args) {
|
|
6052
|
-
if (this.events[eventName]) {
|
|
6053
|
-
this.events[eventName].notify(...args);
|
|
6054
|
-
}
|
|
6055
|
-
}
|
|
6056
|
-
}
|
|
6057
|
-
|
|
6058
|
-
class DOMVisualElement extends VisualElement {
|
|
6059
|
-
sortInstanceNodePosition(a, b) {
|
|
6060
|
-
/**
|
|
6061
|
-
* compareDocumentPosition returns a bitmask, by using the bitwise &
|
|
6062
|
-
* we're returning true if 2 in that bitmask is set to true. 2 is set
|
|
6063
|
-
* to true if b preceeds a.
|
|
6064
|
-
*/
|
|
6065
|
-
return a.compareDocumentPosition(b) & 2 ? 1 : -1;
|
|
6066
|
-
}
|
|
6067
|
-
getBaseTargetFromProps(props, key) {
|
|
6068
|
-
return props.style ? props.style[key] : undefined;
|
|
6069
|
-
}
|
|
6070
|
-
removeValueFromRenderState(key, { vars, style }) {
|
|
6071
|
-
delete vars[key];
|
|
6072
|
-
delete style[key];
|
|
6073
|
-
}
|
|
6074
|
-
makeTargetAnimatableFromInstance({ transition, transitionEnd, ...target }, { transformValues }, isMounted) {
|
|
6075
|
-
let origin = getOrigin(target, transition || {}, this);
|
|
6076
|
-
/**
|
|
6077
|
-
* If Framer has provided a function to convert `Color` etc value types, convert them
|
|
6078
|
-
*/
|
|
6079
|
-
if (transformValues) {
|
|
6080
|
-
if (transitionEnd)
|
|
6081
|
-
transitionEnd = transformValues(transitionEnd);
|
|
6082
|
-
if (target)
|
|
6083
|
-
target = transformValues(target);
|
|
6084
|
-
if (origin)
|
|
6085
|
-
origin = transformValues(origin);
|
|
6086
|
-
}
|
|
6087
|
-
if (isMounted) {
|
|
6088
|
-
checkTargetForNewValues(this, target, origin);
|
|
6089
|
-
const parsed = parseDomVariant(this, target, origin, transitionEnd);
|
|
6090
|
-
transitionEnd = parsed.transitionEnd;
|
|
6091
|
-
target = parsed.target;
|
|
6092
|
-
}
|
|
6093
|
-
return {
|
|
6094
|
-
transition,
|
|
6095
|
-
transitionEnd,
|
|
6096
|
-
...target,
|
|
6097
|
-
};
|
|
6098
|
-
}
|
|
6099
|
-
}
|
|
6100
|
-
|
|
6101
|
-
function getComputedStyle$1(element) {
|
|
6102
|
-
return window.getComputedStyle(element);
|
|
6103
|
-
}
|
|
6104
|
-
class HTMLVisualElement extends DOMVisualElement {
|
|
6105
|
-
readValueFromInstance(instance, key) {
|
|
6106
|
-
if (wrap.transformProps.has(key)) {
|
|
6107
|
-
const defaultType = wrap.getDefaultValueType(key);
|
|
6108
|
-
return defaultType ? defaultType.default || 0 : 0;
|
|
6109
|
-
}
|
|
6110
|
-
else {
|
|
6111
|
-
const computedStyle = getComputedStyle$1(instance);
|
|
6112
|
-
const value = (isCSSVariableName(key)
|
|
6113
|
-
? computedStyle.getPropertyValue(key)
|
|
6114
|
-
: computedStyle[key]) || 0;
|
|
6115
|
-
return typeof value === "string" ? value.trim() : value;
|
|
6116
|
-
}
|
|
6117
|
-
}
|
|
6118
|
-
measureInstanceViewportBox(instance, { transformPagePoint }) {
|
|
6119
|
-
return measureViewportBox(instance, transformPagePoint);
|
|
6120
|
-
}
|
|
6121
|
-
build(renderState, latestValues, options, props) {
|
|
6122
|
-
buildHTMLStyles(renderState, latestValues, options, props.transformTemplate);
|
|
6123
|
-
}
|
|
6124
|
-
scrapeMotionValuesFromProps(props, prevProps) {
|
|
6125
|
-
return scrapeMotionValuesFromProps$1(props, prevProps);
|
|
6126
|
-
}
|
|
6127
|
-
handleChildMotionValue() {
|
|
6128
|
-
if (this.childSubscription) {
|
|
6129
|
-
this.childSubscription();
|
|
6130
|
-
delete this.childSubscription;
|
|
6131
|
-
}
|
|
6132
|
-
const { children } = this.props;
|
|
6133
|
-
if (wrap.isMotionValue(children)) {
|
|
6134
|
-
this.childSubscription = children.on("change", (latest) => {
|
|
6135
|
-
if (this.current)
|
|
6136
|
-
this.current.textContent = `${latest}`;
|
|
6137
|
-
});
|
|
6138
|
-
}
|
|
6139
|
-
}
|
|
6140
|
-
renderInstance(instance, renderState, styleProp, projection) {
|
|
6141
|
-
renderHTML(instance, renderState, styleProp, projection);
|
|
6142
|
-
}
|
|
6143
|
-
}
|
|
6144
|
-
|
|
6145
4353
|
/**
|
|
6146
4354
|
* When a component is the child of `AnimatePresence`, it can use `usePresence`
|
|
6147
4355
|
* to access information about whether it's still present in the React tree.
|
|
@@ -6213,7 +4421,7 @@ class MeasureLayoutWithContext extends React__default["default"].Component {
|
|
|
6213
4421
|
componentDidMount() {
|
|
6214
4422
|
const { visualElement, layoutGroup, switchLayoutGroup, layoutId } = this.props;
|
|
6215
4423
|
const { projection } = visualElement;
|
|
6216
|
-
addScaleCorrector(defaultScaleCorrectors);
|
|
4424
|
+
wrap.addScaleCorrector(defaultScaleCorrectors);
|
|
6217
4425
|
if (projection) {
|
|
6218
4426
|
if (layoutGroup.group)
|
|
6219
4427
|
layoutGroup.group.add(projection);
|
|
@@ -6333,44 +4541,10 @@ const drag = {
|
|
|
6333
4541
|
},
|
|
6334
4542
|
};
|
|
6335
4543
|
|
|
6336
|
-
class SVGVisualElement extends DOMVisualElement {
|
|
6337
|
-
constructor() {
|
|
6338
|
-
super(...arguments);
|
|
6339
|
-
this.isSVGTag = false;
|
|
6340
|
-
}
|
|
6341
|
-
getBaseTargetFromProps(props, key) {
|
|
6342
|
-
return props[key];
|
|
6343
|
-
}
|
|
6344
|
-
readValueFromInstance(instance, key) {
|
|
6345
|
-
if (wrap.transformProps.has(key)) {
|
|
6346
|
-
const defaultType = wrap.getDefaultValueType(key);
|
|
6347
|
-
return defaultType ? defaultType.default || 0 : 0;
|
|
6348
|
-
}
|
|
6349
|
-
key = !camelCaseAttributes.has(key) ? camelToDash(key) : key;
|
|
6350
|
-
return instance.getAttribute(key);
|
|
6351
|
-
}
|
|
6352
|
-
measureInstanceViewportBox() {
|
|
6353
|
-
return createBox();
|
|
6354
|
-
}
|
|
6355
|
-
scrapeMotionValuesFromProps(props, prevProps) {
|
|
6356
|
-
return scrapeMotionValuesFromProps(props, prevProps);
|
|
6357
|
-
}
|
|
6358
|
-
build(renderState, latestValues, options, props) {
|
|
6359
|
-
buildSVGAttrs(renderState, latestValues, options, this.isSVGTag, props.transformTemplate);
|
|
6360
|
-
}
|
|
6361
|
-
renderInstance(instance, renderState, styleProp, projection) {
|
|
6362
|
-
renderSVG(instance, renderState, styleProp, projection);
|
|
6363
|
-
}
|
|
6364
|
-
mount(instance) {
|
|
6365
|
-
this.isSVGTag = isSVGTag(instance.tagName);
|
|
6366
|
-
super.mount(instance);
|
|
6367
|
-
}
|
|
6368
|
-
}
|
|
6369
|
-
|
|
6370
4544
|
const createDomVisualElement = (Component, options) => {
|
|
6371
4545
|
return isSVGComponent(Component)
|
|
6372
|
-
? new SVGVisualElement(options, { enableHardwareAcceleration: false })
|
|
6373
|
-
: new HTMLVisualElement(options, { enableHardwareAcceleration: true });
|
|
4546
|
+
? new wrap.SVGVisualElement(options, { enableHardwareAcceleration: false })
|
|
4547
|
+
: new wrap.HTMLVisualElement(options, { enableHardwareAcceleration: true });
|
|
6374
4548
|
};
|
|
6375
4549
|
|
|
6376
4550
|
const layout = {
|
|
@@ -7247,9 +5421,9 @@ class WillChangeMotionValue extends wrap.MotionValue {
|
|
|
7247
5421
|
memberName = "transform";
|
|
7248
5422
|
}
|
|
7249
5423
|
else if (!name.startsWith("origin") &&
|
|
7250
|
-
!isCSSVariableName(name) &&
|
|
5424
|
+
!wrap.isCSSVariableName(name) &&
|
|
7251
5425
|
name !== "willChange") {
|
|
7252
|
-
memberName = camelToDash(name);
|
|
5426
|
+
memberName = wrap.camelToDash(name);
|
|
7253
5427
|
}
|
|
7254
5428
|
if (memberName) {
|
|
7255
5429
|
wrap.addUniqueItem(this.members, memberName);
|
|
@@ -7264,7 +5438,7 @@ class WillChangeMotionValue extends wrap.MotionValue {
|
|
|
7264
5438
|
}
|
|
7265
5439
|
}
|
|
7266
5440
|
else {
|
|
7267
|
-
wrap.removeItem(this.members, camelToDash(name));
|
|
5441
|
+
wrap.removeItem(this.members, wrap.camelToDash(name));
|
|
7268
5442
|
}
|
|
7269
5443
|
this.update();
|
|
7270
5444
|
}
|
|
@@ -7306,8 +5480,8 @@ function useReducedMotion() {
|
|
|
7306
5480
|
/**
|
|
7307
5481
|
* Lazy initialisation of prefersReducedMotion
|
|
7308
5482
|
*/
|
|
7309
|
-
!hasReducedMotionListener.current && initPrefersReducedMotion();
|
|
7310
|
-
const [shouldReduceMotion] = React.useState(prefersReducedMotion.current);
|
|
5483
|
+
!wrap.hasReducedMotionListener.current && wrap.initPrefersReducedMotion();
|
|
5484
|
+
const [shouldReduceMotion] = React.useState(wrap.prefersReducedMotion.current);
|
|
7311
5485
|
if (process.env.NODE_ENV !== "production") {
|
|
7312
5486
|
wrap.warnOnce(shouldReduceMotion !== true, "You have Reduced Motion enabled on your device. Animations may not appear as expected.");
|
|
7313
5487
|
}
|
|
@@ -7331,6 +5505,9 @@ function useReducedMotionConfig() {
|
|
|
7331
5505
|
}
|
|
7332
5506
|
}
|
|
7333
5507
|
|
|
5508
|
+
function stopAnimation(visualElement) {
|
|
5509
|
+
visualElement.values.forEach((value) => value.stop());
|
|
5510
|
+
}
|
|
7334
5511
|
/**
|
|
7335
5512
|
* @public
|
|
7336
5513
|
*/
|
|
@@ -7361,7 +5538,7 @@ function animationControls() {
|
|
|
7361
5538
|
set(definition) {
|
|
7362
5539
|
wrap.invariant(hasMounted, "controls.set() should only be called after a component has mounted. Consider calling within a useEffect hook.");
|
|
7363
5540
|
return subscribers.forEach((visualElement) => {
|
|
7364
|
-
setValues(visualElement, definition);
|
|
5541
|
+
wrap.setValues(visualElement, definition);
|
|
7365
5542
|
});
|
|
7366
5543
|
},
|
|
7367
5544
|
stop() {
|
|
@@ -7724,7 +5901,7 @@ sync) {
|
|
|
7724
5901
|
}
|
|
7725
5902
|
|
|
7726
5903
|
function startOptimizedAppearAnimation(element, name, keyframes, options, onReady) {
|
|
7727
|
-
const id = element.dataset[optimizedAppearDataId];
|
|
5904
|
+
const id = element.dataset[wrap.optimizedAppearDataId];
|
|
7728
5905
|
if (!id)
|
|
7729
5906
|
return;
|
|
7730
5907
|
window.HandoffAppearAnimations = handoffOptimizedAppearAnimation;
|
|
@@ -7768,10 +5945,10 @@ function startOptimizedAppearAnimation(element, name, keyframes, options, onRead
|
|
|
7768
5945
|
}
|
|
7769
5946
|
|
|
7770
5947
|
const createObject = () => ({});
|
|
7771
|
-
class StateVisualElement extends VisualElement {
|
|
5948
|
+
class StateVisualElement extends wrap.VisualElement {
|
|
7772
5949
|
build() { }
|
|
7773
5950
|
measureInstanceViewportBox() {
|
|
7774
|
-
return createBox();
|
|
5951
|
+
return wrap.createBox();
|
|
7775
5952
|
}
|
|
7776
5953
|
resetTransform() { }
|
|
7777
5954
|
restoreTransform() { }
|
|
@@ -7790,8 +5967,8 @@ class StateVisualElement extends VisualElement {
|
|
|
7790
5967
|
return 0;
|
|
7791
5968
|
}
|
|
7792
5969
|
makeTargetAnimatableFromInstance({ transition, transitionEnd, ...target }) {
|
|
7793
|
-
const origin = getOrigin(target, transition || {}, this);
|
|
7794
|
-
checkTargetForNewValues(this, target, origin);
|
|
5970
|
+
const origin = wrap.getOrigin(target, transition || {}, this);
|
|
5971
|
+
wrap.checkTargetForNewValues(this, target, origin);
|
|
7795
5972
|
return { transition, transitionEnd, ...target };
|
|
7796
5973
|
}
|
|
7797
5974
|
}
|
|
@@ -7880,18 +6057,23 @@ const AnimateSharedLayout = ({ children }) => {
|
|
|
7880
6057
|
};
|
|
7881
6058
|
|
|
7882
6059
|
exports.MotionValue = wrap.MotionValue;
|
|
6060
|
+
exports.VisualElement = wrap.VisualElement;
|
|
6061
|
+
exports.addScaleCorrector = wrap.addScaleCorrector;
|
|
7883
6062
|
exports.animate = wrap.animate;
|
|
7884
6063
|
exports.animateValue = wrap.animateValue;
|
|
7885
6064
|
exports.anticipate = wrap.anticipate;
|
|
7886
6065
|
exports.backIn = wrap.backIn;
|
|
7887
6066
|
exports.backInOut = wrap.backInOut;
|
|
7888
6067
|
exports.backOut = wrap.backOut;
|
|
6068
|
+
exports.buildTransform = wrap.buildTransform;
|
|
6069
|
+
exports.checkTargetForNewValues = wrap.checkTargetForNewValues;
|
|
7889
6070
|
exports.circIn = wrap.circIn;
|
|
7890
6071
|
exports.circInOut = wrap.circInOut;
|
|
7891
6072
|
exports.circOut = wrap.circOut;
|
|
7892
6073
|
exports.clamp = wrap.clamp;
|
|
7893
6074
|
exports.color = wrap.color;
|
|
7894
6075
|
exports.complex = wrap.complex;
|
|
6076
|
+
exports.createBox = wrap.createBox;
|
|
7895
6077
|
exports.cubicBezier = wrap.cubicBezier;
|
|
7896
6078
|
exports.delay = wrap.delay;
|
|
7897
6079
|
exports.distance = wrap.distance;
|
|
@@ -7906,9 +6088,11 @@ Object.defineProperty(exports, 'invariant', {
|
|
|
7906
6088
|
enumerable: true,
|
|
7907
6089
|
get: function () { return wrap.invariant; }
|
|
7908
6090
|
});
|
|
6091
|
+
exports.isBrowser = wrap.isBrowser;
|
|
7909
6092
|
exports.isMotionValue = wrap.isMotionValue;
|
|
7910
6093
|
exports.mix = wrap.mix;
|
|
7911
6094
|
exports.motionValue = wrap.motionValue;
|
|
6095
|
+
exports.optimizedAppearDataAttribute = wrap.optimizedAppearDataAttribute;
|
|
7912
6096
|
exports.pipe = wrap.pipe;
|
|
7913
6097
|
exports.progress = wrap.progress;
|
|
7914
6098
|
exports.px = wrap.px;
|
|
@@ -7935,30 +6119,23 @@ exports.MotionContext = MotionContext;
|
|
|
7935
6119
|
exports.PresenceContext = PresenceContext;
|
|
7936
6120
|
exports.Reorder = Reorder;
|
|
7937
6121
|
exports.SwitchLayoutGroupContext = SwitchLayoutGroupContext;
|
|
7938
|
-
exports.VisualElement = VisualElement;
|
|
7939
6122
|
exports.addPointerEvent = addPointerEvent;
|
|
7940
6123
|
exports.addPointerInfo = addPointerInfo;
|
|
7941
|
-
exports.addScaleCorrector = addScaleCorrector;
|
|
7942
6124
|
exports.animateVisualElement = animateVisualElement;
|
|
7943
6125
|
exports.animationControls = animationControls;
|
|
7944
6126
|
exports.animations = animations;
|
|
7945
|
-
exports.buildTransform = buildTransform;
|
|
7946
6127
|
exports.calcLength = calcLength;
|
|
7947
|
-
exports.checkTargetForNewValues = checkTargetForNewValues;
|
|
7948
|
-
exports.createBox = createBox;
|
|
7949
6128
|
exports.createDomMotionComponent = createDomMotionComponent;
|
|
7950
6129
|
exports.createMotionComponent = createMotionComponent;
|
|
7951
6130
|
exports.domAnimation = domAnimation;
|
|
7952
6131
|
exports.domMax = domMax;
|
|
7953
6132
|
exports.filterProps = filterProps;
|
|
7954
|
-
exports.isBrowser = isBrowser;
|
|
7955
6133
|
exports.isDragActive = isDragActive;
|
|
7956
6134
|
exports.isMotionComponent = isMotionComponent;
|
|
7957
6135
|
exports.isValidMotionProp = isValidMotionProp;
|
|
7958
6136
|
exports.m = m;
|
|
7959
6137
|
exports.makeUseVisualState = makeUseVisualState;
|
|
7960
6138
|
exports.motion = motion;
|
|
7961
|
-
exports.optimizedAppearDataAttribute = optimizedAppearDataAttribute;
|
|
7962
6139
|
exports.resolveMotionValue = resolveMotionValue;
|
|
7963
6140
|
exports.startOptimizedAppearAnimation = startOptimizedAppearAnimation;
|
|
7964
6141
|
exports.unwrapMotionComponent = unwrapMotionComponent;
|