UNPKG

infinity-forge

Version:
190 lines • 10.1 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useCropInteractions = useCropInteractions; var react_1 = require("react"); function useCropInteractions(_a) { var imageDimensions = _a.imageDimensions, cropArea = _a.cropArea, setCropArea = _a.setCropArea, aspectRatio = _a.aspectRatio, imageRef = _a.imageRef; var _b = (0, react_1.useState)(false), isDragging = _b[0], setIsDragging = _b[1]; var _c = (0, react_1.useState)(false), isResizing = _c[0], setIsResizing = _c[1]; var _d = (0, react_1.useState)(null), resizeDirection = _d[0], setResizeDirection = _d[1]; var _e = (0, react_1.useState)({ x: 0, y: 0 }), dragStart = _e[0], setDragStart = _e[1]; var isDraggingRef = (0, react_1.useRef)(isDragging); var isResizingRef = (0, react_1.useRef)(isResizing); var resizeDirectionRef = (0, react_1.useRef)(resizeDirection); var dragStartRef = (0, react_1.useRef)(dragStart); var imageDimensionsRef = (0, react_1.useRef)(imageDimensions); var aspectRatioRef = (0, react_1.useRef)(aspectRatio); var animationFrameRef = (0, react_1.useRef)(null); isDraggingRef.current = isDragging; isResizingRef.current = isResizing; resizeDirectionRef.current = resizeDirection; dragStartRef.current = dragStart; imageDimensionsRef.current = imageDimensions; aspectRatioRef.current = aspectRatio; var getDisplayScale = (0, react_1.useCallback)(function () { if (!imageRef.current || imageDimensionsRef.current.width === 0) return 1; return imageRef.current.clientWidth / imageDimensionsRef.current.width; }, [imageRef]); var handleStart = (0, react_1.useCallback)(function (e, action, direction) { e.preventDefault(); e.stopPropagation(); var clientX = 'touches' in e ? e.touches[0].clientX : e.clientX; var clientY = 'touches' in e ? e.touches[0].clientY : e.clientY; setDragStart({ x: clientX, y: clientY }); if (action === 'move') { setIsDragging(true); } else { setIsResizing(true); setResizeDirection(direction || 'se'); } }, []); var updateCropArea = (0, react_1.useCallback)(function (deltaX, deltaY) { if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); } animationFrameRef.current = requestAnimationFrame(function () { var scale = getDisplayScale(); var scaledDeltaX = deltaX / scale; var scaledDeltaY = deltaY / scale; if (isDraggingRef.current) { setCropArea(function (prev) { var newX = Math.max(0, Math.min(prev.x + scaledDeltaX, imageDimensionsRef.current.width - prev.width)); var newY = Math.max(0, Math.min(prev.y + scaledDeltaY, imageDimensionsRef.current.height - prev.height)); if (newX !== prev.x || newY !== prev.y) { return __assign(__assign({}, prev), { x: newX, y: newY }); } return prev; }); } else if (isResizingRef.current && resizeDirectionRef.current) { setCropArea(function (prev) { var newX = prev.x; var newY = prev.y; var newWidth = prev.width; var newHeight = prev.height; switch (resizeDirectionRef.current) { case 'n': newY = Math.max(0, Math.min(prev.y + scaledDeltaY, prev.y + prev.height - 50)); newHeight = prev.height - (newY - prev.y); break; case 's': newHeight = Math.max(50, Math.min(prev.height + scaledDeltaY, imageDimensionsRef.current.height - prev.y)); break; case 'e': newWidth = Math.max(50, Math.min(prev.width + scaledDeltaX, imageDimensionsRef.current.width - prev.x)); break; case 'w': newX = Math.max(0, Math.min(prev.x + scaledDeltaX, prev.x + prev.width - 50)); newWidth = prev.width - (newX - prev.x); break; case 'nw': newX = Math.max(0, Math.min(prev.x + scaledDeltaX, prev.x + prev.width - 50)); newY = Math.max(0, Math.min(prev.y + scaledDeltaY, prev.y + prev.height - 50)); newWidth = prev.width - (newX - prev.x); newHeight = prev.height - (newY - prev.y); break; case 'ne': newY = Math.max(0, Math.min(prev.y + scaledDeltaY, prev.y + prev.height - 50)); newWidth = Math.max(50, Math.min(prev.width + scaledDeltaX, imageDimensionsRef.current.width - prev.x)); newHeight = prev.height - (newY - prev.y); break; case 'sw': newX = Math.max(0, Math.min(prev.x + scaledDeltaX, prev.x + prev.width - 50)); newHeight = Math.max(50, Math.min(prev.height + scaledDeltaY, imageDimensionsRef.current.height - prev.y)); newWidth = prev.width - (newX - prev.x); break; case 'se': newWidth = Math.max(50, Math.min(prev.width + scaledDeltaX, imageDimensionsRef.current.width - prev.x)); newHeight = Math.max(50, Math.min(prev.height + scaledDeltaY, imageDimensionsRef.current.height - prev.y)); break; } if (aspectRatioRef.current) { var currentAspectRatio = newWidth / newHeight; if (Math.abs(currentAspectRatio - aspectRatioRef.current) > 0.01) { if (resizeDirectionRef.current.includes('e') || resizeDirectionRef.current.includes('w')) { newHeight = newWidth / aspectRatioRef.current; if (resizeDirectionRef.current.includes('n')) { newY = prev.y + prev.height - newHeight; } } else { newWidth = newHeight * aspectRatioRef.current; if (resizeDirectionRef.current.includes('w')) { newX = prev.x + prev.width - newWidth; } } } } newX = Math.max(0, Math.min(newX, imageDimensionsRef.current.width - newWidth)); newY = Math.max(0, Math.min(newY, imageDimensionsRef.current.height - newHeight)); newWidth = Math.min(newWidth, imageDimensionsRef.current.width - newX); newHeight = Math.min(newHeight, imageDimensionsRef.current.height - newY); if (newX !== prev.x || newY !== prev.y || newWidth !== prev.width || newHeight !== prev.height) { return { x: newX, y: newY, width: newWidth, height: newHeight, }; } return prev; }); } }); }, [getDisplayScale, setCropArea]); var handleEnd = (0, react_1.useCallback)(function () { if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); animationFrameRef.current = null; } setIsDragging(false); setIsResizing(false); setResizeDirection(null); }, []); (0, react_1.useEffect)(function () { var handleMove = function (e) { if (!isDraggingRef.current && !isResizingRef.current) return; e.preventDefault(); var clientX = 'touches' in e ? e.touches[0].clientX : e.clientX; var clientY = 'touches' in e ? e.touches[0].clientY : e.clientY; var deltaX = clientX - dragStartRef.current.x; var deltaY = clientY - dragStartRef.current.y; updateCropArea(deltaX, deltaY); setDragStart({ x: clientX, y: clientY }); }; if (isDragging || isResizing) { document.addEventListener('mousemove', handleMove, { passive: false }); document.addEventListener('mouseup', handleEnd); document.addEventListener('touchmove', handleMove, { passive: false }); document.addEventListener('touchend', handleEnd); } return function () { document.removeEventListener('mousemove', handleMove); document.removeEventListener('mouseup', handleEnd); document.removeEventListener('touchmove', handleMove); document.removeEventListener('touchend', handleEnd); if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); } }; }, [isDragging, isResizing, updateCropArea, handleEnd]); return { handleStart: handleStart, getDisplayScale: getDisplayScale, }; } //# sourceMappingURL=use-crop-interactions.js.map