const availablePrefixes = [ 'moz' , 'ms' , 'webkit' ] ; function requestAnimationFramePolyfill ( ) { let lastTime = 0 ; return function ( callback ) : number { const currTime = new Date ( ) . getTime ( ) ; const timeToCall = Math . max ( 0 , 16 - ( currTime - lastTime ) ) ; const id = setTimeout ( ( ) => { callback ( currTime + timeToCall ) ; } , timeToCall ) as any ; lastTime = currTime + timeToCall ; return id ; } ; } function getRequestAnimationFrame ( ) { if ( typeof window === 'undefined' ) { return ( ) => 0 ; } if ( window . requestAnimationFrame ) { return window . requestAnimationFrame . bind ( window ) ; } const prefix = availablePrefixes . filter ( key => `${ key }RequestAnimationFrame` in window ) [ 0 ] ; return prefix ? ( window as any ) [ `${ prefix }RequestAnimationFrame` ] : requestAnimationFramePolyfill ( ) ; } export function cancelRequestAnimationFrame ( id ) { if ( typeof window === 'undefined' ) { return null ; } if ( window . cancelAnimationFrame ) { return window . cancelAnimationFrame ( id ) ; } const prefix = availablePrefixes . filter ( key => `${ key }CancelAnimationFrame` in window || `${ key }CancelRequestAnimationFrame` in window ) [ 0 ] ; return prefix ? ( ( window as any ) [ `${ prefix }CancelAnimationFrame` ] || ( window as any ) [ `${ prefix }CancelRequestAnimationFrame` ] ) . call ( this , id ) : clearTimeout ( id ) ; } export const reqAnimFrame = getRequestAnimationFrame ( ) ;