index.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. var now = require('performance-now')
  2. , root = typeof window === 'undefined' ? global : window
  3. , vendors = ['moz', 'webkit']
  4. , suffix = 'AnimationFrame'
  5. , raf = root['request' + suffix]
  6. , caf = root['cancel' + suffix] || root['cancelRequest' + suffix]
  7. for(var i = 0; !raf && i < vendors.length; i++) {
  8. raf = root[vendors[i] + 'Request' + suffix]
  9. caf = root[vendors[i] + 'Cancel' + suffix]
  10. || root[vendors[i] + 'CancelRequest' + suffix]
  11. }
  12. // Some versions of FF have rAF but not cAF
  13. if(!raf || !caf) {
  14. var last = 0
  15. , id = 0
  16. , queue = []
  17. , frameDuration = 1000 / 60
  18. raf = function(callback) {
  19. if(queue.length === 0) {
  20. var _now = now()
  21. , next = Math.max(0, frameDuration - (_now - last))
  22. last = next + _now
  23. setTimeout(function() {
  24. var cp = queue.slice(0)
  25. // Clear queue here to prevent
  26. // callbacks from appending listeners
  27. // to the current frame's queue
  28. queue.length = 0
  29. for(var i = 0; i < cp.length; i++) {
  30. if(!cp[i].cancelled) {
  31. try{
  32. cp[i].callback(last)
  33. } catch(e) {
  34. setTimeout(function() { throw e }, 0)
  35. }
  36. }
  37. }
  38. }, Math.round(next))
  39. }
  40. queue.push({
  41. handle: ++id,
  42. callback: callback,
  43. cancelled: false
  44. })
  45. return id
  46. }
  47. caf = function(handle) {
  48. for(var i = 0; i < queue.length; i++) {
  49. if(queue[i].handle === handle) {
  50. queue[i].cancelled = true
  51. }
  52. }
  53. }
  54. }
  55. module.exports = function(fn) {
  56. // Wrap in a new function to prevent
  57. // `cancel` potentially being assigned
  58. // to the native rAF function
  59. return raf.call(root, fn)
  60. }
  61. module.exports.cancel = function() {
  62. caf.apply(root, arguments)
  63. }
  64. module.exports.polyfill = function(object) {
  65. if (!object) {
  66. object = root;
  67. }
  68. object.requestAnimationFrame = raf
  69. object.cancelAnimationFrame = caf
  70. }