diff --git a/__tests__/src/components/OpenSeadragonViewer.test.js b/__tests__/src/components/OpenSeadragonViewer.test.js index dc5637a9637dd92cd5e2e2dc2b1649b33d79ac89..18c03a552aecae19163c931456f5255eec8ca221 100644 --- a/__tests__/src/components/OpenSeadragonViewer.test.js +++ b/__tests__/src/components/OpenSeadragonViewer.test.js @@ -232,10 +232,13 @@ describe('OpenSeadragonViewer', () => { let panTo; let zoomTo; let addHandler; + let innerTracker; + beforeEach(() => { panTo = jest.fn(); zoomTo = jest.fn(); addHandler = jest.fn(); + innerTracker = {}; wrapper = shallow( <OpenSeadragonViewer @@ -257,6 +260,7 @@ describe('OpenSeadragonViewer', () => { OpenSeadragon.mockImplementation(() => ({ addHandler, addTiledImage: jest.fn().mockResolvedValue('event'), + innerTracker, viewport: { panTo, zoomTo }, })); }); @@ -279,6 +283,12 @@ describe('OpenSeadragonViewer', () => { expect(addHandler).toHaveBeenCalledWith('animation-finish', expect.anything()); expect(addHandler).toHaveBeenCalledWith('animation-finish', wrapper.instance().onViewportChange); }); + + it('adds a mouse-move handler', () => { + wrapper.instance().componentDidMount(); + + expect(innerTracker.moveHandler).toEqual(wrapper.instance().onCanvasMouseMove); + }); }); describe('componentDidUpdate', () => { @@ -352,4 +362,16 @@ describe('OpenSeadragonViewer', () => { ); }); }); + + describe('onCanvasMouseMove', () => { + it('triggers an OSD event', () => { + const viewer = { raiseEvent: jest.fn() }; + wrapper.setState({ viewer }); + + wrapper.instance().onCanvasMouseMove('event'); + wrapper.instance().onCanvasMouseMove.flush(); + + expect(viewer.raiseEvent).toHaveBeenCalledWith('mouse-move', 'event'); + }); + }); }); diff --git a/src/components/AnnotationsOverlay.js b/src/components/AnnotationsOverlay.js index 941e3f2646f45a02849a1a94ff2062a5113aaeae..dad600e2010ff243ed1c36d5e187a9bfb1761fd9 100644 --- a/src/components/AnnotationsOverlay.js +++ b/src/components/AnnotationsOverlay.js @@ -130,11 +130,7 @@ export class AnnotationsOverlay extends Component { viewer.removeHandler('canvas-click', this.onCanvasClick); viewer.removeHandler('canvas-exit', this.onCanvasExit); viewer.removeHandler('update-viewport', this.onUpdateViewport); - - if (viewer.innerTracker - && viewer.innerTracker.moveHandler === this.onCanvasMouseMove) { - viewer.innerTracker.moveHandler = null; - } + viewer.removeHandler('mouse-move', this.onCanvasMouseMove); } /** */ @@ -263,10 +259,7 @@ export class AnnotationsOverlay extends Component { viewer.addHandler('canvas-click', this.onCanvasClick); viewer.addHandler('canvas-exit', this.onCanvasExit); viewer.addHandler('update-viewport', this.onUpdateViewport); - - if (viewer.innerTracker) { - viewer.innerTracker.moveHandler = this.onCanvasMouseMove; - } + viewer.addHandler('mouse-move', this.onCanvasMouseMove); this.updateCanvas = this.canvasUpdateCallback(); } diff --git a/src/components/OpenSeadragonViewer.js b/src/components/OpenSeadragonViewer.js index ca1469f3fed2318b822cf08499402bd00f0b8ab9..ff9f32373dd27ebfe4e3088e0ea161272eba4a1b 100644 --- a/src/components/OpenSeadragonViewer.js +++ b/src/components/OpenSeadragonViewer.js @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import debounce from 'lodash/debounce'; import isEqual from 'lodash/isEqual'; import OpenSeadragon from 'openseadragon'; import classNames from 'classnames'; @@ -24,6 +25,7 @@ export class OpenSeadragonViewer extends Component { this.ref = React.createRef(); this.apiRef = React.createRef(); OSDReferences.set(props.windowId, this.apiRef); + this.onCanvasMouseMove = debounce(this.onCanvasMouseMove.bind(this), 10); this.onViewportChange = this.onViewportChange.bind(this); this.zoomToWorld = this.zoomToWorld.bind(this); this.osdUpdating = false; @@ -62,6 +64,10 @@ export class OpenSeadragonViewer extends Component { viewer.addHandler('animation-finish', () => { this.osdUpdating = false; }); + + if (viewer.innerTracker) { + viewer.innerTracker.moveHandler = this.onCanvasMouseMove; + } } /** @@ -126,10 +132,21 @@ export class OpenSeadragonViewer extends Component { componentWillUnmount() { const { viewer } = this.state; + if (viewer.innerTracker + && viewer.innerTracker.moveHandler === this.onCanvasMouseMove) { + viewer.innerTracker.moveHandler = null; + } viewer.removeAllHandlers(); this.apiRef.current = undefined; } + /** Shim to provide a mouse-move event coming from the viewer */ + onCanvasMouseMove(event) { + const { viewer } = this.state; + + viewer.raiseEvent('mouse-move', event); + } + /** * Forward OSD state to redux */