framer-motion 7.6.4 → 7.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +789 -850
- package/dist/es/animation/use-animated-state.mjs +29 -17
- package/dist/es/gestures/drag/VisualElementDragControls.mjs +14 -10
- package/dist/es/gestures/use-focus-gesture.mjs +1 -1
- package/dist/es/gestures/use-tap-gesture.mjs +1 -1
- package/dist/es/index.mjs +1 -1
- package/dist/es/motion/features/viewport/use-viewport.mjs +2 -2
- package/dist/es/motion/utils/use-visual-element.mjs +3 -3
- package/dist/es/projection/node/create-projection-node.mjs +74 -60
- package/dist/es/render/VisualElement.mjs +480 -0
- package/dist/es/render/dom/DOMVisualElement.mjs +49 -0
- package/dist/es/render/dom/create-visual-element.mjs +4 -4
- package/dist/es/render/dom/utils/css-variables-conversion.mjs +2 -2
- package/dist/es/render/dom/utils/unit-conversion.mjs +4 -4
- package/dist/es/render/html/HTMLVisualElement.mjs +41 -0
- package/dist/es/render/svg/{visual-element.mjs → SVGVisualElement.mjs} +21 -15
- package/dist/es/render/utils/animation.mjs +4 -4
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/render/utils/resolve-dynamic-variants.mjs +2 -2
- package/dist/es/render/utils/setters.mjs +2 -1
- package/dist/es/value/index.mjs +1 -1
- package/dist/framer-motion.dev.js +789 -850
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +2101 -1931
- package/dist/projection.dev.js +1053 -1136
- package/dist/size-rollup-dom-animation-m.js +1 -1
- package/dist/size-rollup-dom-animation.js +1 -1
- package/dist/size-rollup-dom-max-assets.js +1 -1
- package/dist/size-rollup-dom-max.js +1 -1
- package/dist/size-rollup-m.js +1 -1
- package/dist/size-rollup-motion.js +1 -1
- package/dist/size-webpack-dom-animation.js +1 -1
- package/dist/size-webpack-dom-max.js +1 -1
- package/dist/size-webpack-m.js +1 -1
- package/dist/three-entry.d.ts +1956 -1745
- package/package.json +8 -8
- package/dist/es/render/html/visual-element.mjs +0 -109
- package/dist/es/render/index.mjs +0 -515
- package/dist/es/render/utils/lifecycles.mjs +0 -43
|
@@ -1,29 +1,39 @@
|
|
|
1
1
|
import { useState, useEffect } from 'react';
|
|
2
2
|
import { useConstant } from '../utils/use-constant.mjs';
|
|
3
3
|
import { getOrigin, checkTargetForNewValues } from '../render/utils/setters.mjs';
|
|
4
|
-
import { visualElement } from '../render/index.mjs';
|
|
5
4
|
import { animateVisualElement } from '../render/utils/animation.mjs';
|
|
6
5
|
import { makeUseVisualState } from '../motion/utils/use-visual-state.mjs';
|
|
7
6
|
import { createBox } from '../projection/geometry/models.mjs';
|
|
7
|
+
import { VisualElement } from '../render/VisualElement.mjs';
|
|
8
8
|
|
|
9
9
|
const createObject = () => ({});
|
|
10
|
-
|
|
11
|
-
build() { }
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
class StateVisualElement extends VisualElement {
|
|
11
|
+
build() { }
|
|
12
|
+
measureInstanceViewportBox() {
|
|
13
|
+
return createBox();
|
|
14
|
+
}
|
|
15
|
+
resetTransform() { }
|
|
16
|
+
restoreTransform() { }
|
|
17
|
+
removeValueFromRenderState() { }
|
|
18
|
+
renderInstance() { }
|
|
19
|
+
scrapeMotionValuesFromProps() {
|
|
20
|
+
return createObject();
|
|
21
|
+
}
|
|
22
|
+
getBaseTargetFromProps() {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
18
25
|
readValueFromInstance(_state, key, options) {
|
|
19
26
|
return options.initialState[key] || 0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
}
|
|
28
|
+
sortInstanceNodePosition() {
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
makeTargetAnimatableFromInstance({ transition, transitionEnd, ...target }) {
|
|
32
|
+
const origin = getOrigin(target, transition || {}, this);
|
|
33
|
+
checkTargetForNewValues(this, target, origin);
|
|
24
34
|
return { transition, transitionEnd, ...target };
|
|
25
|
-
}
|
|
26
|
-
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
27
37
|
const useVisualState = makeUseVisualState({
|
|
28
38
|
scrapeMotionValuesFromProps: createObject,
|
|
29
39
|
createRenderState: createObject,
|
|
@@ -35,10 +45,12 @@ const useVisualState = makeUseVisualState({
|
|
|
35
45
|
function useAnimatedState(initialState) {
|
|
36
46
|
const [animationState, setAnimationState] = useState(initialState);
|
|
37
47
|
const visualState = useVisualState({}, false);
|
|
38
|
-
const element = useConstant(() =>
|
|
48
|
+
const element = useConstant(() => {
|
|
49
|
+
return new StateVisualElement({ props: {}, visualState }, { initialState });
|
|
50
|
+
});
|
|
39
51
|
useEffect(() => {
|
|
40
52
|
element.mount({});
|
|
41
|
-
return element.unmount;
|
|
53
|
+
return () => element.unmount();
|
|
42
54
|
}, [element]);
|
|
43
55
|
useEffect(() => {
|
|
44
56
|
element.setProps({
|
|
@@ -84,7 +84,7 @@ class VisualElementDragControls {
|
|
|
84
84
|
* If the MotionValue is a percentage value convert to px
|
|
85
85
|
*/
|
|
86
86
|
if (percent.test(current)) {
|
|
87
|
-
const measuredAxis = (_b = (_a = this.visualElement.projection) === null || _a === void 0 ? void 0 : _a.layout) === null || _b === void 0 ? void 0 : _b.
|
|
87
|
+
const measuredAxis = (_b = (_a = this.visualElement.projection) === null || _a === void 0 ? void 0 : _a.layout) === null || _b === void 0 ? void 0 : _b.layoutBox[axis];
|
|
88
88
|
if (measuredAxis) {
|
|
89
89
|
const length = calcLength(measuredAxis);
|
|
90
90
|
current = length * (parseFloat(current) / 100);
|
|
@@ -121,9 +121,9 @@ class VisualElementDragControls {
|
|
|
121
121
|
* of a re-render we want to ensure the browser can read the latest
|
|
122
122
|
* bounding box to ensure the pointer and element don't fall out of sync.
|
|
123
123
|
*/
|
|
124
|
-
this.visualElement.
|
|
124
|
+
this.visualElement.render();
|
|
125
125
|
/**
|
|
126
|
-
* This must fire after the
|
|
126
|
+
* This must fire after the render call as it might trigger a state
|
|
127
127
|
* change which itself might trigger a layout update.
|
|
128
128
|
*/
|
|
129
129
|
onDrag === null || onDrag === void 0 ? void 0 : onDrag(event, info);
|
|
@@ -185,7 +185,7 @@ class VisualElementDragControls {
|
|
|
185
185
|
}
|
|
186
186
|
else {
|
|
187
187
|
if (dragConstraints && layout) {
|
|
188
|
-
this.constraints = calcRelativeConstraints(layout.
|
|
188
|
+
this.constraints = calcRelativeConstraints(layout.layoutBox, dragConstraints);
|
|
189
189
|
}
|
|
190
190
|
else {
|
|
191
191
|
this.constraints = false;
|
|
@@ -202,7 +202,7 @@ class VisualElementDragControls {
|
|
|
202
202
|
!this.hasMutatedConstraints) {
|
|
203
203
|
eachAxis((axis) => {
|
|
204
204
|
if (this.getAxisMotionValue(axis)) {
|
|
205
|
-
this.constraints[axis] = rebaseAxisConstraints(layout.
|
|
205
|
+
this.constraints[axis] = rebaseAxisConstraints(layout.layoutBox[axis], this.constraints[axis]);
|
|
206
206
|
}
|
|
207
207
|
});
|
|
208
208
|
}
|
|
@@ -218,7 +218,7 @@ class VisualElementDragControls {
|
|
|
218
218
|
if (!projection || !projection.layout)
|
|
219
219
|
return false;
|
|
220
220
|
const constraintsBox = measurePageBox(constraintsElement, projection.root, this.visualElement.getTransformPagePoint());
|
|
221
|
-
let measuredConstraints = calcViewportConstraints(projection.layout.
|
|
221
|
+
let measuredConstraints = calcViewportConstraints(projection.layout.layoutBox, constraintsBox);
|
|
222
222
|
/**
|
|
223
223
|
* If there's an onMeasureDragConstraints listener we call it and
|
|
224
224
|
* if different constraints are returned, set constraints to that
|
|
@@ -300,7 +300,7 @@ class VisualElementDragControls {
|
|
|
300
300
|
const { projection } = this.visualElement;
|
|
301
301
|
const axisValue = this.getAxisMotionValue(axis);
|
|
302
302
|
if (projection && projection.layout) {
|
|
303
|
-
const { min, max } = projection.layout.
|
|
303
|
+
const { min, max } = projection.layout.layoutBox[axis];
|
|
304
304
|
axisValue.set(point[axis] - mix(min, max, 0.5));
|
|
305
305
|
}
|
|
306
306
|
});
|
|
@@ -312,6 +312,8 @@ class VisualElementDragControls {
|
|
|
312
312
|
*/
|
|
313
313
|
scalePositionWithinConstraints() {
|
|
314
314
|
var _a;
|
|
315
|
+
if (!this.visualElement.current)
|
|
316
|
+
return;
|
|
315
317
|
const { drag, dragConstraints } = this.getProps();
|
|
316
318
|
const { projection } = this.visualElement;
|
|
317
319
|
if (!isRefObject(dragConstraints) || !projection || !this.constraints)
|
|
@@ -337,7 +339,7 @@ class VisualElementDragControls {
|
|
|
337
339
|
* Update the layout of this element and resolve the latest drag constraints
|
|
338
340
|
*/
|
|
339
341
|
const { transformTemplate } = this.visualElement.getProps();
|
|
340
|
-
this.visualElement.
|
|
342
|
+
this.visualElement.current.style.transform = transformTemplate
|
|
341
343
|
? transformTemplate({}, "")
|
|
342
344
|
: "none";
|
|
343
345
|
(_a = projection.root) === null || _a === void 0 ? void 0 : _a.updateScroll();
|
|
@@ -360,8 +362,10 @@ class VisualElementDragControls {
|
|
|
360
362
|
}
|
|
361
363
|
addListeners() {
|
|
362
364
|
var _a;
|
|
365
|
+
if (!this.visualElement.current)
|
|
366
|
+
return;
|
|
363
367
|
elementDragControls.set(this.visualElement, this);
|
|
364
|
-
const element = this.visualElement.
|
|
368
|
+
const element = this.visualElement.current;
|
|
365
369
|
/**
|
|
366
370
|
* Attach a pointerdown event listener on this DOM element to initiate drag tracking.
|
|
367
371
|
*/
|
|
@@ -400,7 +404,7 @@ class VisualElementDragControls {
|
|
|
400
404
|
this.originPoint[axis] += delta[axis].translate;
|
|
401
405
|
motionValue.set(motionValue.get() + delta[axis].translate);
|
|
402
406
|
});
|
|
403
|
-
this.visualElement.
|
|
407
|
+
this.visualElement.render();
|
|
404
408
|
}
|
|
405
409
|
}));
|
|
406
410
|
return () => {
|
|
@@ -7,7 +7,7 @@ import { useDomEvent } from '../events/use-dom-event.mjs';
|
|
|
7
7
|
* @param ref
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
|
-
function useFocusGesture({ whileFocus, visualElement }) {
|
|
10
|
+
function useFocusGesture({ whileFocus, visualElement, }) {
|
|
11
11
|
const { animationState } = visualElement;
|
|
12
12
|
const onFocus = () => {
|
|
13
13
|
animationState && animationState.setActive(AnimationType.Focus, true);
|
|
@@ -38,7 +38,7 @@ function useTapGesture({ onTap, onTapStart, onTapCancel, whileTap, visualElement
|
|
|
38
38
|
* We only count this as a tap gesture if the event.target is the same
|
|
39
39
|
* as, or a child of, this component's element
|
|
40
40
|
*/
|
|
41
|
-
!isNodeOrChild(visualElement.
|
|
41
|
+
!isNodeOrChild(visualElement.current, event.target)
|
|
42
42
|
? onTapCancel && onTapCancel(event, info)
|
|
43
43
|
: onTap && onTap(event, info);
|
|
44
44
|
}
|
package/dist/es/index.mjs
CHANGED
|
@@ -37,7 +37,7 @@ export { useDomEvent } from './events/use-dom-event.mjs';
|
|
|
37
37
|
export { createMotionComponent } from './motion/index.mjs';
|
|
38
38
|
export { isMotionComponent } from './motion/utils/is-motion-component.mjs';
|
|
39
39
|
export { unwrapMotionComponent } from './motion/utils/unwrap-motion-component.mjs';
|
|
40
|
-
export {
|
|
40
|
+
export { VisualElement } from './render/VisualElement.mjs';
|
|
41
41
|
export { addScaleCorrector } from './projection/styles/scale-correction.mjs';
|
|
42
42
|
export { useInstantTransition } from './utils/use-instant-transition.mjs';
|
|
43
43
|
export { useInstantLayoutTransition } from './projection/use-instant-layout-transition.mjs';
|
|
@@ -23,7 +23,7 @@ const thresholdNames = {
|
|
|
23
23
|
};
|
|
24
24
|
function useIntersectionObserver(shouldObserve, state, visualElement, { root, margin: rootMargin, amount = "some", once }) {
|
|
25
25
|
useEffect(() => {
|
|
26
|
-
if (!shouldObserve)
|
|
26
|
+
if (!shouldObserve || !visualElement.current)
|
|
27
27
|
return;
|
|
28
28
|
const options = {
|
|
29
29
|
root: root === null || root === void 0 ? void 0 : root.current,
|
|
@@ -61,7 +61,7 @@ function useIntersectionObserver(shouldObserve, state, visualElement, { root, ma
|
|
|
61
61
|
: props.onViewportLeave;
|
|
62
62
|
callback && callback(entry);
|
|
63
63
|
};
|
|
64
|
-
return observeIntersection(visualElement.
|
|
64
|
+
return observeIntersection(visualElement.current, options, intersectionCallback);
|
|
65
65
|
}, [shouldObserve, root, rootMargin, amount]);
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
@@ -10,7 +10,7 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
|
|
|
10
10
|
const lazyContext = useContext(LazyContext);
|
|
11
11
|
const presenceContext = useContext(PresenceContext);
|
|
12
12
|
const reducedMotionConfig = useContext(MotionConfigContext).reducedMotion;
|
|
13
|
-
const visualElementRef = useRef(
|
|
13
|
+
const visualElementRef = useRef();
|
|
14
14
|
/**
|
|
15
15
|
* If we haven't preloaded a renderer, check to see if we have one lazy-loaded
|
|
16
16
|
*/
|
|
@@ -29,14 +29,14 @@ function useVisualElement(Component, visualState, props, createVisualElement) {
|
|
|
29
29
|
}
|
|
30
30
|
const visualElement = visualElementRef.current;
|
|
31
31
|
useIsomorphicLayoutEffect(() => {
|
|
32
|
-
visualElement && visualElement.
|
|
32
|
+
visualElement && visualElement.render();
|
|
33
33
|
});
|
|
34
34
|
useEffect(() => {
|
|
35
35
|
if (visualElement && visualElement.animationState) {
|
|
36
36
|
visualElement.animationState.animateChanges();
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
-
useIsomorphicLayoutEffect(() => () => visualElement && visualElement.
|
|
39
|
+
useIsomorphicLayoutEffect(() => () => visualElement && visualElement.notify("Unmount"), []);
|
|
40
40
|
return visualElement;
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -28,7 +28,7 @@ const transformAxes = ["", "X", "Y", "Z"];
|
|
|
28
28
|
const animationTarget = 1000;
|
|
29
29
|
function createProjectionNode({ attachResizeListener, defaultParent, measureScroll, checkIsScrollRoot, resetTransform, }) {
|
|
30
30
|
return class ProjectionNode {
|
|
31
|
-
constructor(
|
|
31
|
+
constructor(elementId, latestValues = {}, parent = defaultParent === null || defaultParent === void 0 ? void 0 : defaultParent()) {
|
|
32
32
|
/**
|
|
33
33
|
* A Set containing all this component's children. This is used to iterate
|
|
34
34
|
* through the children.
|
|
@@ -81,7 +81,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
81
81
|
/**
|
|
82
82
|
* An object representing the calculated contextual/accumulated/tree scale.
|
|
83
83
|
* This will be used to scale calculcated projection transforms, as these are
|
|
84
|
-
* calculated in screen-space but need to be scaled for elements to
|
|
84
|
+
* calculated in screen-space but need to be scaled for elements to layoutly
|
|
85
85
|
* make it to their calculated destinations.
|
|
86
86
|
*
|
|
87
87
|
* TODO: Lazy-init
|
|
@@ -111,13 +111,13 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
111
111
|
*/
|
|
112
112
|
// TODO Only running on root node
|
|
113
113
|
this.sharedNodes = new Map();
|
|
114
|
-
this.
|
|
114
|
+
this.elementId = elementId;
|
|
115
115
|
this.latestValues = latestValues;
|
|
116
116
|
this.root = parent ? parent.root || parent : this;
|
|
117
117
|
this.path = parent ? [...parent.path, parent] : [];
|
|
118
118
|
this.parent = parent;
|
|
119
119
|
this.depth = parent ? parent.depth + 1 : 0;
|
|
120
|
-
|
|
120
|
+
elementId && this.root.registerPotentialNode(elementId, this);
|
|
121
121
|
for (let i = 0; i < this.path.length; i++) {
|
|
122
122
|
this.path[i].shouldResetTransform = true;
|
|
123
123
|
}
|
|
@@ -151,12 +151,12 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
151
151
|
instance instanceof SVGElement && instance.tagName !== "svg";
|
|
152
152
|
this.instance = instance;
|
|
153
153
|
const { layoutId, layout, visualElement } = this.options;
|
|
154
|
-
if (visualElement && !visualElement.
|
|
154
|
+
if (visualElement && !visualElement.current) {
|
|
155
155
|
visualElement.mount(instance);
|
|
156
156
|
}
|
|
157
157
|
this.root.nodes.add(this);
|
|
158
158
|
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.children.add(this);
|
|
159
|
-
this.
|
|
159
|
+
this.elementId && this.root.potentialNodes.delete(this.elementId);
|
|
160
160
|
if (isLayoutDirty && (layout || layoutId)) {
|
|
161
161
|
this.isLayoutDirty = true;
|
|
162
162
|
}
|
|
@@ -372,14 +372,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
372
372
|
updateSnapshot() {
|
|
373
373
|
if (this.snapshot || !this.instance)
|
|
374
374
|
return;
|
|
375
|
-
|
|
376
|
-
const layout = this.removeTransform(this.removeElementScroll(measured));
|
|
377
|
-
roundBox(layout);
|
|
378
|
-
this.snapshot = {
|
|
379
|
-
measured,
|
|
380
|
-
layout,
|
|
381
|
-
latestValues: {},
|
|
382
|
-
};
|
|
375
|
+
this.snapshot = this.measure();
|
|
383
376
|
}
|
|
384
377
|
updateLayout() {
|
|
385
378
|
var _a;
|
|
@@ -404,18 +397,13 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
404
397
|
node.updateScroll();
|
|
405
398
|
}
|
|
406
399
|
}
|
|
407
|
-
const measured = this.measure();
|
|
408
|
-
roundBox(measured);
|
|
409
400
|
const prevLayout = this.layout;
|
|
410
|
-
this.layout =
|
|
411
|
-
measured,
|
|
412
|
-
actual: this.removeElementScroll(measured),
|
|
413
|
-
};
|
|
401
|
+
this.layout = this.measure(false);
|
|
414
402
|
this.layoutCorrected = createBox();
|
|
415
403
|
this.isLayoutDirty = false;
|
|
416
404
|
this.projectionDelta = undefined;
|
|
417
|
-
this.notifyListeners("measure", this.layout.
|
|
418
|
-
(_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.
|
|
405
|
+
this.notifyListeners("measure", this.layout.layoutBox);
|
|
406
|
+
(_a = this.options.visualElement) === null || _a === void 0 ? void 0 : _a.notify("LayoutMeasure", this.layout.layoutBox, prevLayout === null || prevLayout === void 0 ? void 0 : prevLayout.layoutBox);
|
|
419
407
|
}
|
|
420
408
|
updateScroll() {
|
|
421
409
|
if (this.options.layoutScroll && this.instance) {
|
|
@@ -441,7 +429,25 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
441
429
|
this.scheduleRender();
|
|
442
430
|
}
|
|
443
431
|
}
|
|
444
|
-
measure() {
|
|
432
|
+
measure(removeTransform = true) {
|
|
433
|
+
const pageBox = this.measurePageBox();
|
|
434
|
+
let layoutBox = this.removeElementScroll(pageBox);
|
|
435
|
+
/**
|
|
436
|
+
* Measurements taken during the pre-render stage
|
|
437
|
+
* still have transforms applied so we remove them
|
|
438
|
+
* via calculation.
|
|
439
|
+
*/
|
|
440
|
+
if (removeTransform) {
|
|
441
|
+
layoutBox = this.removeTransform(layoutBox);
|
|
442
|
+
}
|
|
443
|
+
roundBox(layoutBox);
|
|
444
|
+
return {
|
|
445
|
+
measuredBox: pageBox,
|
|
446
|
+
layoutBox,
|
|
447
|
+
latestValues: {},
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
measurePageBox() {
|
|
445
451
|
const { visualElement } = this.options;
|
|
446
452
|
if (!visualElement)
|
|
447
453
|
return createBox();
|
|
@@ -522,9 +528,9 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
522
528
|
continue;
|
|
523
529
|
hasScale(node.latestValues) && node.updateSnapshot();
|
|
524
530
|
const sourceBox = createBox();
|
|
525
|
-
const nodeBox = node.
|
|
531
|
+
const nodeBox = node.measurePageBox();
|
|
526
532
|
copyBoxInto(sourceBox, nodeBox);
|
|
527
|
-
removeBoxTransforms(boxWithoutTransform, node.latestValues, (_a = node.snapshot) === null || _a === void 0 ? void 0 : _a.
|
|
533
|
+
removeBoxTransforms(boxWithoutTransform, node.latestValues, (_a = node.snapshot) === null || _a === void 0 ? void 0 : _a.layoutBox, sourceBox);
|
|
528
534
|
}
|
|
529
535
|
if (hasTransform(this.latestValues)) {
|
|
530
536
|
removeBoxTransforms(boxWithoutTransform, this.latestValues);
|
|
@@ -573,13 +579,17 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
573
579
|
// TODO If this is unsuccessful this currently happens every frame
|
|
574
580
|
if (!this.targetDelta && !this.relativeTarget) {
|
|
575
581
|
// TODO: This is a semi-repetition of further down this function, make DRY
|
|
576
|
-
|
|
577
|
-
if (
|
|
582
|
+
const relativeParent = this.getClosestProjectingParent();
|
|
583
|
+
if (relativeParent && relativeParent.layout) {
|
|
584
|
+
this.relativeParent = relativeParent;
|
|
578
585
|
this.relativeTarget = createBox();
|
|
579
586
|
this.relativeTargetOrigin = createBox();
|
|
580
|
-
calcRelativePosition(this.relativeTargetOrigin, this.layout.
|
|
587
|
+
calcRelativePosition(this.relativeTargetOrigin, this.layout.layoutBox, relativeParent.layout.layoutBox);
|
|
581
588
|
copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
|
|
582
589
|
}
|
|
590
|
+
else {
|
|
591
|
+
this.relativeParent = this.relativeTarget = undefined;
|
|
592
|
+
}
|
|
583
593
|
}
|
|
584
594
|
/**
|
|
585
595
|
* If we have no relative target or no target delta our target isn't valid
|
|
@@ -608,10 +618,10 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
608
618
|
else if (this.targetDelta) {
|
|
609
619
|
if (Boolean(this.resumingFrom)) {
|
|
610
620
|
// TODO: This is creating a new object every frame
|
|
611
|
-
this.target = this.applyTransform(this.layout.
|
|
621
|
+
this.target = this.applyTransform(this.layout.layoutBox);
|
|
612
622
|
}
|
|
613
623
|
else {
|
|
614
|
-
copyBoxInto(this.target, this.layout.
|
|
624
|
+
copyBoxInto(this.target, this.layout.layoutBox);
|
|
615
625
|
}
|
|
616
626
|
applyBoxDelta(this.target, this.targetDelta);
|
|
617
627
|
}
|
|
@@ -619,24 +629,28 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
619
629
|
/**
|
|
620
630
|
* If no target, use own layout as target
|
|
621
631
|
*/
|
|
622
|
-
copyBoxInto(this.target, this.layout.
|
|
632
|
+
copyBoxInto(this.target, this.layout.layoutBox);
|
|
623
633
|
}
|
|
624
634
|
/**
|
|
625
635
|
* If we've been told to attempt to resolve a relative target, do so.
|
|
626
636
|
*/
|
|
627
637
|
if (this.attemptToResolveRelativeTarget) {
|
|
628
638
|
this.attemptToResolveRelativeTarget = false;
|
|
629
|
-
|
|
630
|
-
if (
|
|
631
|
-
Boolean(
|
|
639
|
+
const relativeParent = this.getClosestProjectingParent();
|
|
640
|
+
if (relativeParent &&
|
|
641
|
+
Boolean(relativeParent.resumingFrom) ===
|
|
632
642
|
Boolean(this.resumingFrom) &&
|
|
633
|
-
!
|
|
634
|
-
|
|
643
|
+
!relativeParent.options.layoutScroll &&
|
|
644
|
+
relativeParent.target) {
|
|
645
|
+
this.relativeParent = relativeParent;
|
|
635
646
|
this.relativeTarget = createBox();
|
|
636
647
|
this.relativeTargetOrigin = createBox();
|
|
637
|
-
calcRelativePosition(this.relativeTargetOrigin, this.target,
|
|
648
|
+
calcRelativePosition(this.relativeTargetOrigin, this.target, relativeParent.target);
|
|
638
649
|
copyBoxInto(this.relativeTarget, this.relativeTargetOrigin);
|
|
639
650
|
}
|
|
651
|
+
else {
|
|
652
|
+
this.relativeParent = this.relativeTarget = undefined;
|
|
653
|
+
}
|
|
640
654
|
}
|
|
641
655
|
}
|
|
642
656
|
getClosestProjectingParent() {
|
|
@@ -672,7 +686,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
672
686
|
* Reset the corrected box with the latest values from box, as we're then going
|
|
673
687
|
* to perform mutative operations on it.
|
|
674
688
|
*/
|
|
675
|
-
copyBoxInto(this.layoutCorrected, this.layout.
|
|
689
|
+
copyBoxInto(this.layoutCorrected, this.layout.layoutBox);
|
|
676
690
|
/**
|
|
677
691
|
* Apply all the parent deltas to this box to produce the corrected box. This
|
|
678
692
|
* is the layout box, as it will appear on screen as a result of the transforms of its parents.
|
|
@@ -749,7 +763,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
749
763
|
this.relativeTargetOrigin &&
|
|
750
764
|
this.layout &&
|
|
751
765
|
((_a = this.relativeParent) === null || _a === void 0 ? void 0 : _a.layout)) {
|
|
752
|
-
calcRelativePosition(relativeLayout, this.layout.
|
|
766
|
+
calcRelativePosition(relativeLayout, this.layout.layoutBox, this.relativeParent.layout.layoutBox);
|
|
753
767
|
mixBox(this.relativeTarget, this.relativeTargetOrigin, relativeLayout, progress);
|
|
754
768
|
}
|
|
755
769
|
if (isSharedLayoutAnimation) {
|
|
@@ -833,12 +847,12 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
833
847
|
if (this !== lead &&
|
|
834
848
|
this.layout &&
|
|
835
849
|
layout &&
|
|
836
|
-
shouldAnimatePositionOnly(this.options.animationType, this.layout.
|
|
850
|
+
shouldAnimatePositionOnly(this.options.animationType, this.layout.layoutBox, layout.layoutBox)) {
|
|
837
851
|
target = this.target || createBox();
|
|
838
|
-
const xLength = calcLength(this.layout.
|
|
852
|
+
const xLength = calcLength(this.layout.layoutBox.x);
|
|
839
853
|
target.x.min = lead.target.x.min;
|
|
840
854
|
target.x.max = target.x.min + xLength;
|
|
841
|
-
const yLength = calcLength(this.layout.
|
|
855
|
+
const yLength = calcLength(this.layout.layoutBox.y);
|
|
842
856
|
target.y.min = lead.target.y.min;
|
|
843
857
|
target.y.max = target.y.min + yLength;
|
|
844
858
|
}
|
|
@@ -852,7 +866,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
852
866
|
/**
|
|
853
867
|
* Update the delta between the corrected box and the final target box, after
|
|
854
868
|
* user-set transforms are applied to it. This will be used by the renderer to
|
|
855
|
-
* create a transform style that will reproject the element from its
|
|
869
|
+
* create a transform style that will reproject the element from its layout layout
|
|
856
870
|
* into the desired bounding box.
|
|
857
871
|
*/
|
|
858
872
|
calcBoxDelta(this.projectionDeltaWithTransform, this.layoutCorrected, targetWithTransforms, latestValues);
|
|
@@ -935,7 +949,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
935
949
|
return;
|
|
936
950
|
// Force a render of this element to apply the transform with all rotations
|
|
937
951
|
// set to 0.
|
|
938
|
-
visualElement === null || visualElement === void 0 ? void 0 : visualElement.
|
|
952
|
+
visualElement === null || visualElement === void 0 ? void 0 : visualElement.render();
|
|
939
953
|
// Put back all the values we reset
|
|
940
954
|
for (const key in resetValues) {
|
|
941
955
|
visualElement.setStaticValue(key, resetValues[key]);
|
|
@@ -1008,7 +1022,7 @@ function createProjectionNode({ attachResizeListener, defaultParent, measureScro
|
|
|
1008
1022
|
}
|
|
1009
1023
|
else {
|
|
1010
1024
|
/**
|
|
1011
|
-
* Or we're not animating at all, set the lead component to its
|
|
1025
|
+
* Or we're not animating at all, set the lead component to its layout
|
|
1012
1026
|
* opacity and other components to hidden.
|
|
1013
1027
|
*/
|
|
1014
1028
|
styles.opacity =
|
|
@@ -1072,53 +1086,53 @@ function notifyLayoutUpdate(node) {
|
|
|
1072
1086
|
node.layout &&
|
|
1073
1087
|
snapshot &&
|
|
1074
1088
|
node.hasListeners("didUpdate")) {
|
|
1075
|
-
const {
|
|
1089
|
+
const { layoutBox: layout, measuredBox: measuredLayout } = node.layout;
|
|
1076
1090
|
const { animationType } = node.options;
|
|
1077
1091
|
// TODO Maybe we want to also resize the layout snapshot so we don't trigger
|
|
1078
1092
|
// animations for instance if layout="size" and an element has only changed position
|
|
1079
1093
|
if (animationType === "size") {
|
|
1080
1094
|
eachAxis((axis) => {
|
|
1081
1095
|
const axisSnapshot = snapshot.isShared
|
|
1082
|
-
? snapshot.
|
|
1083
|
-
: snapshot.
|
|
1096
|
+
? snapshot.measuredBox[axis]
|
|
1097
|
+
: snapshot.layoutBox[axis];
|
|
1084
1098
|
const length = calcLength(axisSnapshot);
|
|
1085
1099
|
axisSnapshot.min = layout[axis].min;
|
|
1086
1100
|
axisSnapshot.max = axisSnapshot.min + length;
|
|
1087
1101
|
});
|
|
1088
1102
|
}
|
|
1089
|
-
else if (shouldAnimatePositionOnly(animationType, snapshot.
|
|
1103
|
+
else if (shouldAnimatePositionOnly(animationType, snapshot.layoutBox, layout)) {
|
|
1090
1104
|
eachAxis((axis) => {
|
|
1091
1105
|
const axisSnapshot = snapshot.isShared
|
|
1092
|
-
? snapshot.
|
|
1093
|
-
: snapshot.
|
|
1106
|
+
? snapshot.measuredBox[axis]
|
|
1107
|
+
: snapshot.layoutBox[axis];
|
|
1094
1108
|
const length = calcLength(layout[axis]);
|
|
1095
1109
|
axisSnapshot.max = axisSnapshot.min + length;
|
|
1096
1110
|
});
|
|
1097
1111
|
}
|
|
1098
1112
|
const layoutDelta = createDelta();
|
|
1099
|
-
calcBoxDelta(layoutDelta, layout, snapshot.
|
|
1113
|
+
calcBoxDelta(layoutDelta, layout, snapshot.layoutBox);
|
|
1100
1114
|
const visualDelta = createDelta();
|
|
1101
1115
|
if (snapshot.isShared) {
|
|
1102
|
-
calcBoxDelta(visualDelta, node.applyTransform(measuredLayout, true), snapshot.
|
|
1116
|
+
calcBoxDelta(visualDelta, node.applyTransform(measuredLayout, true), snapshot.measuredBox);
|
|
1103
1117
|
}
|
|
1104
1118
|
else {
|
|
1105
|
-
calcBoxDelta(visualDelta, layout, snapshot.
|
|
1119
|
+
calcBoxDelta(visualDelta, layout, snapshot.layoutBox);
|
|
1106
1120
|
}
|
|
1107
1121
|
const hasLayoutChanged = !isDeltaZero(layoutDelta);
|
|
1108
1122
|
let hasRelativeTargetChanged = false;
|
|
1109
1123
|
if (!node.resumeFrom) {
|
|
1110
|
-
|
|
1124
|
+
const relativeParent = node.getClosestProjectingParent();
|
|
1111
1125
|
/**
|
|
1112
1126
|
* If the relativeParent is itself resuming from a different element then
|
|
1113
1127
|
* the relative snapshot is not relavent
|
|
1114
1128
|
*/
|
|
1115
|
-
if (
|
|
1116
|
-
const { snapshot: parentSnapshot, layout: parentLayout } =
|
|
1129
|
+
if (relativeParent && !relativeParent.resumeFrom) {
|
|
1130
|
+
const { snapshot: parentSnapshot, layout: parentLayout } = relativeParent;
|
|
1117
1131
|
if (parentSnapshot && parentLayout) {
|
|
1118
1132
|
const relativeSnapshot = createBox();
|
|
1119
|
-
calcRelativePosition(relativeSnapshot, snapshot.
|
|
1133
|
+
calcRelativePosition(relativeSnapshot, snapshot.layoutBox, parentSnapshot.layoutBox);
|
|
1120
1134
|
const relativeLayout = createBox();
|
|
1121
|
-
calcRelativePosition(relativeLayout, layout, parentLayout.
|
|
1135
|
+
calcRelativePosition(relativeLayout, layout, parentLayout.layoutBox);
|
|
1122
1136
|
if (!boxEquals(relativeSnapshot, relativeLayout)) {
|
|
1123
1137
|
hasRelativeTargetChanged = true;
|
|
1124
1138
|
}
|
|
@@ -1153,7 +1167,7 @@ function clearMeasurements(node) {
|
|
|
1153
1167
|
function resetTransformStyle(node) {
|
|
1154
1168
|
const { visualElement } = node.options;
|
|
1155
1169
|
if (visualElement === null || visualElement === void 0 ? void 0 : visualElement.getProps().onBeforeLayoutMeasure) {
|
|
1156
|
-
visualElement.
|
|
1170
|
+
visualElement.notify("BeforeLayoutMeasure");
|
|
1157
1171
|
}
|
|
1158
1172
|
node.resetTransform();
|
|
1159
1173
|
}
|