Overview
To zoom to a specific area in Mirador 3, you can use the method described below.
Specifically, it looks like this.
// Box to zoom to
const boxToZoom = {
x: 1420,
y: 1831,
width: 800,
height: 1195
};
const zoomCenter = {
x: boxToZoom.x + boxToZoom.width / 2,
y: boxToZoom.y + boxToZoom.height / 2
};
var action = Mirador.actions.updateViewport(windowId, {
x: zoomCenter.x,
y: zoomCenter.y,
zoom: 1 / boxToZoom.width
});
miradorInstance.store.dispatch(action);
Internally, it appears that OpenSeadragon’s panTo and zoomTo are used.
The issue here is that zoomTo ignores constraints when zooming, as described in the following article.
https://github.com/openseadragon/openseadragon/issues/881
To address this, as shown in the following article, adding viewer.viewport.applyConstraints(); enables zooming that respects constraints.
Below, I introduce a somewhat forceful method to apply this setting to Mirador installed via npm.
Editing Mirador
Install Mirador with the following command.
npm install mirador
A mirador folder is created under node_modules.
The following is an example of adding viewport.applyConstraints(); to a file within that folder.
...
{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps, prevState) {
var _this$props2 = this.props,
viewerConfig = _this$props2.viewerConfig,
canvasWorld = _this$props2.canvasWorld;
var viewer = this.state.viewer;
this.apiRef.current = viewer;
if (prevState.viewer === undefined) {
if (viewerConfig) {
viewer.viewport.panTo(viewerConfig, true);
viewer.viewport.zoomTo(viewerConfig.zoom, viewerConfig, true);
viewerConfig.degrees !== undefined && viewer.viewport.setRotation(viewerConfig.degrees);
viewerConfig.flip !== undefined && viewer.viewport.setFlip(viewerConfig.flip);
}
this.addAllImageSources(!viewerConfig);
return;
}
if (!this.infoResponsesMatch(prevProps.infoResponses) || !this.nonTiledImagedMatch(prevProps.nonTiledImages)) {
viewer.close();
var canvasesChanged = !isEqual(canvasWorld.canvasIds, prevProps.canvasWorld.canvasIds);
this.addAllImageSources(canvasesChanged || !viewerConfig);
} else if (!isEqual(canvasWorld.layers, prevProps.canvasWorld.layers)) {
this.refreshTileProperties();
} else if (viewerConfig && !this.osdUpdating) {
var viewport = viewer.viewport;
if (viewerConfig.x !== viewport.centerSpringX.target.value || viewerConfig.y !== viewport.centerSpringY.target.value) {
viewport.panTo(viewerConfig, false);
}
if (viewerConfig.zoom !== viewport.zoomSpring.target.value) {
viewport.zoomTo(viewerConfig.zoom, viewerConfig, false);
viewport.applyConstraints(); // Added this line
}
if (viewerConfig.rotation !== viewport.getRotation()) {
viewport.setRotation(viewerConfig.rotation);
}
if (viewerConfig.flip !== viewport.getFlip()) {
viewport.setFlip(viewerConfig.flip);
}
}
}
...
With the above setting, when zooming using Mirador.actions.updateViewport, the zoom now respects constraints.
Summary
Ideally, it would be better to modify Mirador’s source code and rebuild it, but since I was unable to build Mirador successfully, I modified the pre-built files as an alternative approach.
I will continue investigating how to modify from the source code, but I hope this is helpful to others.