useImageTransform.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = useImageTransform;
  7. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  8. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  9. var _css = require("rc-util/lib/Dom/css");
  10. var _isEqual = _interopRequireDefault(require("rc-util/lib/isEqual"));
  11. var _raf = _interopRequireDefault(require("rc-util/lib/raf"));
  12. var _react = require("react");
  13. var initialTransform = {
  14. x: 0,
  15. y: 0,
  16. rotate: 0,
  17. scale: 1,
  18. flipX: false,
  19. flipY: false
  20. };
  21. function useImageTransform(imgRef, minScale, maxScale, onTransform) {
  22. var frame = (0, _react.useRef)(null);
  23. var queue = (0, _react.useRef)([]);
  24. var _useState = (0, _react.useState)(initialTransform),
  25. _useState2 = (0, _slicedToArray2.default)(_useState, 2),
  26. transform = _useState2[0],
  27. setTransform = _useState2[1];
  28. var resetTransform = function resetTransform(action) {
  29. setTransform(initialTransform);
  30. if (!(0, _isEqual.default)(initialTransform, transform)) {
  31. onTransform === null || onTransform === void 0 || onTransform({
  32. transform: initialTransform,
  33. action: action
  34. });
  35. }
  36. };
  37. /** Direct update transform */
  38. var updateTransform = function updateTransform(newTransform, action) {
  39. if (frame.current === null) {
  40. queue.current = [];
  41. frame.current = (0, _raf.default)(function () {
  42. setTransform(function (preState) {
  43. var memoState = preState;
  44. queue.current.forEach(function (queueState) {
  45. memoState = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, memoState), queueState);
  46. });
  47. frame.current = null;
  48. onTransform === null || onTransform === void 0 || onTransform({
  49. transform: memoState,
  50. action: action
  51. });
  52. return memoState;
  53. });
  54. });
  55. }
  56. queue.current.push((0, _objectSpread2.default)((0, _objectSpread2.default)({}, transform), newTransform));
  57. };
  58. /** Scale according to the position of centerX and centerY */
  59. var dispatchZoomChange = function dispatchZoomChange(ratio, action, centerX, centerY, isTouch) {
  60. var _imgRef$current = imgRef.current,
  61. width = _imgRef$current.width,
  62. height = _imgRef$current.height,
  63. offsetWidth = _imgRef$current.offsetWidth,
  64. offsetHeight = _imgRef$current.offsetHeight,
  65. offsetLeft = _imgRef$current.offsetLeft,
  66. offsetTop = _imgRef$current.offsetTop;
  67. var newRatio = ratio;
  68. var newScale = transform.scale * ratio;
  69. if (newScale > maxScale) {
  70. newScale = maxScale;
  71. newRatio = maxScale / transform.scale;
  72. } else if (newScale < minScale) {
  73. // For mobile interactions, allow scaling down to the minimum scale.
  74. newScale = isTouch ? newScale : minScale;
  75. newRatio = newScale / transform.scale;
  76. }
  77. /** Default center point scaling */
  78. var mergedCenterX = centerX !== null && centerX !== void 0 ? centerX : innerWidth / 2;
  79. var mergedCenterY = centerY !== null && centerY !== void 0 ? centerY : innerHeight / 2;
  80. var diffRatio = newRatio - 1;
  81. /** Deviation calculated from image size */
  82. var diffImgX = diffRatio * width * 0.5;
  83. var diffImgY = diffRatio * height * 0.5;
  84. /** The difference between the click position and the edge of the document */
  85. var diffOffsetLeft = diffRatio * (mergedCenterX - transform.x - offsetLeft);
  86. var diffOffsetTop = diffRatio * (mergedCenterY - transform.y - offsetTop);
  87. /** Final positioning */
  88. var newX = transform.x - (diffOffsetLeft - diffImgX);
  89. var newY = transform.y - (diffOffsetTop - diffImgY);
  90. /**
  91. * When zooming the image
  92. * When the image size is smaller than the width and height of the window, the position is initialized
  93. */
  94. if (ratio < 1 && newScale === 1) {
  95. var mergedWidth = offsetWidth * newScale;
  96. var mergedHeight = offsetHeight * newScale;
  97. var _getClientSize = (0, _css.getClientSize)(),
  98. clientWidth = _getClientSize.width,
  99. clientHeight = _getClientSize.height;
  100. if (mergedWidth <= clientWidth && mergedHeight <= clientHeight) {
  101. newX = 0;
  102. newY = 0;
  103. }
  104. }
  105. updateTransform({
  106. x: newX,
  107. y: newY,
  108. scale: newScale
  109. }, action);
  110. };
  111. return {
  112. transform: transform,
  113. resetTransform: resetTransform,
  114. updateTransform: updateTransform,
  115. dispatchZoomChange: dispatchZoomChange
  116. };
  117. }