JavaScriptで要素にパンやズーム機能を簡単に追加できるライブラリが便利そうだったので試してみました。
バージョンは9.4.3です。
こういうライブラリがあまりない時代に、商業施設サイトの館内マップを7割ぐらいスクラッチで作ったことがあって苦戦したことをよく覚えています。
例えばマップが表示領域からはみださないようにしたり、ズーム時の再計算処理、さらにスマホの処理が必要になるため思っている以上に実装することが多いです。
このライブラリを使えばそんな煩わしい部分が実装されているので、少しゴニョゴニョすればイイ感じで完成させることができます。もちろんjQueryは不要です。
最低限で実装
オプション無しのサンプルはこちらです。
See the Pen anvaka/panzoom minimum option by hakoirioyaji (@hakoirioyaji) on CodePen.
PCであればマウスダウンしたままドラッグで移動、マウスホイール/ダブルクリックでズームが可能です。
スマホならパンやピンチイン/アウトでズームができ、ダブルタップでズームインが可能です。
表示エリアの制限を入れていますが、これぐらいなら以下のようにとても短いソースで実装が可能です。CSSが少し長いのでminifyしています。
<html>
<head>
<style>
*{box-sizing:border-box}
html{font-size:10px}
body{margin:0;background:#fff;color:#333;font-size:1.6rem;letter-spacing:.1em}
.container{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100vh;padding:1em;background-color:#fff}
.outer{position:relative;width:clamp(300px,100%,600px);height:400px;overflow:hidden;border:3px solid #555;border-radius:5px;background-color:#eee}
#panzoom{display:flex;position:relative;align-items:center;justify-content:center;width:100%;height:100%}
#panzoom img{width:auto;height:auto;vertical-align:bottom}
</style>
</head>
<body>
<div class="container">
<div class="outer">
<div id="panzoom">
<img src="https://images.unsplash.com/photo-1551641506-ee5bf4cb45f1?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1000&q=80">
</div>
</div>
</div>
<script src="https://unpkg.com/panzoom@9.4.3/dist/panzoom.min.js"></script>
<script>
const panzoomEl = document.getElementById('panzoom');
const instance = panzoom(panzoomEl);
</script>
</body>
</html>
JSはpanzoom
の引数に要素を指定するだけです。
オプション無しで動作させて気になったところは、移動範囲に制限がないところでしょうか。
行方不明にならないように以下の移動範囲を制限するオプションは必須だと思います。
- bounds
-
移動範囲を制限します。デフォルトは
false
です。 - boundsPadding
-
余白を調整します。デフォルトは
0.05
です。
const panzoomEl = document.getElementById('panzoom');
const instance = panzoom(panzoomEl, {
bounds: true,
boundsPadding: 0.05
});
See the Pen anvaka/panzoom minimum option by hakoirioyaji (@hakoirioyaji) on CodePen.
一通り使ってみた感じでは、実装に必要そうなオプションやイベントは用意されていると思います。
詳しくは公式サイトを参照したほうが早いと思いますが、その中で好みが分かれそうなオプションを以下に挙げています。
- transformOrigin
-
マウスホイールやピンチ操作でズームを行う時の中心点を変更でき、
{x: 0.5, y: 0.5}
で中心になります。
デフォルト(未設定)の場合はマウスカーソルの位置、スマホの場合は2点間の中央を基準にズーム処理されます。
殆どの場合はデフォルトだと思いますが、中心を使うパターンもあるかなというところです。 - smoothScroll
-
移動後に慣性が働き、ゆっくり止まるようになります。デフォルトは
true
です。 - zoomDoubleClickSpeed
-
ダブルクリックのズーム乗数を調整できます。
ダブルクリックのズーム計算は、現在のズーム値 * zoomDoubleClickSpeed
のように乗算されるため、1より大きければ拡大、1より小さければ縮小になります。1を設定すると無効にできます。 - beforeWheel
-
マウスホイールの挙動を変更できます。公式の説明ではALTキーを押すと動作する実装がされています。
使ってみた感想
オプションの調整を少し行うだけで簡単にパンとズームが実装できるのでオススメしたいところですが、少しだけ妥協が必要な部分があります。
それは移動範囲を制限している状態でのズームインです。
私が作成したHTMLやCSSの構造が悪い可能性がありますが、例えば縮小した状態で表示領域の端まで移動してからズームインしようとすると、ズームが途中で止まったり、変な位置に移動することがあります。この他に移動範囲が狭くなったりします。
もしかしたらforkされたソースで修正されているかもしれませんが、この辺が直ると嬉しいところです。
最後にあまり綺麗なコードではありませんが、初期表示で中央寄せ、ボタンによるズーム、Aタグクリック時の誤動作を防ぐ処理などを実装したサンプルを載せておきます。
See the Pen anvaka/panzoom sample1 by hakoirioyaji (@hakoirioyaji) on CodePen.
コメント