ReactWheelHandler.js.flow 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /**
  2. * Copyright (c) 2013-present, Facebook, Inc.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * This is utility that hanlds onWheel events and calls provided wheel
  8. * callback with correct frame rate.
  9. *
  10. * @providesModule ReactWheelHandler
  11. * @typechecks
  12. */
  13. 'use strict';
  14. const emptyFunction = require("./emptyFunction");
  15. const normalizeWheel = require("./normalizeWheel");
  16. const requestAnimationFramePolyfill = require("./requestAnimationFramePolyfill");
  17. class ReactWheelHandler {
  18. /**
  19. * onWheel is the callback that will be called with right frame rate if
  20. * any wheel events happened
  21. * onWheel should is to be called with two arguments: deltaX and deltaY in
  22. * this order
  23. */
  24. constructor(
  25. /*function*/
  26. onWheel,
  27. /*boolean|function*/
  28. handleScrollX,
  29. /*boolean|function*/
  30. handleScrollY,
  31. /*?boolean|?function*/
  32. stopPropagation) {
  33. this._animationFrameID = null;
  34. this._deltaX = 0;
  35. this._deltaY = 0;
  36. this._didWheel = this._didWheel.bind(this);
  37. if (typeof handleScrollX !== 'function') {
  38. handleScrollX = handleScrollX ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
  39. }
  40. if (typeof handleScrollY !== 'function') {
  41. handleScrollY = handleScrollY ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
  42. }
  43. if (typeof stopPropagation !== 'function') {
  44. stopPropagation = stopPropagation ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
  45. }
  46. this._handleScrollX = handleScrollX;
  47. this._handleScrollY = handleScrollY;
  48. this._stopPropagation = stopPropagation;
  49. this._onWheelCallback = onWheel;
  50. this.onWheel = this.onWheel.bind(this);
  51. }
  52. onWheel(
  53. /*object*/
  54. event) {
  55. const normalizedEvent = normalizeWheel(event);
  56. const deltaX = this._deltaX + normalizedEvent.pixelX;
  57. const deltaY = this._deltaY + normalizedEvent.pixelY;
  58. const handleScrollX = this._handleScrollX(deltaX, deltaY);
  59. const handleScrollY = this._handleScrollY(deltaY, deltaX);
  60. if (!handleScrollX && !handleScrollY) {
  61. return;
  62. }
  63. this._deltaX += handleScrollX ? normalizedEvent.pixelX : 0;
  64. this._deltaY += handleScrollY ? normalizedEvent.pixelY : 0;
  65. event.preventDefault();
  66. let changed;
  67. if (this._deltaX !== 0 || this._deltaY !== 0) {
  68. if (this._stopPropagation()) {
  69. event.stopPropagation();
  70. }
  71. changed = true;
  72. }
  73. if (changed === true && this._animationFrameID === null) {
  74. this._animationFrameID = requestAnimationFramePolyfill(this._didWheel);
  75. }
  76. }
  77. _didWheel() {
  78. this._animationFrameID = null;
  79. this._onWheelCallback(this._deltaX, this._deltaY);
  80. this._deltaX = 0;
  81. this._deltaY = 0;
  82. }
  83. }
  84. module.exports = ReactWheelHandler;