| 26 | * @public |
| 27 | */ |
| 28 | export function useChain( |
| 29 | refs: ReadonlyArray<SpringRef>, |
| 30 | timeSteps?: number[], |
| 31 | timeFrame = 1000 |
| 32 | ) { |
| 33 | useIsomorphicLayoutEffect(() => { |
| 34 | if (timeSteps) { |
| 35 | let prevDelay = 0 |
| 36 | each(refs, (ref, i) => { |
| 37 | const controllers = ref.current |
| 38 | if (controllers.length) { |
| 39 | let delay = timeFrame * timeSteps[i] |
| 40 | |
| 41 | // Use the previous delay if none exists. |
| 42 | if (isNaN(delay)) delay = prevDelay |
| 43 | else prevDelay = delay |
| 44 | |
| 45 | each(controllers, ctrl => { |
| 46 | each(ctrl.queue, props => { |
| 47 | // memoizing stops recursion https://github.com/pmndrs/react-spring/issues/1367 |
| 48 | const memoizedDelayProp = props.delay |
| 49 | props.delay = key => delay + callProp(memoizedDelayProp || 0, key) |
| 50 | }) |
| 51 | }) |
| 52 | |
| 53 | ref.start() |
| 54 | } |
| 55 | }) |
| 56 | } else { |
| 57 | let p: Promise<any> = Promise.resolve() |
| 58 | each(refs, ref => { |
| 59 | const controllers = ref.current |
| 60 | if (controllers.length) { |
| 61 | // Take the queue of each controller |
| 62 | const queues = controllers.map(ctrl => { |
| 63 | const q = ctrl.queue |
| 64 | ctrl.queue = [] |
| 65 | return q |
| 66 | }) |
| 67 | |
| 68 | // Apply the queue when the previous ref stops animating |
| 69 | p = p.then(() => { |
| 70 | each(controllers, (ctrl, i) => |
| 71 | each(queues[i] || [], update => ctrl.queue.push(update)) |
| 72 | ) |
| 73 | return Promise.all(ref.start()) |
| 74 | }) |
| 75 | } |
| 76 | }) |
| 77 | } |
| 78 | }) |
| 79 | } |