UNPKG

react-native-sortables

Version:

Powerful Sortable Components for Flexible Content Reordering in React Native

97 lines (84 loc) 2.59 kB
import type { SharedValue } from 'react-native-reanimated'; import { interpolate, measure, useAnimatedReaction, useDerivedValue } from 'react-native-reanimated'; import { useMutableValue } from '../../../integrations/reanimated'; import type { Vector } from '../../../types'; import { useCommonValuesContext } from '../CommonValuesProvider'; import { usePortalContext } from '../PortalProvider'; export default function useTeleportedItemPosition( key: string, isActive: SharedValue<boolean>, activationAnimationProgress: SharedValue<number> ) { const { activeItemAbsolutePosition } = usePortalContext() ?? {}; const { containerRef, itemPositions } = useCommonValuesContext(); const dropStartValues = useMutableValue<null | { fromAbsolute: Vector; progress: number; toRelative: Vector; }>(null); // Drop start values calculation reaction useAnimatedReaction( () => ({ active: isActive.value }), ({ active }) => { if (active) { dropStartValues.value = null; } else if ( activeItemAbsolutePosition?.value && itemPositions.value[key] ) { dropStartValues.value = { fromAbsolute: activeItemAbsolutePosition.value, progress: activationAnimationProgress.value, toRelative: itemPositions.value[key] }; } } ); const absoluteItemPosition = useDerivedValue(() => { if (dropStartValues.value) { const measurements = measure(containerRef); if (!measurements) { return null; } const { fromAbsolute, progress, toRelative } = dropStartValues.value; const animate = (source: number, target: number) => interpolate( activationAnimationProgress.value, [progress, 0], [source, target] ); return { x: animate(fromAbsolute.x, measurements.pageX + toRelative.x), y: animate(fromAbsolute.y, measurements.pageY + toRelative.y) }; } return activeItemAbsolutePosition?.value ?? null; }); // Drop start values updater on target position change useAnimatedReaction( () => itemPositions.value[key], position => { if ( isActive.value || activationAnimationProgress.value === 0 || !position || !absoluteItemPosition.value ) { return; } dropStartValues.value = { fromAbsolute: absoluteItemPosition.value, progress: activationAnimationProgress.value, toRelative: position }; } ); return absoluteItemPosition; }