🙆♀️
Mirador 4の拡大・縮小・回転の挙動を確認する
概要
Mirador 4の拡大・縮小・回転の挙動を変更する必要があり、その変更方法に関する備忘録です。
セットアップ
以下により、ローカルでMirador 4を起動します。
git clone https://github.com/projectmirador/mirador
cd mirador
pnpm i
pnpm start
ポート4444で起動します。
zoomIn時の処理のカスタマイズ
一例ですが、zoomInボタンをクリックした際の処理を以下のように変更してみます。
/src/components/ZoomControls.js
...
handleZoomInClick() {
const { windowId, updateViewport, viewer } = this.props;
updateViewport(windowId, {
// zoom: viewer.zoom * 2,
zoom: viewer.zoom * 1.1, // 追加
rotation: viewer.rotation + 5, // 追加
x: viewer.x * 1.1, // 追加
y: viewer.y * 1.1, // 追加
});
}
...
結果、zoomInボタンを押した際に、中心が少しずれながら、拡大・回転が行われることがわかります。
これを応用することで、Mirador 3の拡大・縮小・回転等のカスタマイズを行うことができます。
immediateの設定
上記の例では、拡大や回転が完了するまで少し時間がかかっていました。これを即座に行いたい場合、以下のOpenSeadragonViewer.jsのcomponentDidUpdateをカスタマイズします。
viewerConfigオブジェクトのimmediatelyプロパティに基づき、拡大縮小や回転を即座に実施するかを設定できるようにします。
/src/components/OpenSeadragonViewer.js
...
componentDidUpdate(prevProps, prevState) {
const {
viewerConfig,
canvasWorld,
} = this.props;
const { viewer } = this.state;
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();
const 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) {
const { viewport } = viewer;
const immediately = viewerConfig.immediately || false;
if (viewerConfig.x !== viewport.centerSpringX.target.value
|| viewerConfig.y !== viewport.centerSpringY.target.value) {
viewport.panTo(viewerConfig, immediately);
}
if (viewerConfig.zoom !== viewport.zoomSpring.target.value) {
viewport.zoomTo(viewerConfig.zoom, viewerConfig, immediately);
}
if (viewerConfig.rotation !== viewport.getRotation()) {
viewport.setRotation(viewerConfig.rotation, immediately);
}
if (viewerConfig.flip !== viewport.getFlip()) {
viewport.setFlip(viewerConfig.flip);
}
}
}
...
そして、先のZoomControls.jsにおいて、immediately: true
を追加します。
/src/components/ZoomControls.js
...
handleZoomInClick() {
const { windowId, updateViewport, viewer } = this.props;
updateViewport(windowId, {
// zoom: viewer.zoom * 2,
zoom: viewer.zoom * 1.1,
rotation: viewer.rotation + 5,
x: viewer.x * 1.1,
y: viewer.y * 1.1,
immediately: true, // 追加
});
}
...
結果、以下のような挙動になります。
以前の挙動に比べて、拡大や回転が即座に行われるようになりました。
拡大や回転を即座に行いたい理由
現在、複数のウインドウで拡大・縮小・回転処理を同期するプラグインを作成しています。
この開発において、拡大・縮小・回転処理を即座に行わないと、うまく同期ができないケースがありました。
今回の修正では十分に考慮できていない点があるかと思いますが、いずれプルリクエストなどできればと思います。
まとめ
Mirador 4のプラグイン開発にあたり、参考になりましたら幸いです。
Discussion