-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Description
Describe the bug
When labeling an image with the brush tool, the white circular cursor that indicates brush size is smaller than the actual painted stroke. The mismatch is noticeable when clicking/dabbing; the colored area is larger than the cursor preview.
To Reproduce
Steps to reproduce the behavior:
- Open an image labeling project that uses Brush/BrushLabels for segmentation.
- Select the Brush tool.
- Set a brush size (e.g., 5) using the slider.
- Click once to paint a dot.
- Compare the painted dot size to the cursor's white circle.
Expected behavior
The painted dot should match the cursor preview size (the white circle).
Environment:
- OS: macOS 14.4.1
- Label Studio Version 1.20.0
- Browser: Chrome 144.0.7559.97
- Zoom level: any
Additional context
The cursor size appears to be based on the raw brush size, while the actual stroke size is scaled by zoom, which may cause the mismatch when zoomed.
I found the cursor sizing and the actual paint size, and they’re using different scaling. That’s likely why the painted stroke looks larger than the white circle, especially when zoom isn’t 1.
Cursor size is defined in canvas.js (line 357) (createBrushSizeCircleCursor) and used in Brush.jsx (line 233) with self.strokeWidth directly.
Actual brush stroke width is applied in BrushRegion.jsx (line 308) as pathPoints.strokeWidth * self.scaleX * self.parent.stageScale, which scales by zoom.
To make them match, you can scale the cursor size by the same factor (at least stageScale, and possibly scaleX if you see distortion) and refresh the cursor on zoom changes. Example direction: in Brush.jsx (line 233), use self.strokeWidth * (self.obj?.stageScale ?? 1) and ensure updateCursor() runs when zoom changes (e.g., after handleZoom/updateImageAfterZoom). Note the cursor has a browser max size (~128px), so very large zooms may still cap out.
