diff --git a/components/converter/VisualComparison.tsx b/components/converter/VisualComparison.tsx index 1d4e65e..f77f2bb 100644 --- a/components/converter/VisualComparison.tsx +++ b/components/converter/VisualComparison.tsx @@ -16,10 +16,12 @@ export default function VisualComparison({ onValueChange, }: VisualComparisonProps) { const [draggingUnit, setDraggingUnit] = useState(null); + const [draggedPercentage, setDraggedPercentage] = useState(null); const dragStartX = useRef(0); const dragStartWidth = useRef(0); const activeBarRef = useRef(null); const lastUpdateTime = useRef(0); + const baseConversionsRef = useRef([]); // Calculate percentages for visual bars using logarithmic scale const withPercentages = useMemo(() => { if (conversions.length === 0) return []; @@ -86,10 +88,13 @@ export default function VisualComparison({ e.preventDefault(); setDraggingUnit(unit); + setDraggedPercentage(currentPercentage); dragStartX.current = e.clientX; dragStartWidth.current = currentPercentage; activeBarRef.current = barElement; - }, [onValueChange]); + // Save the current conversions as reference + baseConversionsRef.current = [...conversions]; + }, [onValueChange, conversions]); const handleMouseMove = useCallback((e: MouseEvent) => { if (!draggingUnit || !activeBarRef.current || !onValueChange) return; @@ -106,12 +111,14 @@ export default function VisualComparison({ let newPercentage = dragStartWidth.current + deltaPercentage; newPercentage = Math.max(3, Math.min(100, newPercentage)); - // Find the conversion result for this unit - const conversion = conversions.find(c => c.unit === draggingUnit); - if (!conversion) return; + // Update visual percentage immediately + setDraggedPercentage(newPercentage); - // Calculate min/max values for the scale - const values = conversions.map(c => Math.abs(c.value)); + // Use the base conversions (from when drag started) for scale calculation + const baseConversions = baseConversionsRef.current.length > 0 ? baseConversionsRef.current : conversions; + + // Calculate min/max values for the scale from BASE conversions + const values = baseConversions.map(c => Math.abs(c.value)); const maxValue = Math.max(...values); const minValue = Math.min(...values.filter(v => v > 0)); @@ -130,7 +137,9 @@ export default function VisualComparison({ } } setDraggingUnit(null); + setDraggedPercentage(null); activeBarRef.current = null; + baseConversionsRef.current = []; }, [draggingUnit, conversions, onValueChange]); // Touch drag handlers @@ -139,10 +148,13 @@ export default function VisualComparison({ const touch = e.touches[0]; setDraggingUnit(unit); + setDraggedPercentage(currentPercentage); dragStartX.current = touch.clientX; dragStartWidth.current = currentPercentage; activeBarRef.current = barElement; - }, [onValueChange]); + // Save the current conversions as reference + baseConversionsRef.current = [...conversions]; + }, [onValueChange, conversions]); const handleTouchMove = useCallback((e: TouchEvent) => { if (!draggingUnit || !activeBarRef.current || !onValueChange) return; @@ -161,10 +173,13 @@ export default function VisualComparison({ let newPercentage = dragStartWidth.current + deltaPercentage; newPercentage = Math.max(3, Math.min(100, newPercentage)); - const conversion = conversions.find(c => c.unit === draggingUnit); - if (!conversion) return; + // Update visual percentage immediately + setDraggedPercentage(newPercentage); - const values = conversions.map(c => Math.abs(c.value)); + // Use the base conversions (from when drag started) for scale calculation + const baseConversions = baseConversionsRef.current.length > 0 ? baseConversionsRef.current : conversions; + + const values = baseConversions.map(c => Math.abs(c.value)); const maxValue = Math.max(...values); const minValue = Math.min(...values.filter(v => v > 0)); @@ -182,7 +197,9 @@ export default function VisualComparison({ } } setDraggingUnit(null); + setDraggedPercentage(null); activeBarRef.current = null; + baseConversionsRef.current = []; }, [draggingUnit, conversions, onValueChange]); // Add/remove global event listeners for drag @@ -215,6 +232,8 @@ export default function VisualComparison({ {withPercentages.map(item => { const isDragging = draggingUnit === item.unit; const isDraggable = !!onValueChange; + // Use draggedPercentage if this bar is being dragged + const displayPercentage = isDragging && draggedPercentage !== null ? draggedPercentage : item.percentage; return (
@@ -255,14 +274,14 @@ export default function VisualComparison({ draggingUnit ? "transition-none" : "transition-all duration-500 ease-out" )} style={{ - width: `${item.percentage}%`, + width: `${displayPercentage}%`, backgroundColor: color, }} /> {/* Percentage label overlay */}
- {Math.round(item.percentage)}% + {Math.round(displayPercentage)}%