@wordpress/block-editor
Version:
164 lines (142 loc) • 4.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _web = require("@react-spring/web");
var _element = require("@wordpress/element");
var _compose = require("@wordpress/compose");
var _dom = require("@wordpress/dom");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Simple reducer used to increment a counter.
*
* @param {number} state Previous counter value.
* @return {number} New state value.
*/
const counterReducer = state => state + 1;
const getAbsolutePosition = element => {
return {
top: element.offsetTop,
left: element.offsetLeft
};
};
/**
* Hook used to compute the styles required to move a div into a new position.
*
* The way this animation works is the following:
* - It first renders the element as if there was no animation.
* - It takes a snapshot of the position of the block to use it
* as a destination point for the animation.
* - It restores the element to the previous position using a CSS transform
* - It uses the "resetAnimation" flag to reset the animation
* from the beginning in order to animate to the new destination point.
*
* @param {Object} $1 Options
* @param {boolean} $1.isSelected Whether it's the current block or not.
* @param {boolean} $1.adjustScrolling Adjust the scroll position to the current block.
* @param {boolean} $1.enableAnimation Enable/Disable animation.
* @param {*} $1.triggerAnimationOnChange Variable used to trigger the animation if it changes.
*/
function useMovingAnimation({
isSelected,
adjustScrolling,
enableAnimation,
triggerAnimationOnChange
}) {
const ref = (0, _element.useRef)();
const prefersReducedMotion = (0, _compose.useReducedMotion)() || !enableAnimation;
const [triggeredAnimation, triggerAnimation] = (0, _element.useReducer)(counterReducer, 0);
const [finishedAnimation, endAnimation] = (0, _element.useReducer)(counterReducer, 0);
const [transform, setTransform] = (0, _element.useState)({
x: 0,
y: 0
});
const previous = (0, _element.useMemo)(() => ref.current ? getAbsolutePosition(ref.current) : null, [triggerAnimationOnChange]); // Calculate the previous position of the block relative to the viewport and
// return a function to maintain that position by scrolling.
const preserveScrollPosition = (0, _element.useMemo)(() => {
if (!adjustScrolling || !ref.current) {
return () => {};
}
const scrollContainer = (0, _dom.getScrollContainer)(ref.current);
if (!scrollContainer) {
return () => {};
}
const prevRect = ref.current.getBoundingClientRect();
return () => {
const blockRect = ref.current.getBoundingClientRect();
const diff = blockRect.top - prevRect.top;
if (diff) {
scrollContainer.scrollTop += diff;
}
};
}, [triggerAnimationOnChange, adjustScrolling]);
(0, _element.useLayoutEffect)(() => {
if (triggeredAnimation) {
endAnimation();
}
}, [triggeredAnimation]);
(0, _element.useLayoutEffect)(() => {
if (!previous) {
return;
}
if (prefersReducedMotion) {
// If the animation is disabled and the scroll needs to be adjusted,
// just move directly to the final scroll position.
preserveScrollPosition();
return;
}
ref.current.style.transform = undefined;
const destination = getAbsolutePosition(ref.current);
triggerAnimation();
setTransform({
x: Math.round(previous.left - destination.left),
y: Math.round(previous.top - destination.top)
});
}, [triggerAnimationOnChange]);
function onChange({
value
}) {
if (!ref.current) {
return;
}
let {
x,
y
} = value;
x = Math.round(x);
y = Math.round(y);
const finishedMoving = x === 0 && y === 0;
ref.current.style.transformOrigin = 'center center';
ref.current.style.transform = finishedMoving ? undefined : `translate3d(${x}px,${y}px,0)`;
ref.current.style.zIndex = isSelected ? '1' : '';
preserveScrollPosition();
}
(0, _web.useSpring)({
from: {
x: transform.x,
y: transform.y
},
to: {
x: 0,
y: 0
},
reset: triggeredAnimation !== finishedAnimation,
config: {
mass: 5,
tension: 2000,
friction: 200
},
immediate: prefersReducedMotion,
onChange
});
return ref;
}
var _default = useMovingAnimation;
exports.default = _default;
//# sourceMappingURL=index.js.map