1- import Animated from './Animated'
2- import AnimatedValue from './AnimatedValue'
3- import AnimatedArray from './AnimatedArray'
4- import Interpolation from './Interpolation'
5- import {
6- interpolation as interp ,
7- now ,
8- colorNames ,
9- requestFrame as raf ,
10- } from './Globals'
11- import { start } from './FrameLoop'
121import {
13- interpolateTo ,
14- withDefault ,
15- toArray ,
162 callProp ,
3+ interpolateTo ,
174 is ,
5+ toArray ,
6+ withDefault ,
187} from '../shared/helpers'
8+ import AnimatedArray from './AnimatedArray'
9+ import AnimatedValue from './AnimatedValue'
10+ import { start } from './FrameLoop'
11+ import { colorNames , interpolation as interp , now } from './Globals'
12+
13+ type FinishedCallback = ( finished ?: boolean ) => void
14+
15+ type AnimationsFor < P > = { [ Key in keyof P ] : any }
16+
17+ type ValuesFor < P > = { [ Key in keyof P ] : any }
18+
19+ type InterpolationsFor < P > = {
20+ [ Key in keyof P ] : P [ Key ] extends ArrayLike < any >
21+ ? AnimatedArray
22+ : AnimatedValue
23+ }
1924
2025let G = 0
21- export default class Controller {
22- constructor ( props ) {
26+ class Controller < P extends any = { } > {
27+ id : number
28+
29+ idle = true
30+ hasChanged = false
31+ guid = 0
32+ local = 0
33+ props : P = { } as P
34+ merged : any = { }
35+ animations = { } as AnimationsFor < P >
36+ interpolations = { } as InterpolationsFor < P >
37+ values = { } as ValuesFor < P >
38+ configs : any = [ ]
39+ listeners : FinishedCallback [ ] = [ ]
40+ queue : any [ ] = [ ]
41+ localQueue ?: any [ ]
42+
43+ constructor ( ) {
2344 this . id = G ++
24- this . idle = true
25- this . hasChanged = false
26- this . guid = 0
27- this . local = 0
28- this . props = { }
29- this . merged = { }
30- this . animations = { }
31- this . interpolations = { }
32- this . values = { }
33- this . configs = [ ]
34- this . listeners = [ ]
35- this . queue = [ ]
36- if ( props ) this . update ( props )
3745 }
3846
3947 /** update(props)
4048 * This function filters input props and creates an array of tasks which are executed in .start()
4149 * Each task is allowed to carry a delay, which means it can execute asnychroneously */
42- update ( args ) {
50+ update ( args ?: P ) {
4351 //this._id = n + this.id
4452
4553 if ( ! args ) return this
4654 // Extract delay and the to-prop from props
47- const { delay = 0 , to, ...props } = interpolateTo ( args )
55+ const { delay = 0 , to, ...props } = interpolateTo ( args ) as any
4856 if ( is . arr ( to ) || is . fun ( to ) ) {
4957 // If config is either a function or an array queue it up as is
5058 this . queue . push ( { ...props , delay, to } )
5159 } else if ( to ) {
5260 // Otherwise go through each key since it could be delayed individually
53- let merge = { }
61+ let merge : any = { }
5462 Object . entries ( to ) . forEach ( ( [ k , v ] ) => {
5563 // Fetch delay and create an entry, consisting of the to-props, the delay, and basic props
5664 const entry = { to : { [ k ] : v } , delay : callProp ( delay , k ) , ...props }
@@ -71,7 +79,7 @@ export default class Controller {
7179
7280 /** start(onEnd)
7381 * This function either executes a queue, if present, or starts the frameloop, which animates */
74- start ( onEnd ) {
82+ start ( onEnd ?: FinishedCallback ) {
7583 // If a queue is present we must excecute it
7684 if ( this . queue . length ) {
7785 this . idle = false
@@ -92,7 +100,7 @@ export default class Controller {
92100
93101 // Go through each entry and execute it
94102 queue . forEach ( ( { delay, ...props } , index ) => {
95- const cb = finished => {
103+ const cb : FinishedCallback = finished => {
96104 if ( index === queue . length - 1 && local === this . guid && finished ) {
97105 this . idle = true
98106 if ( this . props . onRest ) this . props . onRest ( this . merged )
@@ -122,43 +130,45 @@ export default class Controller {
122130 return this
123131 }
124132
125- stop ( finished ) {
133+ stop ( finished ?: boolean ) {
126134 this . listeners . forEach ( onEnd => onEnd ( finished ) )
127135 this . listeners = [ ]
128136 return this
129137 }
130138
131- runAsync ( { delay, ...props } , onEnd ) {
139+ runAsync ( { delay, ...props } : P , onEnd : FinishedCallback ) {
132140 const local = this . local
133141 // If "to" is either a function or an array it will be processed async, therefor "to" should be empty right now
134142 // If the view relies on certain values "from" has to be present
135- let queue = Promise . resolve ( )
143+ let queue = Promise . resolve ( undefined )
136144 if ( is . arr ( props . to ) ) {
137145 for ( let i = 0 ; i < props . to . length ; i ++ ) {
138146 const index = i
139- const last = index === props . to . length - 1
140147 const fresh = { ...props , to : props . to [ index ] }
141148 if ( is . arr ( fresh . config ) ) fresh . config = fresh . config [ index ]
142- queue = queue . then ( ( ) => {
143- //this.stop()
144- if ( local === this . guid )
145- return new Promise ( r => this . diff ( interpolateTo ( fresh ) ) . start ( r ) )
146- } )
149+ queue = queue . then (
150+ ( ) : Promise < any > | void => {
151+ //this.stop()
152+ if ( local === this . guid )
153+ return new Promise ( r => this . diff ( interpolateTo ( fresh ) ) . start ( r ) )
154+ }
155+ )
147156 }
148157 } else if ( is . fun ( props . to ) ) {
149158 let index = 0
150- let last = undefined
159+ let last : Promise < any >
151160 queue = queue . then ( ( ) =>
152161 props
153162 . to (
154163 // next(props)
155- p => {
164+ ( p : P ) => {
156165 const fresh = { ...props , ...interpolateTo ( p ) }
157166 if ( is . arr ( fresh . config ) ) fresh . config = fresh . config [ index ]
158167 index ++
159168 //this.stop()
160169 if ( local === this . guid )
161170 return ( last = new Promise ( r => this . diff ( fresh ) . start ( r ) ) )
171+ return
162172 } ,
163173 // cancel()
164174 ( finished = true ) => this . stop ( finished )
@@ -169,7 +179,7 @@ export default class Controller {
169179 queue . then ( onEnd )
170180 }
171181
172- diff ( props ) {
182+ diff ( props : any ) {
173183 this . props = { ...this . props , ...props }
174184 let {
175185 from = { } ,
@@ -179,7 +189,6 @@ export default class Controller {
179189 attach,
180190 reset,
181191 immediate,
182- ref,
183192 } = this . props
184193
185194 // Reverse values when requested
@@ -195,8 +204,8 @@ export default class Controller {
195204 let target = attach && attach ( this )
196205
197206 // Reduces input { name: value } pairs into animated values
198- this . animations = Object . entries ( this . merged ) . reduce (
199- ( acc , [ name , value ] , i ) => {
207+ this . animations = Object . entries < any > ( this . merged ) . reduce (
208+ ( acc , [ name , value ] ) => {
200209 // Issue cached entries, except on reset
201210 let entry = acc [ name ] || { }
202211
@@ -222,12 +231,16 @@ export default class Controller {
222231
223232 let newValue = value
224233 if ( isInterpolation )
225- newValue = interp ( { range : [ 0 , 1 ] , output : [ value , value ] } ) ( 1 )
234+ newValue = interp ( {
235+ range : [ 0 , 1 ] ,
236+ output : [ value as string , value as string ] ,
237+ } ) ( 1 )
226238 let currentValue = interpolation && interpolation . getValue ( )
227239
228240 // Change detection flags
229241 const isFirst = is . und ( parent )
230- const isActive = ! isFirst && entry . animatedValues . some ( v => ! v . done )
242+ const isActive =
243+ ! isFirst && entry . animatedValues . some ( ( v : AnimatedValue ) => ! v . done )
231244 const currentValueDiffersFromGoal = ! is . equ ( newValue , currentValue )
232245 const hasNewGoal = ! is . equ ( newValue , entry . previous )
233246 const hasNewConfig = ! is . equ ( toConfig , entry . config )
@@ -301,7 +314,7 @@ export default class Controller {
301314 friction : withDefault ( toConfig . friction , 26 ) ,
302315 mass : withDefault ( toConfig . mass , 1 ) ,
303316 duration : toConfig . duration ,
304- easing : withDefault ( toConfig . easing , t => t ) ,
317+ easing : withDefault ( toConfig . easing , ( t : number ) => t ) ,
305318 decay : toConfig . decay ,
306319 } ,
307320 }
@@ -329,8 +342,8 @@ export default class Controller {
329342 if ( this . hasChanged ) {
330343 // Make animations available to frameloop
331344 this . configs = Object . values ( this . animations )
332- this . values = { }
333- this . interpolations = { }
345+ this . values = { } as ValuesFor < P >
346+ this . interpolations = { } as InterpolationsFor < P >
334347 for ( let key in this . animations ) {
335348 this . interpolations [ key ] = this . animations [ key ] . interpolation
336349 this . values [ key ] = this . animations [ key ] . interpolation . getValue ( )
@@ -341,14 +354,16 @@ export default class Controller {
341354
342355 destroy ( ) {
343356 this . stop ( )
344- this . props = { }
357+ this . props = { } as P
345358 this . merged = { }
346- this . animations = { }
347- this . interpolations = { }
348- this . values = { }
359+ this . animations = { } as AnimationsFor < P >
360+ this . interpolations = { } as InterpolationsFor < P >
361+ this . values = { } as ValuesFor < P >
349362 this . configs = [ ]
350363 this . local = 0
351364 }
352365
353366 getValues = ( ) => this . interpolations
354367}
368+
369+ export default Controller
0 commit comments