useTouchEvent.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  3. import addEventListener from "rc-util/es/Dom/addEventListener";
  4. import { useEffect, useRef, useState } from 'react';
  5. import getFixScaleEleTransPosition from "../getFixScaleEleTransPosition";
  6. function getDistance(a, b) {
  7. var x = a.x - b.x;
  8. var y = a.y - b.y;
  9. return Math.hypot(x, y);
  10. }
  11. function getCenter(oldPoint1, oldPoint2, newPoint1, newPoint2) {
  12. // Calculate the distance each point has moved
  13. var distance1 = getDistance(oldPoint1, newPoint1);
  14. var distance2 = getDistance(oldPoint2, newPoint2);
  15. // If both distances are 0, return the original points
  16. if (distance1 === 0 && distance2 === 0) {
  17. return [oldPoint1.x, oldPoint1.y];
  18. }
  19. // Calculate the ratio of the distances
  20. var ratio = distance1 / (distance1 + distance2);
  21. // Calculate the new center point based on the ratio
  22. var x = oldPoint1.x + ratio * (oldPoint2.x - oldPoint1.x);
  23. var y = oldPoint1.y + ratio * (oldPoint2.y - oldPoint1.y);
  24. return [x, y];
  25. }
  26. export default function useTouchEvent(imgRef, movable, visible, minScale, transform, updateTransform, dispatchZoomChange) {
  27. var rotate = transform.rotate,
  28. scale = transform.scale,
  29. x = transform.x,
  30. y = transform.y;
  31. var _useState = useState(false),
  32. _useState2 = _slicedToArray(_useState, 2),
  33. isTouching = _useState2[0],
  34. setIsTouching = _useState2[1];
  35. var touchPointInfo = useRef({
  36. point1: {
  37. x: 0,
  38. y: 0
  39. },
  40. point2: {
  41. x: 0,
  42. y: 0
  43. },
  44. eventType: 'none'
  45. });
  46. var updateTouchPointInfo = function updateTouchPointInfo(values) {
  47. touchPointInfo.current = _objectSpread(_objectSpread({}, touchPointInfo.current), values);
  48. };
  49. var onTouchStart = function onTouchStart(event) {
  50. if (!movable) return;
  51. event.stopPropagation();
  52. setIsTouching(true);
  53. var _event$touches = event.touches,
  54. touches = _event$touches === void 0 ? [] : _event$touches;
  55. if (touches.length > 1) {
  56. // touch zoom
  57. updateTouchPointInfo({
  58. point1: {
  59. x: touches[0].clientX,
  60. y: touches[0].clientY
  61. },
  62. point2: {
  63. x: touches[1].clientX,
  64. y: touches[1].clientY
  65. },
  66. eventType: 'touchZoom'
  67. });
  68. } else {
  69. // touch move
  70. updateTouchPointInfo({
  71. point1: {
  72. x: touches[0].clientX - x,
  73. y: touches[0].clientY - y
  74. },
  75. eventType: 'move'
  76. });
  77. }
  78. };
  79. var onTouchMove = function onTouchMove(event) {
  80. var _event$touches2 = event.touches,
  81. touches = _event$touches2 === void 0 ? [] : _event$touches2;
  82. var _touchPointInfo$curre = touchPointInfo.current,
  83. point1 = _touchPointInfo$curre.point1,
  84. point2 = _touchPointInfo$curre.point2,
  85. eventType = _touchPointInfo$curre.eventType;
  86. if (touches.length > 1 && eventType === 'touchZoom') {
  87. // touch zoom
  88. var newPoint1 = {
  89. x: touches[0].clientX,
  90. y: touches[0].clientY
  91. };
  92. var newPoint2 = {
  93. x: touches[1].clientX,
  94. y: touches[1].clientY
  95. };
  96. var _getCenter = getCenter(point1, point2, newPoint1, newPoint2),
  97. _getCenter2 = _slicedToArray(_getCenter, 2),
  98. centerX = _getCenter2[0],
  99. centerY = _getCenter2[1];
  100. var ratio = getDistance(newPoint1, newPoint2) / getDistance(point1, point2);
  101. dispatchZoomChange(ratio, 'touchZoom', centerX, centerY, true);
  102. updateTouchPointInfo({
  103. point1: newPoint1,
  104. point2: newPoint2,
  105. eventType: 'touchZoom'
  106. });
  107. } else if (eventType === 'move') {
  108. // touch move
  109. updateTransform({
  110. x: touches[0].clientX - point1.x,
  111. y: touches[0].clientY - point1.y
  112. }, 'move');
  113. updateTouchPointInfo({
  114. eventType: 'move'
  115. });
  116. }
  117. };
  118. var onTouchEnd = function onTouchEnd() {
  119. if (!visible) return;
  120. if (isTouching) {
  121. setIsTouching(false);
  122. }
  123. updateTouchPointInfo({
  124. eventType: 'none'
  125. });
  126. if (minScale > scale) {
  127. /** When the scaling ratio is less than the minimum scaling ratio, reset the scaling ratio */
  128. return updateTransform({
  129. x: 0,
  130. y: 0,
  131. scale: minScale
  132. }, 'touchZoom');
  133. }
  134. var width = imgRef.current.offsetWidth * scale;
  135. var height = imgRef.current.offsetHeight * scale;
  136. // eslint-disable-next-line @typescript-eslint/no-shadow
  137. var _imgRef$current$getBo = imgRef.current.getBoundingClientRect(),
  138. left = _imgRef$current$getBo.left,
  139. top = _imgRef$current$getBo.top;
  140. var isRotate = rotate % 180 !== 0;
  141. var fixState = getFixScaleEleTransPosition(isRotate ? height : width, isRotate ? width : height, left, top);
  142. if (fixState) {
  143. updateTransform(_objectSpread({}, fixState), 'dragRebound');
  144. }
  145. };
  146. useEffect(function () {
  147. var onTouchMoveListener;
  148. if (visible && movable) {
  149. onTouchMoveListener = addEventListener(window, 'touchmove', function (e) {
  150. return e.preventDefault();
  151. }, {
  152. passive: false
  153. });
  154. }
  155. return function () {
  156. var _onTouchMoveListener;
  157. (_onTouchMoveListener = onTouchMoveListener) === null || _onTouchMoveListener === void 0 || _onTouchMoveListener.remove();
  158. };
  159. }, [visible, movable]);
  160. return {
  161. isTouching: isTouching,
  162. onTouchStart: onTouchStart,
  163. onTouchMove: onTouchMove,
  164. onTouchEnd: onTouchEnd
  165. };
  166. }