Miradorプラグインアーキテクチャの概要

Miradorは、IIIFビューアとして広く利用されているオープンソースソフトウェアであり、その最大の特徴の一つがプラグインによる拡張性です。Miradorのプラグインアーキテクチャは、Reactコンポーネントの差し込みとReduxストアの拡張を組み合わせた設計になっており、ビューア本体のコードを直接変更することなく、機能を追加・変更できます。

プラグインは主に以下の要素で構成されます。

  • target: プラグインを配置する場所(Miradorのコンポーネント名)を指定する。例えばWindowTopMenuはウインドウ上部のメニュー、WindowTopBarPluginAreaはウインドウバーの直接表示領域、OpenSeadragonViewerはビューア本体への追加を表す
  • mode: コンポーネントの追加方法を指定する。addは既存のコンポーネントに追加、wrapは既存のコンポーネントをラップして機能を上書きする
  • component: 実際に表示するReactコンポーネント
  • mapDispatchToProps: Reduxのdispatchアクションをpropsとして渡す設定
  • mapStateToProps: Reduxのstateから必要な値をpropsとして取得する設定
  • config: 翻訳データなどの追加設定

以下は、ウインドウコピー機能を追加するプラグインの基本構造です。

export default {
  target: 'WindowTopMenu',
  mode: 'add',
  component: CopyWindowComponent,
  mapDispatchToProps: mapDispatchToProps,
  mapStateToProps: mapStateToProps,
};

targetに指定可能なコンポーネント名は、Miradorのソースコードのcontainersディレクトリで確認できます。WindowTopBarPluginAreaを指定するとウインドウバーに直接アイコンを表示でき、WindowTopBarPluginMenuを指定すると三点ドットメニュー内にプラグインの項目を表示できるなど、用途に応じて使い分けが可能です。

主要なプラグインの紹介

Miradorのエコシステムには、公式およびコミュニティによる多数のプラグインが存在します。以下に代表的なものを紹介します。

mirador-image-tools

画像の操作機能を提供する公式プラグインです。90度単位の回転、明度・コントラストの調整、反転といった基本的な画像操作が可能になります。デジタルアーカイブの資料閲覧において、劣化した画像の視認性向上などに活用できます。

mirador-annotations

IIIFアノテーションの作成・編集・保存機能を提供するプラグインです。デフォルトではローカルストレージにアノテーションが保存されますが、アダプタ機構により保存先を変更できます。例えば、Firestore用のアダプタを実装すれば、ユーザごとにクラウド上でアノテーションを管理することも可能です。Firestoreアダプタでは、Firebase Authenticationと連携してユーザ認証を行い、ログインユーザの付与したアノテーションのみを表示・編集できるようにした実装例があります。

mirador-sync-windows

複数ウインドウ間の表示を同期するプラグインです。異なるマニフェストの画像を並べて表示し、一方をスクロール・ズームすると他方も連動して動きます。資料の比較研究に有用です。

mirador-textoverlay

OCR結果やトランスクリプションに基づく選択可能なテキストオーバーレイを表示するプラグインです。ALTO XMLやhOCRなどの形式に対応しています。日本語の縦書きテキストには標準では対応していませんが、フォークにより縦書き表示を実現した事例もあります。マニフェストのCanvas内でseeAlsoプロパティによりALTO XMLファイルへのURLを指定する形式で利用します。

mirador-rotation-plugin

任意の角度で画像を回転できるプラグインです。mirador-image-toolsの90度単位回転に対し、1度単位のスライダーによる微調整が可能です。90度単位の回転ボタン、リセットボタン、ヘルプ機能なども搭載しています。URLパラメータによるマニフェストや初期回転角度の指定にも対応しており、外部からの呼び出しや共有が容易です。

mirador-disable-zoom

ズーム操作を無効化するプラグインです。プレゼンテーション用途や、意図しないズーム操作を防ぎたい場合に利用します。UCLA Libraryによる Mirador 2 版を参考に、Mirador 4向けに再実装されています。

mirador-layer-slideshow-plugin

マニフェスト内のレイヤーをスライドショー形式で自動切り替えするプラグインです。「起絵図」のように、同一キャンバス上の複数レイヤーを順次表示したい場合に活用できます。

プラグインの導入方法

npmパッケージを利用する方法

プラグインがnpmパッケージとして公開されている場合、以下のようにインストールして使用します。

npm install mirador mirador-rotation

Miradorの初期化時に、プラグイン配列を第二引数として渡します。

import Mirador from 'mirador';
import { miradorRotationPlugin } from 'mirador-rotation';

Mirador.viewer({
  id: 'mirador-viewer',
  windows: [{
    rotationEnabled: true,
    manifestId: 'https://example.com/manifest.json',
  }],
}, [...miradorRotationPlugin]);

scriptタグで読み込む方法

CDNやビルド済みファイルを利用して、HTMLから直接読み込む方法もあります。この場合、Miradorとプラグインを1つのJavaScriptファイルにバンドルする必要があります(後述の「複数プラグインの統合とバンドル」を参照)。

<div id="demo"></div>
<script src="mirador.js"></script>
<script>
  Mirador.viewer({
    id: 'demo',
    windows: [{
      rotationEnabled: true,
      manifestId: 'https://example.com/manifest.json',
    }],
  }, [...miradorRotationPlugin]);
</script>

カスタムプラグイン開発の基本

自分でプラグインを開発する場合の手順を、回転プラグインの開発を例に解説します。

1. 開発環境の準備

公式のプラグインデモリポジトリ(mirador-plugin-demos)や、既存のプラグイン(例: mirador-dl-plugin)をクローンし、ベースとして利用するのが効率的です。

2. プラグインの構造を定義する

まず、エクスポートするプラグイン設定を定義します。1つのプラグインパッケージに複数のコンポーネントを含めることもできます。例えば、ズーム無効化プラグインでは、ビューアのズーム動作を制御するコンポーネントとUIボタンのコンポーネントを分けて定義しています。

export const miradorDisableZoomPlugin = [
  {
    target: 'OpenSeadragonViewer',
    mode: 'add',
    component: MiradorDisableZoom,
    mapStateToProps: (state, { windowId }) => ({
      enabled: getWindowConfig(state, { windowId }).disableZoomEnabled || false,
    }),
  },
  {
    target: 'WindowTopBarPluginArea',
    component: MiradorDisableZoomMenuItem,
    mode: 'add',
    mapDispatchToProps: {
      updateWindow: actions.updateWindow,
    },
    mapStateToProps: (state, { windowId }) => ({
      enabled: getWindowConfig(state, { windowId }).disableZoomEnabled || false,
    }),
    config: {
      translations,
    },
  },
];

3. Reactコンポーネントを実装する

mapDispatchToPropsでpropsに渡したアクションをコンポーネント内で利用します。Reduxのstateやdispatchを活用し、Miradorの内部状態を読み書きします。

4. 翻訳への対応

多言語対応を行う場合、翻訳ファイルを作成し、プラグインのconfig.translationsとして設定します。

export default {
  en: {
    rotateLeft: 'Rotate 90° left',
    rotateRight: 'Rotate 90° right',
  },
  ja: {
    rotateLeft: '左に90度回転',
    rotateRight: '右に90度回転',
  },
};

プラグインのnpm公開方法

開発したプラグインをnpmで公開するための手順を紹介します。

  1. package.jsonの設定: パッケージ名、バージョン、エントリポイントを適切に設定します。スコープ付きパッケージ名(例: @nakamura196/mirador)を使うことで名前の衝突を避けられます

  2. ビルド設定: ViteやParcelなどのビルドツールでライブラリとしてビルドできるように設定します

  3. 公開: npm publish(またはpnpm publish)でnpmレジストリに公開します

カスタマイズしたMirador本体をnpmパッケージとして公開する場合は、公式リポジトリをフォークし、変更を加えた後、パッケージ名を変更して公開します。

{
  "name": "@yourscope/mirador",
  "version": "4.0.0",
  "main": "dist/cjs/src/index.js",
  "module": "dist/es/src/index.js"
}

Mirador 3から4へのプラグイン移行ガイド

2024年にMirador 4がリリースされ、プラグインの移行が必要となりました。主な変更点と移行時の注意点を整理します。

主な変更点

項目Mirador 3Mirador 4
React16〜1718
UIライブラリMaterial-UI v4MUI v7
ビルドツールnwb / WebpackVite / Parcel
アクションのインポートimport { actions } from 'mirador'import { receiveAnnotation } from 'mirador'

移行時の主なポイント

アクション・セレクターのインポート変更

Mirador 3ではネストされた構造でアクセスしていたものが、Mirador 4ではフラットなnamed exportに変更されています。

// Mirador 3
import { actions, selectors } from 'mirador';
actions.receiveAnnotation(...);

// Mirador 4
import { receiveAnnotation, getVisibleCanvases } from 'mirador';
receiveAnnotation(...);

Material-UIからMUIへの移行

@material-ui/*@mui/*に変更し、makeStylessx propに置き換えます。Gridコンポーネントではitemxssizeに統合されています。

refフォワーディングへの対応

MUI v5以降のMenuListautoFocusItemは、子コンポーネントがforwardRefを使ってrefをDOM要素に正しくフォワードすることを要求します。クラスコンポーネントから関数コンポーネントへの書き換えが必要になるケースがあります。

ConnectedコンポーネントとBaseコンポーネントの区別

Miradorは一部のコンポーネントについて、ベース版とRedux接続版の2種類をエクスポートしています。プラグインからはConnectedCompanionWindowのようなRedux接続版を使用する必要がある場合があります。

複数プラグインの統合とバンドル

複数のプラグインをMiradorと一緒に1つのJavaScriptファイルにまとめて配布する方法を解説します。

mirador-integrationの活用

公式のmirador-integrationリポジトリを参考に、統合環境を構築します。

// index.js
import Mirador, * as MiradorAll from 'mirador';
import { miradorRotationPlugin } from 'mirador-rotation';

window.Mirador = { ...Mirador, ...MiradorAll };
window.miradorRotationPlugin = miradorRotationPlugin;

* as MiradorAllでnamed exportsをすべて取得し、スプレッド構文でフラット化している点が重要です。これにより、UMDビルドと同様にMirador.addCompanionWindow()のようなフラットなAPI呼び出しが可能になります。単純にimport Mirador from 'mirador'だけでは、default exportのみが取得され、Mirador.actions.addCompanionWindow()というネストされた構造になってしまいます。

Parcelでのビルド設定

グローバル変数として出力するために、package.jsonで以下のように設定します。

{
  "source": "index.js",
  "targets": {
    "global": {
      "outputFormat": "global",
      "distDir": "./dist"
    }
  },
  "scripts": {
    "build": "parcel build --target global"
  }
}

Parcelはデフォルトでハッシュ付きのファイル名を生成するため、必要に応じてビルド後にリネームスクリプトを実行します。

ビルド結果の利用

ビルド後のdist/mirador.jsを任意のHTMLから読み込み、複数プラグインを含むMiradorを利用できます。

<script src="mirador.js"></script>
<script>
  const { Mirador, miradorImageToolsPlugin } = integration;
  Mirador.viewer(config, [...miradorImageToolsPlugin]);
</script>

まとめ

Miradorのプラグインアーキテクチャは、ビューアの機能を柔軟に拡張するための強力な仕組みです。公式プラグインだけでなく、コミュニティによる多様なプラグインが開発されており、回転操作、アノテーション、テキストオーバーレイ、ウインドウ同期など、さまざまなユースケースに対応できます。

Mirador 4への移行に伴い、React 18やMUI v7への対応が必要となりますが、基本的なプラグインアーキテクチャの考え方は変わっていません。targetmodeによるコンポーネントの配置、mapDispatchToPropsmapStateToPropsによるReduxストアとの連携という構造を理解すれば、カスタムプラグインの開発にも取り組めるでしょう。