feat: Add isDragging hook to mouse interaction

- useMouseInteraction 훅에 isDragging 함수를 추가했습니다.
- ImageDistortion 컴포넌트의 애니메이션 콜백에서 마우스 드래그 상태를 감지하여,
  드래그 중일 때는 자동 애니메이션의 dragVector를 0으로 설정하도록 로직을 개선했습니다.
This commit is contained in:
BaekRyang 2025-11-24 13:48:06 +09:00
parent f6ad8b11b0
commit 4bdae13f7f
8 changed files with 62 additions and 11 deletions

1
dist/index.d.mts vendored
View File

@ -557,6 +557,7 @@ declare const useMouseInteraction: (containerRef: React.RefObject<HTMLElement |
updateInteraction: (areas: DistortionArea[], deltaTime: number) => DistortionArea[]; updateInteraction: (areas: DistortionArea[], deltaTime: number) => DistortionArea[];
updateConfig: (newConfig: Partial<MouseInteractionConfig>) => void; updateConfig: (newConfig: Partial<MouseInteractionConfig>) => void;
reset: () => void; reset: () => void;
isDragging: () => boolean;
}; };
export { ANIMATION_CONFIG, AnimationLoop, type AnimationState, type AnimationTicker, type AreaBounds, DEFAULT_AREA, type DistortionArea, DistortionEditor, type DistortionEditorProps, type DistortionMovement, type EasingFunction, type EditMode, type EditorState, ImageDistortion, type ImageDistortionProps, type MotionPreset, type MouseInteractionConfig, type MouseState, type Point, SHADER_CONFIG, type ShaderConfig, ShaderManager, type ShaderUniforms, SpringPhysics, type SpringPhysicsConfig, type SpringState, ThreeScene, applyEasing, isRotationPreset, presetToVector, useAnimationFrame, useDistortionEditor, useMouseInteraction, useMouseVelocity }; export { ANIMATION_CONFIG, AnimationLoop, type AnimationState, type AnimationTicker, type AreaBounds, DEFAULT_AREA, type DistortionArea, DistortionEditor, type DistortionEditorProps, type DistortionMovement, type EasingFunction, type EditMode, type EditorState, ImageDistortion, type ImageDistortionProps, type MotionPreset, type MouseInteractionConfig, type MouseState, type Point, SHADER_CONFIG, type ShaderConfig, ShaderManager, type ShaderUniforms, SpringPhysics, type SpringPhysicsConfig, type SpringState, ThreeScene, applyEasing, isRotationPreset, presetToVector, useAnimationFrame, useDistortionEditor, useMouseInteraction, useMouseVelocity };

1
dist/index.d.ts vendored
View File

@ -557,6 +557,7 @@ declare const useMouseInteraction: (containerRef: React.RefObject<HTMLElement |
updateInteraction: (areas: DistortionArea[], deltaTime: number) => DistortionArea[]; updateInteraction: (areas: DistortionArea[], deltaTime: number) => DistortionArea[];
updateConfig: (newConfig: Partial<MouseInteractionConfig>) => void; updateConfig: (newConfig: Partial<MouseInteractionConfig>) => void;
reset: () => void; reset: () => void;
isDragging: () => boolean;
}; };
export { ANIMATION_CONFIG, AnimationLoop, type AnimationState, type AnimationTicker, type AreaBounds, DEFAULT_AREA, type DistortionArea, DistortionEditor, type DistortionEditorProps, type DistortionMovement, type EasingFunction, type EditMode, type EditorState, ImageDistortion, type ImageDistortionProps, type MotionPreset, type MouseInteractionConfig, type MouseState, type Point, SHADER_CONFIG, type ShaderConfig, ShaderManager, type ShaderUniforms, SpringPhysics, type SpringPhysicsConfig, type SpringState, ThreeScene, applyEasing, isRotationPreset, presetToVector, useAnimationFrame, useDistortionEditor, useMouseInteraction, useMouseVelocity }; export { ANIMATION_CONFIG, AnimationLoop, type AnimationState, type AnimationTicker, type AreaBounds, DEFAULT_AREA, type DistortionArea, DistortionEditor, type DistortionEditorProps, type DistortionMovement, type EasingFunction, type EditMode, type EditorState, ImageDistortion, type ImageDistortionProps, type MotionPreset, type MouseInteractionConfig, type MouseState, type Point, SHADER_CONFIG, type ShaderConfig, ShaderManager, type ShaderUniforms, SpringPhysics, type SpringPhysicsConfig, type SpringState, ThreeScene, applyEasing, isRotationPreset, presetToVector, useAnimationFrame, useDistortionEditor, useMouseInteraction, useMouseVelocity };

20
dist/index.js vendored
View File

@ -739,10 +739,15 @@ var useMouseInteraction = (containerRef, config) => {
}); });
setInteractingAreaIndices(/* @__PURE__ */ new Set()); setInteractingAreaIndices(/* @__PURE__ */ new Set());
}, []); }, []);
const isDragging = (0, import_react3.useCallback)(() => {
const mouseState = getState();
return mouseState.isDragging;
}, [getState]);
return { return {
updateInteraction, updateInteraction,
updateConfig, updateConfig,
reset reset,
isDragging
}; };
}; };
@ -917,8 +922,17 @@ var ImageDistortion = ({
const animationCallback = (0, import_react4.useCallback)((deltaTime) => { const animationCallback = (0, import_react4.useCallback)((deltaTime) => {
if (!isReady) return; if (!isReady) return;
setCurrentAreas((prevAreas) => { setCurrentAreas((prevAreas) => {
let updatedAreas = AnimationLoop.updateProgress(prevAreas, deltaTime); const isDragging = mouseInteractionHook.isDragging?.();
updatedAreas = AnimationLoop.updateAreaDragVectors(updatedAreas); let updatedAreas = prevAreas;
if (!isDragging) {
updatedAreas = AnimationLoop.updateProgress(prevAreas, deltaTime);
updatedAreas = AnimationLoop.updateAreaDragVectors(updatedAreas);
} else {
updatedAreas = prevAreas.map((area) => ({
...area,
dragVector: { x: 0, y: 0 }
}));
}
if (mouseInteraction?.enabled) { if (mouseInteraction?.enabled) {
updatedAreas = mouseInteractionHook.updateInteraction(updatedAreas, deltaTime); updatedAreas = mouseInteractionHook.updateInteraction(updatedAreas, deltaTime);
} }

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

20
dist/index.mjs vendored
View File

@ -688,10 +688,15 @@ var useMouseInteraction = (containerRef, config) => {
}); });
setInteractingAreaIndices(/* @__PURE__ */ new Set()); setInteractingAreaIndices(/* @__PURE__ */ new Set());
}, []); }, []);
const isDragging = useCallback2(() => {
const mouseState = getState();
return mouseState.isDragging;
}, [getState]);
return { return {
updateInteraction, updateInteraction,
updateConfig, updateConfig,
reset reset,
isDragging
}; };
}; };
@ -866,8 +871,17 @@ var ImageDistortion = ({
const animationCallback = useCallback3((deltaTime) => { const animationCallback = useCallback3((deltaTime) => {
if (!isReady) return; if (!isReady) return;
setCurrentAreas((prevAreas) => { setCurrentAreas((prevAreas) => {
let updatedAreas = AnimationLoop.updateProgress(prevAreas, deltaTime); const isDragging = mouseInteractionHook.isDragging?.();
updatedAreas = AnimationLoop.updateAreaDragVectors(updatedAreas); let updatedAreas = prevAreas;
if (!isDragging) {
updatedAreas = AnimationLoop.updateProgress(prevAreas, deltaTime);
updatedAreas = AnimationLoop.updateAreaDragVectors(updatedAreas);
} else {
updatedAreas = prevAreas.map((area) => ({
...area,
dragVector: { x: 0, y: 0 }
}));
}
if (mouseInteraction?.enabled) { if (mouseInteraction?.enabled) {
updatedAreas = mouseInteractionHook.updateInteraction(updatedAreas, deltaTime); updatedAreas = mouseInteractionHook.updateInteraction(updatedAreas, deltaTime);
} }

2
dist/index.mjs.map vendored

File diff suppressed because one or more lines are too long

View File

@ -214,9 +214,21 @@ export const ImageDistortion: React.FC<ImageDistortionProps> = ({
if (!isReady) return; if (!isReady) return;
setCurrentAreas((prevAreas) => { setCurrentAreas((prevAreas) => {
// 1. 기존 영역 애니메이션 업데이트 // 마우스가 드래그 중인지 확인
let updatedAreas = AnimationLoop.updateProgress(prevAreas, deltaTime); const isDragging = mouseInteractionHook.isDragging?.();
updatedAreas = AnimationLoop.updateAreaDragVectors(updatedAreas);
// 1. 자동 애니메이션 업데이트 (마우스 드래그 중이 아닐 때만)
let updatedAreas = prevAreas;
if (!isDragging) {
updatedAreas = AnimationLoop.updateProgress(prevAreas, deltaTime);
updatedAreas = AnimationLoop.updateAreaDragVectors(updatedAreas);
} else {
// 드래그 중일 때는 자동 애니메이션 dragVector를 0으로 설정
updatedAreas = prevAreas.map(area => ({
...area,
dragVector: { x: 0, y: 0 }
}));
}
// 2. 마우스 인터랙션 적용 (기존 dragVector에 스프링 변위 추가) // 2. 마우스 인터랙션 적용 (기존 dragVector에 스프링 변위 추가)
if (mouseInteraction?.enabled) { if (mouseInteraction?.enabled) {

View File

@ -194,9 +194,18 @@ export const useMouseInteraction = (
setInteractingAreaIndices(new Set()); setInteractingAreaIndices(new Set());
}, []); }, []);
/**
*
*/
const isDragging = useCallback((): boolean => {
const mouseState = getState();
return mouseState.isDragging;
}, [getState]);
return { return {
updateInteraction, updateInteraction,
updateConfig, updateConfig,
reset, reset,
isDragging,
}; };
}; };