requestAnimationFrame.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import defined from "./defined.js";
  2. import getTimestamp from "./getTimestamp.js";
  3. let implementation;
  4. if (typeof requestAnimationFrame !== "undefined") {
  5. implementation = requestAnimationFrame;
  6. }
  7. (function () {
  8. // look for vendor prefixed function
  9. if (!defined(implementation) && typeof window !== "undefined") {
  10. const vendors = ["webkit", "moz", "ms", "o"];
  11. let i = 0;
  12. const len = vendors.length;
  13. while (i < len && !defined(implementation)) {
  14. implementation = window[`${vendors[i]}RequestAnimationFrame`];
  15. ++i;
  16. }
  17. }
  18. // build an implementation based on setTimeout
  19. if (!defined(implementation)) {
  20. const msPerFrame = 1000.0 / 60.0;
  21. let lastFrameTime = 0;
  22. implementation = function (callback) {
  23. const currentTime = getTimestamp();
  24. // schedule the callback to target 60fps, 16.7ms per frame,
  25. // accounting for the time taken by the callback
  26. const delay = Math.max(msPerFrame - (currentTime - lastFrameTime), 0);
  27. lastFrameTime = currentTime + delay;
  28. return setTimeout(function () {
  29. callback(lastFrameTime);
  30. }, delay);
  31. };
  32. }
  33. })();
  34. /**
  35. * A browser-independent function to request a new animation frame. This is used to create
  36. * an application's draw loop as shown in the example below.
  37. *
  38. * @function requestAnimationFrame
  39. *
  40. * @param {requestAnimationFrameCallback} callback The function to call when the next frame should be drawn.
  41. * @returns {Number} An ID that can be passed to {@link cancelAnimationFrame} to cancel the request.
  42. *
  43. *
  44. * @example
  45. * // Create a draw loop using requestAnimationFrame. The
  46. * // tick callback function is called for every animation frame.
  47. * function tick() {
  48. * scene.render();
  49. * Cesium.requestAnimationFrame(tick);
  50. * }
  51. * tick();
  52. *
  53. * @see {@link https://www.w3.org/TR/html51/webappapis.html#animation-frames|The Web API Animation Frames interface}
  54. */
  55. function requestAnimationFramePolyFill(callback) {
  56. // we need this extra wrapper function because the native requestAnimationFrame
  57. // functions must be invoked on the global scope (window), which is not the case
  58. // if invoked as Cesium.requestAnimationFrame(callback)
  59. return implementation(callback);
  60. }
  61. /**
  62. * A function that will be called when the next frame should be drawn.
  63. * @callback requestAnimationFrameCallback
  64. *
  65. * @param {Number} timestamp A timestamp for the frame, in milliseconds.
  66. */
  67. export default requestAnimationFramePolyFill;