• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zooniverse / front-end-monorepo / 13440953185

20 Feb 2025 05:18PM UTC coverage: 75.515% (-0.03%) from 75.544%
13440953185

push

github

web-flow
refactor(drawing-tools): replace scale prop with useScale hook (#6697)

* refactor(drawing-tools): replace scale prop with useScale hook

Replace the `scale` prop with a `useScale` hook in the drawing tools. It's useful to imitate `vector-effect: non-scaling-size` by inverting any scaling applied to a parent SVG element. The drawing tools remain the same size on the screen, no matter whether the subject image is zoomed in or zoomed out.

The scale it returns is the scale factor of the current subject, calculated from the size of the drawing canvas (client width / intrinsic width.)

```jsx
const scale = useScale();

return (
  <g ref={root} transform={`scale(1 / ${scale})`}>
    <circle cx={0} cy={0} r={10} />
  </g>
);
```

* add useScale to subject viewers

* Docs and example

* type annotations for useScale and SVGContext

* use stored svgContext.rotate in scale calculation

* Remove scale from drawing API readme

* Add DragHandle props for polygon onPointerDown

* clean up DragHandle props

---------

Co-authored-by: Mark Bouslog <mark@zooniverse.org>

10839 of 16550 branches covered (65.49%)

Branch coverage included in aggregate %.

54 of 63 new or added lines in 18 files covered. (85.71%)

1 existing line in 1 file now uncovered.

16952 of 20252 relevant lines covered (83.71%)

398.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

26.67
/packages/lib-classifier/src/plugins/drawingTools/components/UndoButton/UndoButton.js
1
import { number, func } from 'prop-types'
1✔
2
import styled from 'styled-components'
1✔
3
import { Tooltip } from '@zooniverse/react-components'
4

5
import useScale from '../../hooks/useScale'
4✔
6

7
const StyledGroup = styled('g')`
1✔
8
  &:hover {
9
    cursor: pointer;
10
  }
11
`
12

NEW
13
function UndoButton({ x, y, undoDrawing }) {
×
NEW
14
  const scale = useScale()
×
15
  const ARIA_LABEL = 'Undo'
×
16
  const STROKE_COLOR = 'black'
×
17
  const ARROW_STROKE_COLOR = 'white'
×
18
  const FILL_COLOR = 'black'
×
19
  const STROKE_WIDTH = 1.5
×
20
  const ARROW_STROKE_WIDTH = 0.5
×
21
  const undoTransform = `translate(${x + 15}, ${y - 35}) scale(${1 / scale})`
×
22
  const cx = x + 20
×
23
  const cy = y - 30
×
24

25
  function onKeyDown(event) {
26
    switch (event.key) {
×
27
      case 'Enter':
28
      case ' ': {
29
        return onPointerDown(event)
×
30
      }
31
      default: {
32
        return true
×
33
      }
34
    }
35
  }
36

37
  function onPointerDown(event) {
38
    event.preventDefault()
×
39
    event.stopPropagation()
×
40
    undoDrawing()
×
41
    return false
×
42
  }
43

44
  return (
×
45
    <StyledGroup
46
      x={cx}
47
      y={cy}
48
      role='button'
49
      onKeyDown={onKeyDown}
50
      onPointerDown={onPointerDown}
51
      aria-label={ARIA_LABEL}
52
      focusable='true'
53
      stroke={STROKE_COLOR}
54
      strokeWidth={STROKE_WIDTH}
55
    >
56
      <Tooltip label='Undo'>
57
        <path
58
          d='M24 12c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 6.628 5.372 12 12 12s12-5.372 12-12zM6 12l6-6v4.5h6v3h-6v4.5l-6-6z'
59
          transform={undoTransform}
60
          fill={FILL_COLOR}
61
          stroke={ARROW_STROKE_COLOR}
62
          strokeWidth={ARROW_STROKE_WIDTH}
63
        ></path>
64
      </Tooltip>
65
    </StyledGroup>
66
  )
67
}
68

69
UndoButton.propTypes = {
1✔
70
  /**
71
    x position of the vertex closets to the origin
72
  */
73
  x: number,
74
  /**
75
    y position of the vertex closets to the origin
76
  */
77
  y: number,
78
  /**
79
    Callback to shorten path array
80
  */
81
  undoDrawing: func
82
}
1✔
83

84
export default UndoButton
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc