Fixing scrollbar flickering in annotator mode (#1968)
<!-- This is an auto-generated description by cubic. --> ## Summary by cubic Fixes scrollbar flickering in annotator mode by constraining draggable inputs within the container and suppressing scroll during drag for smoother movement. - **Bug Fixes** - Added containerRef to DraggableTextInput and elementRef to calculate bounds. - Constrained drag coordinates to container size and accounted for scale. - Prevented default and stopped propagation on mousemove to avoid scroll jitter. - Passed containerRef from Annotator to DraggableTextInput. <sup>Written for commit 959605ddaa5faf23252ee797bf206c6dff46a069. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
committed by
GitHub
parent
3fd45ec253
commit
2e31c508da
@@ -26,6 +26,7 @@ interface DraggableTextInputProps {
|
|||||||
spanRef: React.MutableRefObject<HTMLSpanElement[]>;
|
spanRef: React.MutableRefObject<HTMLSpanElement[]>;
|
||||||
inputRef: React.MutableRefObject<HTMLInputElement[]>;
|
inputRef: React.MutableRefObject<HTMLInputElement[]>;
|
||||||
color: string;
|
color: string;
|
||||||
|
containerRef?: React.RefObject<HTMLDivElement | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DraggableTextInput = ({
|
export const DraggableTextInput = ({
|
||||||
@@ -40,15 +41,33 @@ export const DraggableTextInput = ({
|
|||||||
spanRef,
|
spanRef,
|
||||||
inputRef,
|
inputRef,
|
||||||
color,
|
color,
|
||||||
|
containerRef,
|
||||||
}: DraggableTextInputProps) => {
|
}: DraggableTextInputProps) => {
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
const dragOffset = useRef({ x: 0, y: 0 });
|
const dragOffset = useRef({ x: 0, y: 0 });
|
||||||
|
const elementRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleMouseMove = (e: MouseEvent) => {
|
const handleMouseMove = (e: MouseEvent) => {
|
||||||
if (isDragging) {
|
e.preventDefault();
|
||||||
const newX = e.clientX - dragOffset.current.x;
|
e.stopPropagation();
|
||||||
const newY = e.clientY - dragOffset.current.y;
|
if (isDragging && containerRef?.current && elementRef.current) {
|
||||||
|
const containerRect = containerRef.current.getBoundingClientRect();
|
||||||
|
const elementRect = elementRef.current.getBoundingClientRect();
|
||||||
|
|
||||||
|
let newX = e.clientX - dragOffset.current.x;
|
||||||
|
let newY = e.clientY - dragOffset.current.y;
|
||||||
|
|
||||||
|
// Constrain within container bounds
|
||||||
|
newX = Math.max(
|
||||||
|
0,
|
||||||
|
Math.min(newX, containerRect.width - elementRect.width),
|
||||||
|
);
|
||||||
|
newY = Math.max(
|
||||||
|
0,
|
||||||
|
Math.min(newY, containerRect.height - elementRect.height),
|
||||||
|
);
|
||||||
|
|
||||||
// Calculate adjusted coordinates for the canvas
|
// Calculate adjusted coordinates for the canvas
|
||||||
const adjustedX = newX / scale;
|
const adjustedX = newX / scale;
|
||||||
const adjustedY = newY / scale;
|
const adjustedY = newY / scale;
|
||||||
@@ -69,10 +88,11 @@ export const DraggableTextInput = ({
|
|||||||
document.removeEventListener("mouseup", handleMouseUp);
|
document.removeEventListener("mouseup", handleMouseUp);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [isDragging, input.id, onMove, scale]);
|
}, [isDragging, input.id, onMove, scale, containerRef]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
ref={elementRef}
|
||||||
className="absolute z-[999]"
|
className="absolute z-[999]"
|
||||||
style={{
|
style={{
|
||||||
left: `${input.x}px`,
|
left: `${input.x}px`,
|
||||||
|
|||||||
@@ -377,6 +377,7 @@ export const Annotator = ({
|
|||||||
spanRef={spanRef}
|
spanRef={spanRef}
|
||||||
inputRef={inputRef}
|
inputRef={inputRef}
|
||||||
color={input.color}
|
color={input.color}
|
||||||
|
containerRef={containerRef}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user