83 lines
2.2 KiB
JavaScript
83 lines
2.2 KiB
JavaScript
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
import { noop } from '../util/DataUtils';
|
|
import { resolveDefaultProps } from '../util/resolveDefaultProps';
|
|
import { useAnimationManager } from './useAnimationManager';
|
|
import { getTransitionVal } from './util';
|
|
var defaultProps = {
|
|
begin: 0,
|
|
duration: 1000,
|
|
easing: 'ease',
|
|
isActive: true,
|
|
canBegin: true,
|
|
onAnimationEnd: () => {},
|
|
onAnimationStart: () => {}
|
|
};
|
|
export function CSSTransitionAnimate(outsideProps) {
|
|
var props = resolveDefaultProps(outsideProps, defaultProps);
|
|
var {
|
|
animationId,
|
|
from,
|
|
to,
|
|
attributeName,
|
|
isActive,
|
|
canBegin,
|
|
duration,
|
|
easing,
|
|
begin,
|
|
onAnimationEnd,
|
|
onAnimationStart: onAnimationStartFromProps,
|
|
children
|
|
} = props;
|
|
var animationManager = useAnimationManager(animationId + attributeName, props.animationManager);
|
|
var [style, setStyle] = useState(() => {
|
|
if (!isActive) {
|
|
return to;
|
|
}
|
|
return from;
|
|
});
|
|
var initialized = useRef(false);
|
|
var onAnimationStart = useCallback(() => {
|
|
setStyle(from);
|
|
onAnimationStartFromProps();
|
|
}, [from, onAnimationStartFromProps]);
|
|
useEffect(() => {
|
|
if (!isActive || !canBegin) {
|
|
return noop;
|
|
}
|
|
initialized.current = true;
|
|
var unsubscribe = animationManager.subscribe(setStyle);
|
|
animationManager.start([onAnimationStart, begin, to, duration, onAnimationEnd]);
|
|
return () => {
|
|
animationManager.stop();
|
|
if (unsubscribe) {
|
|
unsubscribe();
|
|
}
|
|
onAnimationEnd();
|
|
};
|
|
}, [isActive, canBegin, duration, easing, begin, onAnimationStart, onAnimationEnd, animationManager, to, from]);
|
|
if (!isActive) {
|
|
/*
|
|
* With isActive=false, the component always renders with the final style, immediately,
|
|
* and ignores all other props.
|
|
* Also there is no transition applied.
|
|
*/
|
|
return children({
|
|
[attributeName]: to
|
|
});
|
|
}
|
|
if (!canBegin) {
|
|
return children({
|
|
[attributeName]: from
|
|
});
|
|
}
|
|
if (initialized.current) {
|
|
var transition = getTransitionVal([attributeName], duration, easing);
|
|
return children({
|
|
transition,
|
|
[attributeName]: style
|
|
});
|
|
}
|
|
return children({
|
|
[attributeName]: from
|
|
});
|
|
} |