infinity-forge
Version:
190 lines • 10.1 kB
JavaScript
;
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