1- import { useRef , useLayoutEffect , useCallback , MutableRefObject } from "react" ;
1+ import {
2+ useRef ,
3+ useLayoutEffect ,
4+ useCallback ,
5+ MutableRefObject ,
6+ } from "react" ;
27
38export type AnimationOptions = {
49 duration ?: number ;
@@ -22,17 +27,20 @@ export const useWebAnimation = ({
2227 delay,
2328 easing,
2429 pause
25- } : AnimationOptions ) : [ MutableRefObject < HTMLElement | undefined > , ( ) => void ] => {
30+ } : AnimationOptions ) : [
31+ MutableRefObject < HTMLElement | undefined > ,
32+ ( ) => void
33+ ] => {
2634 const ref = useRef < HTMLElement > ( ) ;
2735 const callback = useRef < any > ( ) ;
2836 const animation = useRef < Animation | undefined > ( ) ;
2937 const reverse = useRef ( false ) ;
3038
3139 const animate = useCallback (
3240 ( onComplete ?: ( ( ) => void ) ) => {
33- if ( ! ref . current || ! ref . current . animate ) {
34- if ( process . env . NODE_ENV !== ' production' ) {
35- throw new Error ( ' Please apply the ref to a dom-element.' ) ;
41+ if ( ! ref . current ) {
42+ if ( process . env . NODE_ENV !== " production" ) {
43+ throw new Error ( " Please apply the ref to a dom-element." ) ;
3644 }
3745 return ;
3846 }
@@ -41,36 +49,44 @@ export const useWebAnimation = ({
4149 ref . current ! . style [ property as any ] = getValue ( to ) ;
4250 return ;
4351 }
44-
4552 const timingObject : KeyframeAnimationOptions = {
4653 duration : duration || 750 ,
4754 iterations : 1 ,
4855 delay,
49- easing,
56+ easing
5057 } ;
5158
5259 callback . current = ( ) => {
5360 if ( infinite ) {
54- timingObject . direction = reverse . current ? "reverse" : "normal" ;
5561 reverse . current = ! reverse . current ;
56-
57- animation . current = ref . current ! . animate (
58- [ { [ property ] : getValue ( from ) } , { [ property ] : getValue ( to ) } ] ,
59- timingObject
60- ) ;
61- animation . current . addEventListener ( "finish" , callback . current ) ;
62- } else {
6362 if ( animation . current ) {
64- ref . current ! . style [ property as any ] = getValue ( to ) ;
65- if ( onComplete ) {
66- onComplete ( ) ;
67- }
63+ ref . current ! . style [ property as any ] = getValue ( reverse . current ? from : to ) ;
64+ animation . current . reverse ( ) ;
65+ } else {
66+ animation . current = ref . current ! . animate (
67+ [ { [ property ] : getValue ( from ) } , { [ property ] : getValue ( to ) } ] ,
68+ timingObject
69+ ) ;
70+ animation . current . addEventListener ( "finish" , callback . current ) ;
71+ }
72+ } else {
73+ if ( animation . current && animation . current . playState === "running" ) {
74+ reverse . current = ! reverse . current ;
75+ animation . current . reverse ( ) ;
76+ animation . current . removeEventListener ( "finish" , callback . current ) ;
77+ animation . current . addEventListener ( "finish" , callback . current ) ;
78+ } else if ( animation . current ) {
79+ ref . current ! . style [ property as any ] = getValue ( reverse . current ? from : to ) ;
80+
81+ if ( onComplete ) onComplete ( ) ;
82+
6883 if ( animation . current && callback . current ) {
69- animation . current ! . removeEventListener (
84+ animation . current . removeEventListener (
7085 "finish" ,
7186 callback . current
7287 ) ;
7388 }
89+
7490 animation . current = undefined ;
7591 callback . current = undefined ;
7692 } else {
@@ -89,16 +105,14 @@ export const useWebAnimation = ({
89105 ) ;
90106
91107 useLayoutEffect ( ( ) => {
92- if ( ! pause ) {
93- animate ( ) ;
94- }
108+ if ( ! pause ) animate ( ) ;
95109
96110 return ( ) => {
97111 if ( animation . current && ! pause ) {
112+ animation . current . cancel ( ) ;
98113 if ( animation . current && callback . current ) {
99- animation . current ! . removeEventListener ( "finish" , callback . current ) ;
114+ animation . current . removeEventListener ( "finish" , callback . current ) ;
100115 }
101- animation . current . cancel ( ) ;
102116 }
103117 } ;
104118 } , [ pause ] ) ;
0 commit comments