zooniverse / front-end-monorepo

A rebuild of the front-end for zooniverse.org
https://www.zooniverse.org
Apache License 2.0
104 stars 30 forks source link

Correct-A-Cell line styles vary from subject to subject #6167

Open eatyourgreens opened 1 month ago

eatyourgreens commented 1 month ago

Package

Describe the bug

The width of freehand lines depend on the size of the subject image. Compare the lines here for these two subjects, both on the same workflow:

The line width also depends on the size of the subject viewer. You can vary the rendered line width by changing the width of the browser window. Variation in size from subject to subject is a bigger effect, though.

Screenshots

1200px subject at a scale of 0.74. Rendered lines are ~2.4px thick.

Subject 93925784, with thin lines.

600px subject at a scale of 1.48. Rendered lines are ~3.7px thick.

Subject 93925884, with thick lines.

Expected behavior

Freehand line widths should be the same for each subject.

eatyourgreens commented 1 month ago

This is a similar bug to #6072.

eatyourgreens commented 1 month ago

6066 should fix this, by using non-scaling paths with a constant stroke width.

eatyourgreens commented 1 month ago

Here’s the line that causes this bug. It doesn’t properly compensate for changes in scale when image size changes. Eg. when the image scale is halved, the rendered stroke width should be doubled in order to render the same line width in CSS pixels.

In the examples above, if the 600px subject is rendered at a scale of 1 then the 1200px subject renders at a scale of 0.5. The formula here then give stroke widths of 3px (600px subject) and 3.5px (1200px subject), which renders a thicker line on the smaller image (3/600 is larger than 3.5/1200.) The rendered line width would then be 3px on the 600px subject, but 1.75px on the 1200px image.

https://github.com/zooniverse/front-end-monorepo/blob/68a3e2bee5b6eb24012037fd6351e2ac1512f638/packages/lib-classifier/src/plugins/drawingTools/experimental/components/FreehandLine/FreehandLine.js#L78

In #6066 I’ve avoided all this by having the browser handle the line scaling calculations.

eatyourgreens commented 1 month ago

Here's the maths for this bug in production. For drawing tools in general, the rendered width is a constant 2px for all image scales. For freehand lines, the rendered stroke width depends on the square of both the client width (set by the width of the volunteer's browser window) and natural width (size of the uploaded image):

// scale of the rendered subject image in the browser.
scale = clientWidth / naturalWidth;

// SVG stroke width for all drawing tools except freehand lines.
strokeWidth = 2 / scale;

// rendered line width in the browser is simply SVG width multiplied by SVG scale.
renderedStrokeWidth = (2 / scale) * scale = 2;

// Freehand lines with scale < 3.
strokeWidth = 4 - scale;
renderedStrokeWidth = (4 * scale) - scale ** 2;

// Freehand lines with scale >= 3.
strokeWidth = 1;
renderedStrokeWidth = scale;