Skip to content

Commit

Permalink
Merge pull request #4026 from ProjectMirador/loose-eq
Browse files Browse the repository at this point in the history
Improve OSD viewport initialization
  • Loading branch information
cbeer authored Dec 10, 2024
2 parents 126a357 + 530577f commit 26409c7
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 28 deletions.
6 changes: 6 additions & 0 deletions __tests__/src/lib/CanvasWorld.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ describe('CanvasWorld', () => {
expect(new CanvasWorld([1]).canvases.map(c => c.canvas)).toEqual([1]);
});
});
describe('hasDimensions', () => {
it('is true if we can calculate the canvas world dimensions', () => {
expect(new CanvasWorld([canvases[1]]).hasDimensions()).toEqual(true);
expect(new CanvasWorld([]).hasDimensions()).toEqual(false);
});
});
describe('worldBounds', () => {
it('calculates a world bounds for the given canvases', () => {
expect(new CanvasWorld([canvases[1]]).worldBounds()).toEqual([0, 0, 6501, 4421]);
Expand Down
67 changes: 40 additions & 27 deletions src/components/OpenSeadragonComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function OpenSeadragonComponent({
const id = useId();
const [grabbing, setGrabbing] = useState(false);
const viewerRef = useRef(undefined);
const initialViewportSet = useRef(false);
const [, forceUpdate] = useReducer(x => x + 1, 0);

const moveHandler = useDebouncedCallback(useCallback((event) => {
Expand All @@ -35,12 +36,46 @@ function OpenSeadragonComponent({
});
}, [onUpdateViewport]);

const setInitialBounds = useCallback(({ viewport }) => {
if (initialViewportSet.current) return;
initialViewportSet.current = true;

if (viewerConfig.x != null && viewerConfig.y != null) {
viewport.panTo(new Openseadragon.Point(viewerConfig.x, viewerConfig.y), true);
}

if (viewerConfig.zoom != null) {
viewport.zoomTo(viewerConfig.zoom, new Openseadragon.Point(viewerConfig.x, viewerConfig.y), true);
}

if (viewerConfig.rotation && viewerConfig.rotation !== viewport.getRotation()) {
viewport.setRotation(viewerConfig.rotation);
}

if (viewerConfig.flip != null && (viewerConfig.flip || false) !== viewport.getFlip()) {
viewport.setFlip(viewerConfig.flip);
}

if (!viewerConfig.x && !viewerConfig.y && !viewerConfig.zoom) {
if (viewerConfig.bounds) {
viewport.fitBounds(new Openseadragon.Rect(...viewerConfig.bounds), true);
} else {
viewport.goHome(true);
}
}
}, [initialViewportSet, viewerConfig]);

useEffect(() => {
const viewer = viewerRef.current;
if (!viewer) return;

const { viewport } = viewer;

if (!initialViewportSet.current) {
setInitialBounds(viewer);
return;
}

// @ts-expect-error
if (viewerConfig.x && viewerConfig.y
&& (Math.round(viewerConfig.x) !== Math.round(viewport.centerSpringX.target.value)
Expand All @@ -58,7 +93,7 @@ function OpenSeadragonComponent({
viewport.setRotation(viewerConfig.rotation);
}

if (viewerConfig.flip !== undefined && (viewerConfig.flip || false) !== viewport.getFlip()) {
if (viewerConfig.flip != null && (viewerConfig.flip || false) !== viewport.getFlip()) {
viewport.setFlip(viewerConfig.flip);
}

Expand All @@ -68,7 +103,7 @@ function OpenSeadragonComponent({
viewport.fitBounds(rect, false);
}
}
}, [viewerConfig, viewerRef]);
}, [initialViewportSet, setInitialBounds, viewerConfig, viewerRef]);

// initialize OSD stuff when this component is mounted
useEffect(() => {
Expand Down Expand Up @@ -99,32 +134,10 @@ function OpenSeadragonComponent({

viewerRef.current = viewer;
setViewer(viewer);
viewer.addOnceHandler('tile-loaded', () => {
const { viewport } = viewer;

if (viewerConfig.x !== undefined && viewerConfig.y !== undefined) {
viewport.panTo(new Openseadragon.Point(viewerConfig.x, viewerConfig.y), true);
}

if (viewerConfig.zoom !== undefined) {
viewport.zoomTo(viewerConfig.zoom, new Openseadragon.Point(viewerConfig.x, viewerConfig.y), true);
}

if (viewerConfig.rotation && viewerConfig.rotation !== viewport.getRotation()) {
viewport.setRotation(viewerConfig.rotation);
}

if (viewerConfig.flip !== undefined && (viewerConfig.flip || false) !== viewport.getFlip()) {
viewport.setFlip(viewerConfig.flip);
}

if (!viewerConfig.x && !viewerConfig.y && !viewerConfig.zoom) {
if (viewerConfig.bounds) {
viewport.fitBounds(new Openseadragon.Rect(...viewerConfig.bounds), true);
} else {
viewport.goHome();
}
}
viewer.addOnceHandler('tile-loaded', () => {
initialViewportSet.current = false;
setInitialBounds(viewer);
});

forceUpdate();
Expand Down
2 changes: 1 addition & 1 deletion src/components/OpenSeadragonViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function OpenSeadragonViewer({
className={classNames(ns('osd-container'))}
Container={StyledSection}
osdConfig={osdConfig}
viewerConfig={viewerConfig || { bounds: canvasWorld.worldBounds() }}
viewerConfig={viewerConfig || (canvasWorld.hasDimensions() ? { bounds: canvasWorld.worldBounds() } : undefined)}
onUpdateViewport={onViewportChange}
setViewer={setViewer}
aria-label={t('item', { label })}
Expand Down
5 changes: 5 additions & 0 deletions src/lib/CanvasWorld.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ export default class CanvasWorld {
};
}

/** */
hasDimensions() {
return this.canvasDimensions.length > 0;
}

/**
* worldBounds - calculates the "World" bounds. World in this case is canvases
* lined up horizontally starting from left to right.
Expand Down

0 comments on commit 26409c7

Please sign in to comment.