kinetic-slider
Version:
A WebGL-powered kinetic slider component using PIXI.js
222 lines (217 loc) • 6.83 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var react = require('react');
var gsap = require('gsap');
const isDevelopment = false;
const useMouseDrag = ({
sliderRef,
slidesRef,
currentIndex,
swipeScaleIntensity,
swipeDistance,
onSwipeLeft,
onSwipeRight,
resourceManager
}) => {
const dragStateRef = react.useRef({
isDragging: false,
startX: 0,
endX: 0,
isAnimating: false,
lastThrottleTime: 0,
activeAnimations: []
});
const isMountedRef = react.useRef(true);
const processBatchAnimations = react.useCallback(() => {
try {
const { activeAnimations } = dragStateRef.current;
if (!resourceManager || activeAnimations.length === 0) return;
resourceManager.trackAnimationBatch(activeAnimations);
activeAnimations.length = 0;
if (isDevelopment) ;
} catch (error) {
dragStateRef.current.activeAnimations = [];
}
}, [resourceManager]);
const cleanupAnimations = react.useCallback(() => {
try {
const { activeAnimations } = dragStateRef.current;
activeAnimations.forEach((tween) => {
if (tween && tween.isActive()) {
tween.kill();
}
});
activeAnimations.length = 0;
dragStateRef.current.isAnimating = false;
} catch (error) {
}
}, []);
const handleDragEffect = react.useCallback((deltaX) => {
try {
if (!isMountedRef.current) return;
const currentSlide = slidesRef.current[currentIndex.current];
if (!currentSlide) return;
const normalizedFactor = Math.min(Math.abs(deltaX) / swipeDistance, 1);
const newScale = 1 + normalizedFactor * swipeScaleIntensity;
cleanupAnimations();
const dragTween = gsap.gsap.to(currentSlide.scale, {
x: currentSlide.baseScale * newScale,
y: currentSlide.baseScale * newScale,
duration: 0.1,
ease: "power2.out",
onComplete: () => {
if (resourceManager && currentSlide) {
resourceManager.trackDisplayObject(currentSlide);
}
}
});
dragStateRef.current.activeAnimations.push(dragTween);
processBatchAnimations();
} catch (error) {
}
}, [
slidesRef,
currentIndex,
swipeScaleIntensity,
swipeDistance,
cleanupAnimations,
processBatchAnimations,
resourceManager
]);
const resetSlideScale = react.useCallback(() => {
try {
if (!isMountedRef.current) return;
const currentSlide = slidesRef.current[currentIndex.current];
if (!currentSlide) return;
cleanupAnimations();
const resetTween = gsap.gsap.to(currentSlide.scale, {
x: currentSlide.baseScale,
y: currentSlide.baseScale,
duration: 0.2,
ease: "power2.out",
onComplete: () => {
if (resourceManager && currentSlide) {
resourceManager.trackDisplayObject(currentSlide);
}
dragStateRef.current.isAnimating = false;
}
});
dragStateRef.current.activeAnimations.push(resetTween);
processBatchAnimations();
} catch (error) {
dragStateRef.current.isAnimating = false;
}
}, [
slidesRef,
currentIndex,
cleanupAnimations,
processBatchAnimations,
resourceManager
]);
const handleMouseDown = react.useCallback((event) => {
try {
const e = event;
e.preventDefault();
dragStateRef.current.isDragging = true;
dragStateRef.current.startX = e.clientX;
dragStateRef.current.endX = e.clientX;
} catch (error) {
}
}, []);
const handleMouseMove = react.useCallback((event) => {
try {
if (!dragStateRef.current.isDragging) return;
const e = event;
e.preventDefault();
const now = Date.now();
const throttleDelay = 16;
if (now - dragStateRef.current.lastThrottleTime < throttleDelay) return;
dragStateRef.current.lastThrottleTime = now;
dragStateRef.current.endX = e.clientX;
const deltaX = dragStateRef.current.endX - dragStateRef.current.startX;
handleDragEffect(deltaX);
} catch (error) {
}
}, [handleDragEffect]);
const handleMouseUp = react.useCallback((event) => {
try {
if (!dragStateRef.current.isDragging) return;
const e = event;
e.preventDefault();
dragStateRef.current.isDragging = false;
const deltaX = dragStateRef.current.endX - dragStateRef.current.startX;
resetSlideScale();
if (Math.abs(deltaX) > swipeDistance) {
setTimeout(() => {
if (!isMountedRef.current) return;
if (deltaX < 0) {
onSwipeLeft();
} else {
onSwipeRight();
}
}, 50);
}
} catch (error) {
dragStateRef.current.isDragging = false;
}
}, [resetSlideScale, swipeDistance, onSwipeLeft, onSwipeRight]);
const handleMouseLeave = react.useCallback((event) => {
try {
if (!dragStateRef.current.isDragging) return;
const e = event;
e.preventDefault();
dragStateRef.current.isDragging = false;
resetSlideScale();
} catch (error) {
dragStateRef.current.isDragging = false;
}
}, [resetSlideScale]);
react.useEffect(() => {
if (typeof window === "undefined") return;
if (!sliderRef.current) return;
try {
const slider = sliderRef.current;
isMountedRef.current = true;
const listeners = /* @__PURE__ */ new Map();
listeners.set("mousedown", [handleMouseDown]);
listeners.set("mousemove", [handleMouseMove]);
listeners.set("mouseup", [handleMouseUp]);
listeners.set("mouseleave", [handleMouseLeave]);
if (resourceManager) {
resourceManager.addEventListenerBatch(slider, listeners);
} else {
slider.addEventListener("mousedown", handleMouseDown);
slider.addEventListener("mousemove", handleMouseMove);
slider.addEventListener("mouseup", handleMouseUp);
slider.addEventListener("mouseleave", handleMouseLeave);
}
return () => {
isMountedRef.current = false;
try {
cleanupAnimations();
if (!resourceManager) {
slider.removeEventListener("mousedown", handleMouseDown);
slider.removeEventListener("mousemove", handleMouseMove);
slider.removeEventListener("mouseup", handleMouseUp);
slider.removeEventListener("mouseleave", handleMouseLeave);
}
} catch (cleanupError) {
if (isDevelopment) ;
}
};
} catch (error) {
return () => {
};
}
}, [
sliderRef,
handleMouseDown,
handleMouseMove,
handleMouseUp,
handleMouseLeave,
cleanupAnimations,
resourceManager
]);
};
exports.default = useMouseDrag;
//# sourceMappingURL=useMouseDrag.cjs.map