1
- import { createRef , useEffect , useLayoutEffect , useRef , useState } from "react" ;
1
+ import {
2
+ createRef ,
3
+ RefObject ,
4
+ useEffect ,
5
+ useLayoutEffect ,
6
+ useRef ,
7
+ useState ,
8
+ } from "react" ;
2
9
import { isSameObject , isSameObjectArray , toArray } from "../utils" ;
3
10
import {
4
11
AnimationOptions ,
@@ -20,99 +27,97 @@ export type AnimationHandle = {
20
27
rate : number | ( ( prevRate : number ) => number )
21
28
) => AnimationHandle ;
22
29
end : ( ) => Promise < void > ;
30
+ ref : RefObject < any > ;
23
31
} ;
24
- export type WithRef < T > = T & { ref : React . RefObject < any > } ;
25
32
26
33
export const useAnimation = (
27
34
keyframe : TypedKeyframe | TypedKeyframe [ ] ,
28
35
options ?: AnimationOptions
29
- ) : WithRef < AnimationHandle > => {
36
+ ) : AnimationHandle => {
30
37
const keyframeRef = useRef ( keyframe ) ;
31
38
const optionsRef = useRef ( options ) ;
32
39
33
- const [ animation , cleanup ] = useState < [ WithRef < AnimationHandle > , ( ) => void ] > (
34
- ( ) => {
35
- const ref = createRef < HTMLElement > ( ) ;
40
+ const [ animation , cleanup ] = useState < [ AnimationHandle , ( ) => void ] > ( ( ) => {
41
+ const ref = createRef < HTMLElement > ( ) ;
36
42
37
- const getTarget = ( ) => ref . current ;
38
- const getKeyframes = ( ) => toArray ( keyframeRef . current ) ;
39
- const getOptions = ( ) => optionsRef . current ;
43
+ const getTarget = ( ) => ref . current ;
44
+ const getKeyframes = ( ) => toArray ( keyframeRef . current ) ;
45
+ const getOptions = ( ) => optionsRef . current ;
40
46
41
- let cache :
42
- | [
43
- animation : Animation ,
44
- el : HTMLElement ,
45
- keyframes : TypedKeyframe [ ] ,
46
- options : AnimationOptions | undefined
47
- ]
48
- | undefined ;
49
- const initAnimation = (
50
- keyframes : TypedKeyframe [ ] ,
51
- options : AnimationOptions | undefined
52
- ) : Animation => {
53
- const el = getTarget ( ) ! ;
54
- if ( cache ) {
55
- const [ prevAnimation , prevEl , prevKeyframes , prevOptions ] = cache ;
56
- if (
57
- el === prevEl &&
58
- isSameObjectArray ( keyframes , prevKeyframes ) &&
59
- isSameObject ( options , prevOptions )
60
- ) {
61
- return prevAnimation ;
62
- }
63
- prevAnimation . cancel ( ) ;
47
+ let cache :
48
+ | [
49
+ animation : Animation ,
50
+ el : HTMLElement ,
51
+ keyframes : TypedKeyframe [ ] ,
52
+ options : AnimationOptions | undefined
53
+ ]
54
+ | undefined ;
55
+ const initAnimation = (
56
+ keyframes : TypedKeyframe [ ] ,
57
+ options : AnimationOptions | undefined
58
+ ) : Animation => {
59
+ const el = getTarget ( ) ! ;
60
+ if ( cache ) {
61
+ const [ prevAnimation , prevEl , prevKeyframes , prevOptions ] = cache ;
62
+ if (
63
+ el === prevEl &&
64
+ isSameObjectArray ( keyframes , prevKeyframes ) &&
65
+ isSameObject ( options , prevOptions )
66
+ ) {
67
+ return prevAnimation ;
64
68
}
65
- const animation = createAnimation ( el , keyframes as Keyframe [ ] , options ) ;
66
- cache = [ animation , el , keyframes , options ] ;
67
- return animation ;
68
- } ;
69
- const getAnimation = ( ) => cache ?. [ 0 ] ;
70
- const handle = createHandle ( ) ;
69
+ prevAnimation . cancel ( ) ;
70
+ }
71
+ const animation = createAnimation ( el , keyframes as Keyframe [ ] , options ) ;
72
+ cache = [ animation , el , keyframes , options ] ;
73
+ return animation ;
74
+ } ;
75
+ const getAnimation = ( ) => cache ?. [ 0 ] ;
76
+ const handle = createHandle ( ) ;
71
77
72
- const externalHandle : WithRef < AnimationHandle > = {
73
- play : ( opts ) => {
74
- handle . _play ( initAnimation ( getKeyframes ( ) , getOptions ( ) ) , opts ) ;
75
- return externalHandle ;
76
- } ,
77
- reverse : ( ) => {
78
- handle . _reverse ( initAnimation ( getKeyframes ( ) , getOptions ( ) ) ) ;
79
- return externalHandle ;
80
- } ,
81
- cancel : ( ) => {
82
- handle . _cancel ( getAnimation ( ) ) ;
83
- return externalHandle ;
84
- } ,
85
- finish : ( ) => {
86
- handle . _finish ( getAnimation ( ) ) ;
87
- return externalHandle ;
88
- } ,
89
- pause : ( ) => {
90
- handle . _pause ( getAnimation ( ) ) ;
91
- return externalHandle ;
92
- } ,
93
- persist : ( ) => {
94
- handle . _persist ( getAnimation ( ) , getTarget ( ) ! , getKeyframes ( ) ) ;
95
- return externalHandle ;
96
- } ,
97
- setTime : ( time ) => {
98
- handle . _setTime ( getAnimation ( ) , time ) ;
99
- return externalHandle ;
100
- } ,
101
- setPlaybackRate : ( rate ) => {
102
- handle . _setRate ( getAnimation ( ) , rate ) ;
103
- return externalHandle ;
104
- } ,
105
- end : ( ) => handle . _end ( getAnimation ( ) ) ,
106
- ref,
107
- } ;
108
- return [
109
- externalHandle ,
110
- ( ) => {
111
- handle . _cancel ( getAnimation ( ) ) ;
112
- } ,
113
- ] ;
114
- }
115
- ) [ 0 ] ;
78
+ const externalHandle : AnimationHandle = {
79
+ play : ( opts ) => {
80
+ handle . _play ( initAnimation ( getKeyframes ( ) , getOptions ( ) ) , opts ) ;
81
+ return externalHandle ;
82
+ } ,
83
+ reverse : ( ) => {
84
+ handle . _reverse ( initAnimation ( getKeyframes ( ) , getOptions ( ) ) ) ;
85
+ return externalHandle ;
86
+ } ,
87
+ cancel : ( ) => {
88
+ handle . _cancel ( getAnimation ( ) ) ;
89
+ return externalHandle ;
90
+ } ,
91
+ finish : ( ) => {
92
+ handle . _finish ( getAnimation ( ) ) ;
93
+ return externalHandle ;
94
+ } ,
95
+ pause : ( ) => {
96
+ handle . _pause ( getAnimation ( ) ) ;
97
+ return externalHandle ;
98
+ } ,
99
+ persist : ( ) => {
100
+ handle . _persist ( getAnimation ( ) , getTarget ( ) ! , getKeyframes ( ) ) ;
101
+ return externalHandle ;
102
+ } ,
103
+ setTime : ( time ) => {
104
+ handle . _setTime ( getAnimation ( ) , time ) ;
105
+ return externalHandle ;
106
+ } ,
107
+ setPlaybackRate : ( rate ) => {
108
+ handle . _setRate ( getAnimation ( ) , rate ) ;
109
+ return externalHandle ;
110
+ } ,
111
+ end : ( ) => handle . _end ( getAnimation ( ) ) ,
112
+ ref,
113
+ } ;
114
+ return [
115
+ externalHandle ,
116
+ ( ) => {
117
+ handle . _cancel ( getAnimation ( ) ) ;
118
+ } ,
119
+ ] ;
120
+ } ) [ 0 ] ;
116
121
117
122
useLayoutEffect ( ( ) => {
118
123
keyframeRef . current = keyframe ;
0 commit comments