こんにちは、もしくはこんばんは。シロです!
model-viewerは、Web上で簡単に3Dモデルを表示できるJavaScriptライブラリです。
しかし、残念ながら具体的な使いかたのドキュメントが少なく、調べるのに苦労したので自分でまとめることにしました!
この記事では、3Dデータ読み込みの基本Loadingの項目から検証した結果も含めて解説していきます。
Attributes:属性
src
3DモデルのデータファイルへのURLを指定します。<img>
タグのsrc
属性と一緒です。
<model-viewer src="path/to/model.gltf"></model-viewer>
glTF(.gltf/.glb)というファイル形式のみがサポートされています。
glTFについて詳しくは以下をご覧ください。
alt
3Dモデルの代替テキストを定義します。<img
タグのalt
属性と一緒です。
モデルが正常に読み込まれなかった場合や、3Dビューアーをサポートしていないブラウザーでアクセスされた場合の代替テキストを記述することができます。
デルの読み込みに失敗した場合や、3Dビューアーをサポートしていないブラウザーでアクセスされた場合に、「3D model of a chair」という代替テキストを表示。
<model-viewer src="path/to/model.gltf" alt="3D model of chair"></model-viewer>
poster
3Dモデルをロードして表示するまでの間に、3Dモデルの代わりに表示する画像を指定できます。
poster
属性は、読み込む3Dモデルのファイルの容量が大きく、時間がかかる場合などに、ユーザーに「今ロード中だよ~」を提供するために使用できます。
posterには画像ファイルのパスを指定します。
<model-viewer src="path/to/model.gltf" poster="path/to/poster.png"></model-viewer>
loading
loading
属性は、モデルを表示するロードするタイミングを制御できます。この属性には3つのオプションがあります。
auto(デフォルト) | ブラウザがページを読み込むと同時に、<model-viewer>のモデルも同時に読み込まれます。 これにより、<model-viewer>が表示されるまでの時間が短縮され、ユーザーがより速く3Dモデルを見ることができます。 ただし、モデルが大きい場合、ページの読み込みに時間がかかる可能性があります。 |
lazy | ページが読み込まれた後、ユーザーが<model-viewer>の表示位置までスクロールするまで、モデルの読み込みが遅延されます。 これにより、ページの読み込み時間を短縮することができます。 ただし、ユーザーが3Dモデルを見るまでに時間がかかる可能性があります。 |
eager | ページのロード前に<model-viewer>のモデルが即座に読み込まれます。 これにより、ページの読み込み完了後に<model-viewer>のモデルを再度ロードする必要がなくなり、より速く3Dモデルを見ることができます。 ただし、モデルが大きい場合、ページの読み込みに時間がかかる可能性があります。 |
通常はデフォルトのautoでもOK。SEO対策としてページの表示速度を上げたい場合はlazyを選択。
<model-viewer src="path/to/model.gltf" loading="eager"></model-viewer>
ページの表示速度を優先したいなら lazy > auto > eager、3Dモデルの表示速度を優先したいなら、eager > auto > lazy の順で選択しましょう。
reveal
reveal
属性は、3Dモデルを表示するタイミングを制御できます。この属性には2つのオプションがあります。
auto(デフォルト) | モデルのロードとレンダリングが完了すると、すぐに3Dモデルを表示します。 |
manual | モデルのロードとレンダリングが完了しても、3Dモデルを表示しません。 dismissPoster()メソッドを使うことで、明示的に表示を要求できます。 |
表示ボタンを押すと、非表示状態の3Dモデルを表示します。↓の3Dモデルビューのサンプルコードです。
<model-viewer id="reveal_sample" camera-controls="" touch-action="pan-y" interaction-prompt="none" src="path/to/model.gltf" ar="" alt="A 3D model of a sphere" poster="path/to/model.png" autoplay="" controls="" loading="lazy" reveal="manual">
<button id="reveal_view">表示</button>
</model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer#reveal_sample");
const viewButton = modelViewer.querySelector("#reveal_view");
viewButton.addEventListener('click', function(){
modelViewer.dismissPoster();
});
</script>
with-credentials
公式ドキュメントの内容を自分なりにかみ砕いて書きましたが、クロスオリジンリクエストについていまいち理解してないです。
ちゃんと調べて、おいおい更新できたらと思います。
通常は使わないので、ひとまずスルーして大丈夫です。
model-viewerのwith-credentials
属性は、クロスオリジンリクエストに関する設定です。
この属性を使用することで、model-viewerが別のサーバからリソースを取得する際に、Cookieや認証情報などのクレデンシャル情報を使用できるようになります。
with-credentials属性は、ブール値を取ります。デフォルトではfalseになっており、クレデンシャル情報を使用しない設定になっています。trueに設定することで、クレデンシャル情報を使用する設定になります。
Properties:プロパティ
loaded
loaded
プロパティは、モデルの読み込み状態を表します。
読み込み状態とは、3Dモデルが完全に読み込まれ、表示可能になった状態を指します。
後述のload
イベントが発火した時点でtrueになります。
<model-viewer src="path/to/model.gltf" loading="eager"></model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
if (modelViewer.loaded) {
// 3Dモデルがロード済みの場合に実行するコード
} else {
// 3Dモデルが未ロードの場合に実行するコード
}
</script>
modelIsVisible (model-is-visible)
modelIsVisible
プロパティは、モデルの表示状態を表します。
表示状態とは、ポスターが閉じられ、3Dモデルを表示している状態を指します。
後述のmodel-visibility
イベントが発火した時点でtrueになります。
<model-viewer src="path/to/model.gltf" loading="eager"></model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
if (modelViewer.modelIsVisible) {
// 3Dモデルが表示されている場合に実行するコード
} else {
// 3Dモデルが非表示の場合に実行するコード
}
</script>
Static Properties:静的プロパティ(準備中)
dracoDecoderLocation
ktx2TranscoderLocation
meshoptDecoderLocation
lottieLoaderLocation
minimumRenderScale
modelCacheSize
powerPreference
Methods:メソッド
dismissPoster()
dismissPoster()
メソッドは、poster
属性で指定したポスター画像を非表示にして、3Dモデルを表示します。
reveal="manual"
を指定し、3Dモデルの自動表示を止めていた場合に、手動で表示するために使います。
この例では、ポスターを非表示ボタンを押したときに、dismissPoster()メソッドを呼び出して手動でポスター画像を閉じるようにしています。
<model-viewer src="path/to/model.gltf" poster="path/to/poster.png" reveal="manual">
<button id="dismissPoster">ポスターを非表示</button>
</model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
const dismissPosterButton = modelViewer.querySelector("button#dismissPoster");
dismissPosterButton.addEventListener('click', ()=>{
modelViewer.dismissPoster();
});
</script>
showPoster()
showPoster()
メソッドは、3Dモデルを非表示にして、poster
属性で指定したポスター画像を表示します。
この例では、ポスターを表示ボタンを押したときに、showPoster()メソッドを呼び出して手動でポスター画像を表示するようにしています。
<model-viewer src="path/to/model.gltf" poster="path/to/poster.png" reveal="auto">
<button id="showPoster">ポスターを表示</button>
</model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
const showPosterButton = modelViewer.querySelector("button#showPoster");
showPosterButton.addEventListener('click', ()=>{
modelViewer.showPoster();
});
</script>
ついでのサンプルコード
3Dモデルの表示・非表示状態に応じて、dismissPoster()メソッドとshowPoster()メソッドを使い分ける例です。
<model-viewer src="path/to/model.gltf" poster="path/to/poster.png" autoplay="" reveal="manual">
<button id="posterButton">ポスター表示/非表示</button>
</model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
const posterButton = modelViewer.querySelector("button#posterButton");
posterButton.addEventListener('click', ()=>{
if (modelViewer.modelIsVisible) { // モデルが表示状態
modelViewer.showPoster();
} else { // モデルが非表示状態
modelViewer.dismissPoster();
}
});
</script>
getDimensions()
getDimensions()
メソッドは、3Dモデルの寸法を取得できます。寸法はメートル単位です。
この例では、ボタンを押した時にgetDimensions()
メソッドを呼び出して3Dモデルの寸法をコンソールに出力しています。getDimensions()
が返すオブジェクトに含まれるtoString()
メソッドを使えば、寸法に単位mを付与した文字列を取得できます。
<model-viewer src="path/to/gltf" camera-controls>
<button id="getDimmensionsButton">getDimensions</button>
</model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
const getDimmensionsButton= modelViewer.querySelector("button#getDimmensionsButton");
getDimmensionsButton.addEventListener('click', ()=>{
dimensions = modelViewer.getDimensions();
console.log(dimensions)
console.log(dimensions.toString());
});
</script>
補足
以下の画像は、実際にBlenderで作成したキューブモデルをブラウザに表示して、寸法を取得した例です。
勘のいい方はお気づきかもしれませんが、BlenderとブラウザでYとZの寸法があべこべになっています。
これは、Blenderと<model-viewer>の座標系が異なるためです。
ただ3Dモデルを表示するだけなら特に気にする必要はありませんが、3Dコンテンツ作成にあたって3Dモデルの向きを気にする必要が出てくる可能性もあるので頭の片隅にとどめておきましょう。
getBoundingBoxCenter()
getBoundingBoxCenter()
メソッドは、3Dモデルのバウンディングボックスの中心座標を返すメソッドです。
バウンディングボックスは、3Dモデルを囲む最小の矩形や立方体のことで、モデルの位置や大きさを表す重要な情報を持っています。
基本的な使いかたはgetDimensions()
メソッドと同じなので、サンプルコードはそちらをご覧ください。
座標系についてもgetDimensions()
メソッドと同じです。YとZの座標があべこべになっています。
以下の画像は、実際にBlenderで作成したキューブモデルの位置をずらしてブラウザに表示して、中心座標を取得した例です。
toBlob(options: {mimeType, qualityArgument, idealAspect})
toBlob()
メソッドは、<model-viewer>
要素の現在の表示内容を画像としてBlobオブジェクトに変換するメソッドです。
Blobオブジェクトは、ブラウザのメモリ内に保存されたバイナリデータを表すオブジェクトで、ファイルのアップロードやダウンロードなどに利用できます。
mimeType | 変換する画像のMIMEタイプを指定します。(default : ‘image/png’) |
qualityArgument | 画像の品質を指定します。(default : 0.8) |
idealAspect | trueに設定すると、キャンバスのアスペクト比ではなく、画像に適切なアスペクト比で画像を生成してくれます。(default : false) |
サンプルコード準備中。ごめんね!
toDataURL(type, encoderOptions)
toDataURL()
メソッドは、指定された形式でcanvasの内容を画像データとして取得することができます。
主に、canvasで描画した画像を保存したい場合に使用できます。
type | 変換する画像のMIMEタイプを指定します。(default : ‘image/png’) |
encoderOptions | 画像の品質を指定します。0 から 1 までの浮動小数点数を指定できます。1 に近い値を指定すると高品質で大きなファイルサイズになりますが、0 に近い値を指定すると低品質で小さなファイルサイズになります。 デフォルト値は 0.92 です。 |
サンプルコード準備中。ごめんね!
↓の関連記事に少し載せてます。
補足:toBob()メソッドとtoDataURL()メソッドの違いについて
<model-viewer>
のtoBlob()
メソッドとtoDataURL()
メソッドは、両方とも画像を生成するために使用されますが、それぞれ異なる出力フォーマットを提供します。
toBlob()
メソッドは、PNGまたはJPEG形式のバイナリデータを含むBlobオブジェクトを生成します。Blobオブジェクトを使用すると、画像を直接ダウンロードしたり、他のAPIに送信したりすることができます。
一方、toDataURL()
メソッドは、画像をBase64エンコードされたData URL形式で生成します。Data URLは、画像をインラインで表示したり、HTMLやCSSで使用したりするために使用されます。ただし、Data URLはBlobよりも大きく、パフォーマンスに影響を与える場合があります。
つまり、toBlob()
メソッドはファイルダウンロードやAPI送信などに適しており、toDataURL()
メソッドはインライン表示やHTML/CSSでの使用に適しています。
registerRenderer(externalRenderer)
registerRenderer()
メソッドは、カスタムレンダラーを登録するために使用されます。
Three.jsを使用して、カスタムレンダラーを作成できるらしいのですが、使いかたは検証中です。
unregisterRenderer()
unregisterRenderer()
は、カスタムレンダラーを登録解除するためのメソッドです。
このメソッドを使用することで、登録したカスタムレンダラーを再利用する前に、登録解除することができます。
registerRenderer()
メソッドで登録したカスタムレンダラーを解除するためのメソッドのようですが、まだ検証中です。
Static Methods:静的メソッド(準備中)
mapURLs(callback)
Events:イベント
error
errorイベントは、以下のような状況で発火します。
- モデルファイルの読み込みに失敗した場合
- モデルファイルが壊れていた場合
- モデルファイルが無効な場合(サポートされていないファイル形式、壊れたファイルなど)
- モデルファイルのURLが無効である場合
- 3D描画に必要な機能がユーザーのブラウザーにサポートされていない場合
これらの問題が発生した場合、<model-viewer>はerrorイベントを発火し、コード内でこのイベントを処理することができます。
この例では、エラー発生時に詳細をコンソールに出力しています。
<model-viewer src="path/to/model.gltf"></model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
modelViewer.addEventListener('error', (event) => {
console.error('モデルのロード時にエラーが発生しました', event.detail);
});
</script>
– | 調査中です。 |
load
loadイベントは、3Dモデルが完全に読み込まれた後に発火するイベントです。
このイベントは、モデルが表示される前に完全に読み込まれたことを確認するために使用できます。
この例では、3Dモデルの読み込み完了時にメッセージをコンソールに出力しています。
<model-viewer src="path/to/model.gltf"></model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
modelViewer.addEventListener('load', (event) => {
console.log('モデルが正常にロードされました', event.detail);
});
</script>
url | 読み込んだ3DモデルのURLパスを表します。 |
src
属性を変更して3Dモデルのロードが行われるたびに発火されます。
poster-dismissed
poster-dismissedイベントは、ポスターがユーザーによって閉じられた後に発生するイベントです。
ポスターが閉じられたことを検知することで、開発者は、ポスターが表示された後に何らかのアクションを実行することができます。
たとえば、ユーザーがポスターを閉じると3Dモデルのアニメーション再生する、といった使いかたができます。
この例では、ポスターが閉じられ3Dモデルが表示された時に、コンソールにメッセージを出力しています。
<model-viewer src="path/to/model.gltf"></model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
modelViewer.addEventListener('poster-dismissed', () => {
console.log('ポスターが閉じられました');
});
</script>
model-visibility
model-visibilityイベントは、3Dモデルの表示状態が変更されたときに発生するイベントです。
たとえば、モデルがユーザーに意図的に表示されたり、非表示になったりする場合に発生します。
また、ページをスクロールして、3Dモデルが見える位置に達したとき、もしくは見えなくなったときにも発生します。
この例では、3Dモデルの表示状態が変わった時に、コンソールにメッセージを出力しています。
<model-viewer src="path/to/model.gltf"></model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
modelViewer.addEventListener('model-visibility', (event) => {
console.log('可視性が変更されました', event.detail.visible);
});
</script>
visible | 3Dモデルの表示状態を表します。trueで表示中、falseで非表示です。 |
poster-dismissedイベントは、posterを閉じて3Dモデルをページに表示したときに発火、model-visibilityイベントは、3Dモデルが表示されて、ユーザが見えるようになったときに発火します。
progress
progressイベントは、3Dモデルの読み込み状況に応じて発生します。
このイベントを監視することで、3Dモデルの読み込み進捗状況をリアルタイムで監視することができます。
この例では、3Dモデルの読み込み進捗率が変わった時に、コンソールにメッセージを出力しています。
<model-viewer src="path/to/model.gltf"></model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
modelViewer.addEventListener('progress', (event) => {
console.log('進捗状況', event.detail.totalProgress);
});
</script>
totalProgress | 3Dモデルの読み込み進捗率を0 から 1 までの浮動小数点数の値で表します。 |
render-scale
render-scaleイベントは、3Dモデルのレンダリングスケールが変更されたときに発生します。
たとえば、3Dモデルの初回レンダリング(表示)時や、ブラウザのウィンドウサイズを変更して3Dモデルビューのサイズが変わったときに発生します、
この例では、3Dモデルのレンダリングスケールが変わった時に、コンソールにメッセージを出力しています。
<model-viewer src="path/to/model.gltf"></model-viewer>
<script>
const modelViewer = document.querySelector("model-viewer");
modelViewer.addEventListener('render-scale', (event) => {
console.log('レンダリングスケールが変更されました', event.detail);
});
</script>
minimumDpr | レンダリングスケールの最小値を表します。 この値は model-viewer 要素の min-scale 属性の値に基づいて計算されます。 |
pixelHeight | レンダリングされたキャンバスの高さ(ピクセル単位)を表します。(*1) |
pixelWidth | レンダリングされたキャンバスの幅(ピクセル単位)を表します。(*1) |
reason | レンダリングスケールが変更された原因を表します。(*2) |
renderedDpr | 実際にレンダリングされたレンダリングスケールの値を表します。reportedDpr よりも高い場合があります。 |
reportedDpr | model-viewer 要素に設定されたレンダリングスケールの値を表します。実際にレンダリングされたスケールとは異なる場合があります。 |
*1: ブラウザに表示している<model-viewer>のサイズ(CSSで設定した値) ✖️ renderedDpr の値が入っているようです。
*2: 実際にブラウザのウィンドウサイズを変えて確認しましたが、何も入っていませんでした・・・謎
このイベントを使用すると、3Dモデルのレンダリングスケールが変更されたときに、レンダリング品質やパフォーマンスに適切な調整を行うことができます。
たとえば、ユーザーが3Dモデルを拡大した場合にレンダリングスケールを上げて、より高品質なレンダリングを提供することができます。
Parts:パーツ(準備中)
default-progress-bar
Slots:スロット(準備中)
poster
progress-bar
canvas
まとめ
この記事では、<model-viewer>のLoading APIについて解説しました。
3Dモデルは画像と比べてもサイズが大きくなりやすく、Webページの表示速度にも影響してしまいます。
<model-viewer>はWebページの表示に最適化されており、デフォルトの設定のままでも十分なパフォーマンスを発揮しますが、よりコンテンツのユーザビリティにこだわりたいなら、Loadingプロパティについて理解しておきましょう!
以上、「model-viewer Loading APIの解説」でした。