useMobileTouchMove.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
  2. import { useRef } from 'react';
  3. var SMOOTH_PTG = 14 / 15;
  4. export default function useMobileTouchMove(inVirtual, listRef, callback) {
  5. var touchedRef = useRef(false);
  6. var touchXRef = useRef(0);
  7. var touchYRef = useRef(0);
  8. var elementRef = useRef(null);
  9. // Smooth scroll
  10. var intervalRef = useRef(null);
  11. /* eslint-disable prefer-const */
  12. var cleanUpEvents;
  13. var onTouchMove = function onTouchMove(e) {
  14. if (touchedRef.current) {
  15. var currentX = Math.ceil(e.touches[0].pageX);
  16. var currentY = Math.ceil(e.touches[0].pageY);
  17. var offsetX = touchXRef.current - currentX;
  18. var offsetY = touchYRef.current - currentY;
  19. var _isHorizontal = Math.abs(offsetX) > Math.abs(offsetY);
  20. if (_isHorizontal) {
  21. touchXRef.current = currentX;
  22. } else {
  23. touchYRef.current = currentY;
  24. }
  25. var scrollHandled = callback(_isHorizontal, _isHorizontal ? offsetX : offsetY, false, e);
  26. if (scrollHandled) {
  27. e.preventDefault();
  28. }
  29. // Smooth interval
  30. clearInterval(intervalRef.current);
  31. if (scrollHandled) {
  32. intervalRef.current = setInterval(function () {
  33. if (_isHorizontal) {
  34. offsetX *= SMOOTH_PTG;
  35. } else {
  36. offsetY *= SMOOTH_PTG;
  37. }
  38. var offset = Math.floor(_isHorizontal ? offsetX : offsetY);
  39. if (!callback(_isHorizontal, offset, true) || Math.abs(offset) <= 0.1) {
  40. clearInterval(intervalRef.current);
  41. }
  42. }, 16);
  43. }
  44. }
  45. };
  46. var onTouchEnd = function onTouchEnd() {
  47. touchedRef.current = false;
  48. cleanUpEvents();
  49. };
  50. var onTouchStart = function onTouchStart(e) {
  51. cleanUpEvents();
  52. if (e.touches.length === 1 && !touchedRef.current) {
  53. touchedRef.current = true;
  54. touchXRef.current = Math.ceil(e.touches[0].pageX);
  55. touchYRef.current = Math.ceil(e.touches[0].pageY);
  56. elementRef.current = e.target;
  57. elementRef.current.addEventListener('touchmove', onTouchMove, {
  58. passive: false
  59. });
  60. elementRef.current.addEventListener('touchend', onTouchEnd, {
  61. passive: true
  62. });
  63. }
  64. };
  65. cleanUpEvents = function cleanUpEvents() {
  66. if (elementRef.current) {
  67. elementRef.current.removeEventListener('touchmove', onTouchMove);
  68. elementRef.current.removeEventListener('touchend', onTouchEnd);
  69. }
  70. };
  71. useLayoutEffect(function () {
  72. if (inVirtual) {
  73. listRef.current.addEventListener('touchstart', onTouchStart, {
  74. passive: true
  75. });
  76. }
  77. return function () {
  78. var _listRef$current;
  79. (_listRef$current = listRef.current) === null || _listRef$current === void 0 || _listRef$current.removeEventListener('touchstart', onTouchStart);
  80. cleanUpEvents();
  81. clearInterval(intervalRef.current);
  82. };
  83. }, [inVirtual]);
  84. }