Skip to content

Commit

Permalink
fix: Minor image annotator fixes #1726 (#1742)
Browse files Browse the repository at this point in the history
  • Loading branch information
mturoci authored Dec 8, 2022
1 parent 6c375ae commit e42ee39
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
50 changes: 48 additions & 2 deletions ui/src/image_annotator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,17 @@ describe('ImageAnnotator.tsx', () => {
expect(wave.args[name]).toMatchObject(items)
})

it('Does not draw a new rect if dimensions too small', async () => {
const { container, getByText } = render(<XImageAnnotator model={model} />)
await waitForLoad()
const canvasEl = container.querySelectorAll('canvas')[1]
fireEvent.click(getByText('Rectangle'))
fireEvent.mouseDown(canvasEl, { clientX: 110, clientY: 110, buttons: 1 })
fireEvent.click(canvasEl, { clientX: 115, clientY: 115 })

expect(wave.args[name]).toMatchObject(items)
})

it('Removes rect after clicking remove btn', async () => {
const { container, getByText } = render(<XImageAnnotator model={model} />)
await waitForLoad()
Expand Down Expand Up @@ -207,6 +218,30 @@ describe('ImageAnnotator.tsx', () => {
expect(wave.args[name]).toMatchObject([{ tag: 'person', shape: { rect: { x1: 20, x2: 110, y1: 20, y2: 110 } } }, polygon])
})

it('Moves rect correctly if click happened outside the canvas', async () => {
const { container } = render(<XImageAnnotator model={model} />)
await waitForLoad()
const canvasEl = container.querySelectorAll('canvas')[1]
fireEvent.click(canvasEl, { clientX: 50, clientY: 50 })
fireEvent.mouseDown(canvasEl, { clientX: 50, clientY: 50, buttons: 1 })
fireEvent.mouseMove(canvasEl, { clientX: 45, clientY: 50, buttons: 1 })
fireEvent.mouseLeave(canvasEl, { clientX: -10, clientY: 60, buttons: 1 })

expect(wave.args[name]).toMatchObject([{ tag: 'person', shape: { rect: { x1: 5, x2: 95, y1: 10, y2: 100 } } }, polygon])
})

it('Does not move rect if click happened outside the canvas but left mouse btn not pressed', async () => {
const { container } = render(<XImageAnnotator model={model} />)
await waitForLoad()
const canvasEl = container.querySelectorAll('canvas')[1]
fireEvent.click(canvasEl, { clientX: 50, clientY: 50 })
fireEvent.mouseDown(canvasEl, { clientX: 50, clientY: 50, buttons: 1 })
fireEvent.mouseMove(canvasEl, { clientX: 45, clientY: 50, buttons: 1 })
fireEvent.mouseLeave(canvasEl, { clientX: -10, clientY: 60 })

expect(wave.args[name]).toMatchObject(items)
})

it('Does not move rect if left mouse btn not pressed (dragging)', async () => {
const { container } = render(<XImageAnnotator model={model} />)
await waitForLoad()
Expand Down Expand Up @@ -542,6 +577,18 @@ describe('ImageAnnotator.tsx', () => {
expect(pushMock).toBeCalledTimes(1)
})

it('Calls sync after moving rect and finishing outside of canvas', async () => {
const { container } = render(<XImageAnnotator model={{ ...model, trigger: true }} />)
await waitForLoad()
const canvasEl = container.querySelectorAll('canvas')[1]
fireEvent.click(canvasEl, { clientX: 50, clientY: 50 })
fireEvent.mouseDown(canvasEl, { clientX: 50, clientY: 50, buttons: 1 })
fireEvent.mouseMove(canvasEl, { clientX: 60, clientY: 60, buttons: 1 })
fireEvent.click(canvasEl, { clientX: 60, clientY: 60 })

expect(pushMock).toBeCalledTimes(1)
})

it('Calls sync after resizing rect', async () => {
const { container } = render(<XImageAnnotator model={{ ...model, trigger: true }} />)
await waitForLoad()
Expand All @@ -560,12 +607,11 @@ describe('ImageAnnotator.tsx', () => {
const canvasEl = container.querySelectorAll('canvas')[1]
fireEvent.click(canvasEl, { clientX: 50, clientY: 50 })
await waitForLoad()
fireEvent.click(getByText('Remove selection').parentElement?.parentElement?.parentElement!)
fireEvent.click(getByText('Remove selection').parentElement!.parentElement!.parentElement!)

expect(pushMock).toBeCalledTimes(1)
})


it('Calls sync after removing polygon', async () => {
const { container, getByText } = render(<XImageAnnotator model={{ ...model, trigger: true }} />)
await waitForLoad()
Expand Down
12 changes: 12 additions & 0 deletions ui/src/image_annotator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,17 @@ export const XImageAnnotator = ({ model }: { model: ImageAnnotator }) => {
redrawExistingShapes()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [redrawExistingShapes]),

onMouseLeave = (e: React.MouseEvent<HTMLCanvasElement>) => {
const canvas = canvasRef.current
if (!canvas || e.buttons !== 1) return

setWaveArgs(drawnShapes)

polygonRef.current?.resetDragging()
rectRef.current?.resetDragging()
redrawExistingShapes()
},
onMouseDown = (e: React.MouseEvent) => {
const canvas = canvasRef.current
if (!canvas) return
Expand Down Expand Up @@ -462,6 +473,7 @@ export const XImageAnnotator = ({ model }: { model: ImageAnnotator }) => {
className={css.canvas}
onMouseMove={onMouseMove}
onMouseDown={onMouseDown}
onMouseLeave={onMouseLeave}
onKeyDown={onKeyDown}
// Do not show context menu on right click.
onContextMenu={e => e.preventDefault()}
Expand Down
4 changes: 3 additions & 1 deletion ui/src/image_annotator_rect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ export class RectAnnotator {
onClick = (cursor_x: U, cursor_y: U, tag: S, start?: Position): DrawnShape | undefined => {
let newRect
if (!this.resizedCorner && start?.dragging) {
newRect = { shape: { rect: this.createRect(start.x, cursor_x, start.y, cursor_y) }, tag }
const rect = this.createRect(start.x, cursor_x, start.y, cursor_y)
if (!rect) return
newRect = { shape: { rect }, tag }
}

this.resetDragging()
Expand Down

0 comments on commit e42ee39

Please sign in to comment.