[Refactoring] Add waitForTransitionEnd and waitForAnimationEnd helpers
This commit is contained in:
parent
f13b1950ef
commit
a77b826710
@ -22,6 +22,7 @@ import {
|
|||||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { fastRaf } from '../../util/schedulers';
|
import { fastRaf } from '../../util/schedulers';
|
||||||
|
import { waitForTransitionEnd } from '../../util/cssAnimationEndListeners';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
import useBackgroundMode from '../../hooks/useBackgroundMode';
|
import useBackgroundMode from '../../hooks/useBackgroundMode';
|
||||||
import useBeforeUnload from '../../hooks/useBeforeUnload';
|
import useBeforeUnload from '../../hooks/useBeforeUnload';
|
||||||
@ -135,17 +136,8 @@ const Main: FC<StateProps & DispatchProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent();
|
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent();
|
||||||
const middleColumnEl = document.getElementById('MiddleColumn')!;
|
|
||||||
|
|
||||||
middleColumnEl.addEventListener('transitionend', function handleTransitionEnd(e: TransitionEvent) {
|
waitForTransitionEnd(document.getElementById('MiddleColumn')!, dispatchHeavyAnimationEnd);
|
||||||
if (e.target !== e.currentTarget) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
middleColumnEl.removeEventListener('transitionend', handleTransitionEnd);
|
|
||||||
|
|
||||||
dispatchHeavyAnimationEnd();
|
|
||||||
});
|
|
||||||
}, [isLeftColumnShown]);
|
}, [isLeftColumnShown]);
|
||||||
|
|
||||||
// Dispatch heavy transition event and add body class when opening right column
|
// Dispatch heavy transition event and add body class when opening right column
|
||||||
@ -154,20 +146,13 @@ const Main: FC<StateProps & DispatchProps> = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent();
|
|
||||||
const rightColumnEl = document.getElementById('RightColumn')!;
|
|
||||||
|
|
||||||
fastRaf(() => {
|
fastRaf(() => {
|
||||||
document.body.classList.add('animating-right-column');
|
document.body.classList.add('animating-right-column');
|
||||||
});
|
});
|
||||||
|
|
||||||
rightColumnEl.addEventListener('transitionend', function handleTransitionEnd(e: TransitionEvent) {
|
const dispatchHeavyAnimationEnd = dispatchHeavyAnimationEvent();
|
||||||
if (e.target !== e.currentTarget) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rightColumnEl.removeEventListener('transitionend', handleTransitionEnd);
|
|
||||||
|
|
||||||
|
waitForTransitionEnd(document.getElementById('RightColumn')!, () => {
|
||||||
dispatchHeavyAnimationEnd();
|
dispatchHeavyAnimationEnd();
|
||||||
|
|
||||||
fastRaf(() => {
|
fastRaf(() => {
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import useForceUpdate from '../../hooks/useForceUpdate';
|
|||||||
import usePrevious from '../../hooks/usePrevious';
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||||
|
import { waitForAnimationEnd } from '../../util/cssAnimationEndListeners';
|
||||||
|
|
||||||
import './Transition.scss';
|
import './Transition.scss';
|
||||||
|
|
||||||
@ -139,8 +140,6 @@ const Transition: FC<OwnProps> = ({
|
|||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
container.classList.add('animating');
|
container.classList.add('animating');
|
||||||
|
|
||||||
const toNode = childNodes[activeIndex];
|
|
||||||
|
|
||||||
function onAnimationEnd() {
|
function onAnimationEnd() {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
container.classList.remove('animating', 'backwards');
|
container.classList.remove('animating', 'backwards');
|
||||||
@ -174,15 +173,8 @@ const Transition: FC<OwnProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (animationLevel > 0) {
|
if (animationLevel > 0) {
|
||||||
toNode.addEventListener('animationend', function handleAnimationEnd(e: AnimationEvent) {
|
const toNode = name === 'mv-slide' ? childNodes[activeIndex].firstChild! : childNodes[activeIndex];
|
||||||
if (e.target !== e.currentTarget) {
|
waitForAnimationEnd(toNode, onAnimationEnd);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
toNode.removeEventListener('animationend', handleAnimationEnd as EventListener);
|
|
||||||
|
|
||||||
onAnimationEnd();
|
|
||||||
} as EventListener);
|
|
||||||
} else {
|
} else {
|
||||||
onAnimationEnd();
|
onAnimationEnd();
|
||||||
}
|
}
|
||||||
|
|||||||
40
src/util/cssAnimationEndListeners.ts
Normal file
40
src/util/cssAnimationEndListeners.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Sometimes event is fired earlier than animation completes
|
||||||
|
const ANIMATION_END_DELAY = 50;
|
||||||
|
|
||||||
|
export function waitForTransitionEnd(node: Node, handler: NoneToVoidFunction, propertyName?: string) {
|
||||||
|
waitForEndEvent('transitionend', node, handler, propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function waitForAnimationEnd(node: Node, handler: NoneToVoidFunction, animationName?: string) {
|
||||||
|
waitForEndEvent('animationend', node, handler, animationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitForEndEvent(
|
||||||
|
eventType: 'transitionend' | 'animationend',
|
||||||
|
node: Node,
|
||||||
|
handler: NoneToVoidFunction,
|
||||||
|
detailedName?: string,
|
||||||
|
) {
|
||||||
|
let isHandled = false;
|
||||||
|
|
||||||
|
node.addEventListener(eventType, function handleAnimationEnd(e: TransitionEvent | AnimationEvent) {
|
||||||
|
if (isHandled || e.target !== e.currentTarget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detailedName && (
|
||||||
|
(e instanceof TransitionEvent && e.propertyName === detailedName)
|
||||||
|
|| (e instanceof AnimationEvent && e.animationName === detailedName)
|
||||||
|
)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isHandled = true;
|
||||||
|
|
||||||
|
node.removeEventListener(eventType, handleAnimationEnd as EventListener);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
handler();
|
||||||
|
}, ANIMATION_END_DELAY);
|
||||||
|
} as EventListener);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user