diff --git a/ux/client/views/viz/useGetViewportCameraZoom.js b/ux/client/views/viz/useGetViewportCameraZoom.js new file mode 100644 index 00000000..aed1dfd6 --- /dev/null +++ b/ux/client/views/viz/useGetViewportCameraZoom.js @@ -0,0 +1,24 @@ +// -*- web -*- +// +// michael a.g. aïvázis +// (c) 1998-2022 all rights reserved + + +// externals +import React from 'react' + +// local +// context +import { ViewportContext } from './viewportContext' + + +// get the viewport position +export const useGetViewportCameraZoom = () => { + // grab the value + const { zoom } = React.useContext(ViewportContext) + // and return it + return zoom +} + + +// end of file diff --git a/ux/client/views/viz/usePanViewportCamera.js b/ux/client/views/viz/usePanViewportCamera.js index ffe03d1f..e4274b9d 100644 --- a/ux/client/views/viz/usePanViewportCamera.js +++ b/ux/client/views/viz/usePanViewportCamera.js @@ -15,19 +15,12 @@ import { ViewportContext } from './viewportContext' // pan the viewport camera export const usePanViewportCamera = () => { // grab the position mutator of the viewport camera - const { setPosition } = React.useContext(ViewportContext) - // build a controller that updates the viewport cameras - const pan = position => { - // adjust the viewport camera position - setPosition((old) => { - // if this is not a substantive update - if (old.x === position.x && old.y === position.y) { - // bail - return old - } - // otherwise, build the new camera position and return it - return { ...old, ...position } - }) + const { position } = React.useContext(ViewportContext) + + // build a controller that updates the viewport camera + const pan = pos => { + // update the camera position + position.current = { ...position.current, ...pos } // all done return } diff --git a/ux/client/views/viz/viewport.js b/ux/client/views/viz/viewport.js index 2fd48b72..d676daec 100644 --- a/ux/client/views/viz/viewport.js +++ b/ux/client/views/viz/viewport.js @@ -14,15 +14,15 @@ import { Mosaic } from '~/widgets' // locals // hooks import { usePanViewportCamera } from './usePanViewportCamera' -import { useGetViewportCameraPostion } from './useGetViewportCameraPosition' +import { useGetViewportCameraZoom } from './useGetViewportCameraZoom' // styles import styles from './styles' // display the datasets associated with this reader const Panel = ({ idx, view, uri, registrar, ...rest }) => { - // get my camera position - const { z } = useGetViewportCameraPostion() + // get the current zoom level + const zoom = useGetViewportCameraZoom() // and its panning controller const panViewportCamera = usePanViewportCamera() @@ -32,10 +32,10 @@ const Panel = ({ idx, view, uri, registrar, ...rest }) => { const { shape, origin, tile } = dataset // compute the dimensions of the mosaic - const width = Math.trunc(shape[1] / z) - const height = Math.trunc(shape[0] / z) + const width = Math.trunc(shape[1] / zoom) + const height = Math.trunc(shape[0] / zoom) // and fold my zoom level into the data request uri - const withZoom = [uri, z].join("/") + const withZoom = [uri, zoom].join("/") // build my scroll handler const scroll = evt => { diff --git a/ux/client/views/viz/viewportContext.js b/ux/client/views/viz/viewportContext.js index 73176c0c..77e30f97 100644 --- a/ux/client/views/viz/viewportContext.js +++ b/ux/client/views/viz/viewportContext.js @@ -12,8 +12,9 @@ export const ViewportContext = React.createContext( // the default value that consumers see when accessing the context outside a provider { // the camera position + zoom: null, + setSoom: () => { throw new Error(complaint) }, position: null, - setPosition: () => { throw new Error(complaint) } } ) @@ -24,12 +25,18 @@ export const ViewportProvider = ({ children }) => { // set up the camera position - const [position, setPosition] = React.useState({ x: 0, y: 0, z: 1 }) + // N.B.: the separation of {zoom} in a state variable vs {position} in a ref is a performance + // enhancement; modifying {position} does not cause the {viewport} to rerender, but + // modifying {zoom} must; i have to remember to update the {z} component of {position} + // whenever {zoon} is updated + const [zoom, setZoom] = React.useState(1) + const position = React.useRef({ x: 0, y: 0, z: zoom }) // assemble the context value const context = { // camera position - position, setPosition, + zoom, setZoom, + position, } // provide for my children