九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、最近3Dコンテンツの開発をさせていただきました!「Sketchfab」というサービスで実装したのですが、これがスグレモノで、
JavaScriptを使って3Dコンテンツを操作できる😊
ようになっています!
Sketchfabは以下のような3Dコンテンツの巨大サイトです。(2022年時点)
- コミュニティメンバー:1,000万人
- 3Dコンテンツ:500万点
引用:Sketchfab Celebrates 10 Million Members
サンプルを体験してみてください。
↓↓↓
出典:African penguin (Spheniscus demersus) Low poly by Major on Sketchfab
視点をグリグリ360°変更することができます。
すごいですね!
しかも、スマホでも操作できるので、次のような使われ方もしています。
- 賃貸物件:ウェブ上で内覧
- 商品販売:より詳しい質感を確かめられる
- オーダーメイド:好みの色を指定して注文できる
そして、Sketchfabは「JavaScript API」を公開してくれています。
そこで❗
今回は「Sketchfab Viewer API」の基本的な操作をまとめてみました。
私のための備忘録ですが、何かの役に立ちましたら嬉しいです😊
ぜひ最後まで読んでくださいね!
「オクトパストラベラー、
絶対ラスボス倒せないでしょ😱」
目次
【3Dコンテンツ】表示する基本
基本の基本、Sketchfabで3Dコンテンツを表示させる(だけ)の部分です。
先にサンプルコードです。
<html> <head> <title>Sketchfab Viewer API (JavaScript)基本操作サンプル</title> </head> <body> <div class="p-5 mx-auto md:w-1/2"> <h1 class="text-lg mb-1"> <span class="text-sky-700 font-bold">Sketchfab Viewer API (JavaScript)</span>:基本操作サンプル </h1> <iframe id="sketchfab-iframe" class="w-full" style="height:500px;"></iframe> </div> <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script> <script src="https://cdn.tailwindcss.com/3.4.15"></script> <script> const iframe = document.getElementById('sketchfab-iframe'); const version = '1.12.1'; const uid = 'c599b3aa82eb46f7ba3bb2d22bd9dfc6'; // 3DモデルのUID const client = new Sketchfab(version, iframe); window.addEventListener('load', () => { client.init(uid, { success(api) { api.start(); console.log('初期化に成功しました ^o^'); }, error() { console.log('初期化に失敗しました..'); } }); }); </script> </body> </html>
Sketchfab Viewer APIはライブラリを提供してくれているので、scriptタグを設置すれば簡単に3Dコンテンツを表示することができます。
もしnpm
でインストールしたい場合は、
npm i @sketchfab/viewer-api
でパッケージをインストールして、次のように呼び出します(必要ならビルドしてください)
import Sketchfab from '@sketchfab/viewer-api'; window.Sketchfab = Sketchfab;
なお、コード中にある「uid」は3DコンテンツのIDです。
const uid = 'c599b3aa82eb46f7ba3bb2d22bd9dfc6';
別の3Dコンテンツを表示したい場合は、Sketchfabの3Dモデルページの各URLから取得してください。
たとえば、以下の場合、最後の32文字の英数字部分です。(※文字数は変わるかもしれません)
https://sketchfab.com/3d-models/african-penguin-spheniscus-demersus-low-poly-9e59070815fe451d93398e2ebdb9bb92
【3Dコンテンツ】クリックイベントをつくる
3Dコンテンツがクリックされた「構成パーツ」の情報を取得するコードをご紹介します。
<html> <head> <title>Sketchfab Viewer API (JavaScript)基本操作サンプル</title> </head> <body> <div class="p-5 mx-auto md:w-1/2"> <h1 class="text-lg mb-1"> <span class="text-sky-700 font-bold">Sketchfab Viewer API (JavaScript)</span>:基本操作サンプル </h1> <iframe id="sketchfab-iframe" class="w-full" style="height:500px;"></iframe> </div> <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script> <script src="https://cdn.tailwindcss.com/3.4.15"></script> <script> const iframe = document.getElementById('sketchfab-iframe'); const version = '1.12.1'; const uid = 'c599b3aa82eb46f7ba3bb2d22bd9dfc6'; // 3DモデルのUID const client = new Sketchfab(version, iframe); window.addEventListener('load', () => { client.init(uid, { success(api) { api.start(); api.addEventListener('viewerready', () => { // 初期化が完了したとき // クリックイベント api.addEventListener('click', (info) => { console.log(info); // クリックされたノード(構成パーツ)のデータ }); }); }, error() { console.log('初期化に失敗しました..'); } }); }); </script> </body> </html>
Sketchfabが初期化できた時点で、JavaScriptのようにイベントをセットすればOKです。
api.addEventListener('click', (info) => { // クリックしたらここが実行される });
【3Dコンテンツ】色を変える
次にクリックした構成パーツの色を変えてみましょう。
サンプルソースです。
<html> <head> <title>Sketchfab Viewer API (JavaScript)基本操作サンプル</title> </head> <body> <div class="p-5 mx-auto md:w-1/2"> <h1 class="text-lg mb-1"> <span class="text-sky-700 font-bold">Sketchfab Viewer API (JavaScript)</span>:基本操作サンプル </h1> <iframe id="sketchfab-iframe" class="w-full" style="height:500px;"></iframe> </div> <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script> <script src="https://cdn.tailwindcss.com/3.4.15"></script> <script> const iframe = document.getElementById('sketchfab-iframe'); const version = '1.12.1'; const uid = 'c599b3aa82eb46f7ba3bb2d22bd9dfc6'; // 3DモデルのUID const client = new Sketchfab(version, iframe); // データ const colors = [ [0.5, 0.1, 0.1], // 赤 [0.1, 0.5, 0.1], // 緑 [0.1, 0.1, 0.5], // 青 [0.5, 0.5, 0.0], // 黄色 [0.4, 0.1, 0.4], // 紫 [0.0, 0.5, 0.5], // 水色 ]; let colorIndex = 0; window.addEventListener('load', () => { client.init(uid, { success(api) { api.start(); api.addEventListener('viewerready', () => { // 初期化が完了したとき // クリックイベント api.addEventListener('click', (info) => { if(info.material) { const material = info.material; // 新しいデータをセット material.channels.AlbedoPBR.color = colors[colorIndex];; // データを更新 api.setMaterial(material); // 次の色インデックスに更新 colorIndex = (colorIndex + 1) % colors.length; } }); }); }, error() { console.log('初期化に失敗しました..'); } }); }); </script> </body> </html>
やることは、クリックした構成パーツのmaterialデータ(オブジェクト)の中身を変更してsetMaterial()
にセットするだけです。
気をつけないといけないのが、色データは16進数(例:#cccccc
)ではなく、[R, G, B]
の配列で指定しないといけない点です。
なお、3Dデータにより違うようですが、もしこのコードで色が変わらない場合は以下のようなパラメータを変更してみてください。
- AlbedoPBR
- DiffusePBR
- EmitColor
その他のパラメータ一覧は、こちらのページのMaterial channelsを参照してください。
また、パラメータが有効になってるかどうかは、enabled部分がどうなっているか(trueかfalse)で判断してください。
他のパラメータを変更することで、色だけでなく光沢や透過率も変更することができます。
【3Dコンテンツ】表示/非表示にする
次はコンテンツの表示/非表示です。
サンプルソースはこちら。
<html> <head> <title>Sketchfab Viewer API (JavaScript)基本操作サンプル</title> </head> <body> <div class="p-5 mx-auto md:w-1/2"> <h1 class="text-lg mb-1"> <span class="text-sky-700 font-bold">Sketchfab Viewer API (JavaScript)</span>:基本操作サンプル </h1> <iframe id="sketchfab-iframe" class="w-full" style="height:500px;"></iframe> </div> <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script> <script src="https://cdn.tailwindcss.com/3.4.15"></script> <script> const iframe = document.getElementById('sketchfab-iframe'); const version = '1.12.1'; const uid = 'c599b3aa82eb46f7ba3bb2d22bd9dfc6'; // 3DモデルのUID const client = new Sketchfab(version, iframe); window.addEventListener('load', () => { client.init(uid, { success(api) { api.start(); api.addEventListener('viewerready', () => { // 初期化が完了したとき // クリックイベント api.addEventListener('click', (info) => { const instanceId = info.instanceID; if(instanceId) { api.hide(instanceId, (err) => { // パーツを非表示 if (! err) { console.log('非表示にした構成パーツ:', instanceId); } // 3秒後:非表示したパーツを表示 setTimeout(() => { api.show(instanceId, (err) => { // パーツを表示 if (! err) { console.log('表示にした構成パーツ:', instanceId); } }); }, 1000); }); } }); }); }, error() { console.log('初期化に失敗しました..'); } }); }); </script> </body> </html>
【3Dコンテンツ】カメラ視点を変更する
続いては、カメラの視点(ポジション)を変更したり、逆に現在の位置情報を取得する方法です。
ソースコードはこちら。
<html> <head> <title>Sketchfab Viewer API (JavaScript):カメラ視点の変更</title> </head> <body> <div class="p-5 mx-auto md:w-1/2"> <h1 class="text-lg mb-1"> <span class="text-sky-700 font-bold">Sketchfab Viewer API (JavaScript)</span>:カメラ視点の変更 </h1> <iframe id="sketchfab-iframe" class="w-full" style="height:500px;"></iframe> <div class="text-center mt-3"> <button id="camera-button-front" class="bg-sky-600 text-white px-4 py-2 rounded">前から</button> <button id="camera-button-rear" class="bg-sky-600 text-white px-4 py-2 rounded">後ろから</button> <button id="camera-button-top" class="bg-sky-600 text-white px-4 py-2 rounded">上から</button> <button id="camera-button-bottom" class="bg-sky-600 text-white px-4 py-2 rounded">下から</button> </div> <div class="text-center mt-3"> <button id="camera-position" class="bg-sky-600 text-white px-4 py-2 rounded">カメラ位置の取得</button> </div> </div> <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script> <script src="https://cdn.tailwindcss.com/3.4.15"></script> <script> const iframe = document.getElementById('sketchfab-iframe'); const version = '1.12.1'; const uid = 'c599b3aa82eb46f7ba3bb2d22bd9dfc6'; // 3DモデルのUID const client = new Sketchfab(version, iframe); const positionItems = [ { key: 'front', position: [0.00027227842457719196, -0.12323447965269245, 0.006010688798040832], target: [0.0002722784245772618, -1.2963339716016102e-18, 0.006010688798040856], }, { key: 'rear', position: [0.0017653025285150942, 0.12322533725599279, 0.005855406984030233], target: [0.0002722784245772618, -1.2963339716016102e-18, 0.006010688798040856], }, { key: 'top', position: [0.00021956383795308866, -0.0430367330509624, 0.2757288099404258], target: [0.0002722784245772618, -1.2963339716016102e-18, 0.006010688798040856], }, { key: 'bottom', position: [0.0002911564848656767, -0.004290098937768513, -0.26708567283614254], target: [0.0002722784245772618, -1.2963339716016102e-18, 0.006010688798040856], }, ]; window.addEventListener('load', () => { client.init(uid, { success(api) { api.start(); api.addEventListener('viewerready', () => { // 初期化が完了したとき // カメラ位置の変更 for(const key in positionItems) { const positionItem = positionItems[key]; const button = document.getElementById(`camera-button-${positionItem.key}`); button.addEventListener('click', () => { const position = positionItem.position; const target = positionItem.target; const duration = 1; // 移動時間(秒) api.setCameraLookAt(position, target, duration, (err) => { if (! err) { console.log('カメラ視点を変更しました:', positionItem); } }); }); } // カメラ位置の取得 const positionButton = document.getElementById('camera-position'); positionButton.addEventListener('click', () => { api.getCameraLookAt(function(err, camera) { if(! err) { console.log('ポジション:', camera.position); console.log('ターゲット:', camera.target); } }); }); }); }, error() { console.log('初期化に失敗しました..'); } }); }); </script> </body> </html>
カメラ位置の変更は、先にデータを用意しておいて、setCameraLookAt()
を実行するだけでOKです。
逆に今表示している3Dコンテンツの位置情報を取得する場合はgetCameraLookAt()
です。
【3Dコンテンツ】背景色を変更する
今回で言うと車ではなく、その背景の色を変更してみます。
ソースコードはこちら。
<html> <head> <title>Sketchfab Viewer API (JavaScript):背景色の変更</title> </head> <body> <div class="p-5 mx-auto md:w-1/2"> <h1 class="text-lg mb-1"> <span class="text-sky-700 font-bold">Sketchfab Viewer API (JavaScript)</span>:背景色の変更 </h1> <iframe id="sketchfab-iframe" class="w-full" style="height:500px;"></iframe> <div class="text-center mt-3"> <button id="background-button" class="bg-sky-600 text-white px-4 py-2 rounded">背景色を変更する</button> </div> </div> <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script> <script src="https://cdn.tailwindcss.com/3.4.15"></script> <script> const iframe = document.getElementById('sketchfab-iframe'); const version = '1.12.1'; const uid = 'c599b3aa82eb46f7ba3bb2d22bd9dfc6'; // 3DモデルのUID const client = new Sketchfab(version, iframe); // データ const colors = [ [0.5, 0.1, 0.1], // 赤 [0.1, 0.5, 0.1], // 緑 [0.1, 0.1, 0.5], // 青 [0.5, 0.5, 0.0], // 黄色 [0.4, 0.1, 0.4], // 紫 [0.0, 0.5, 0.5], // 水色 ]; let colorIndex = 0; window.addEventListener('load', () => { client.init(uid, { success(api) { api.start(); const button = document.getElementById('background-button'); button.addEventListener('click', () => { const color = colors[colorIndex]; api.setBackground({color: color}, () => { console.log('変更した背景色:', color); }); colorIndex = (colorIndex + 1) % colors.length; }); }, error() { console.log('初期化に失敗しました..'); } }); }); </script> </body> </html>
背景色を変更するにはsetBackground()
を呼ぶだけでOKです。
なお、色ではなく画像をセットすることもできるようですが、以下のようにUIDで指定しないといけません。
api.setBackground({uid: '51af6a870cce449eb75b0345feebaebb'}, () => { // });
つまり、3Dコンテンツの中に同梱している必要がなります。
【3Dコンテンツ】スクリーンショットでダウンロードする
好きな位置で3Dコンテンツを表示し、そのスクリーンショットをとる方法です
ソースコードはこちら。
<html> <head> <title>Sketchfab Viewer API (JavaScript):スクリーンショットの保存</title> </head> <body> <div class="p-5 mx-auto md:w-1/2"> <h1 class="text-lg mb-1"> <span class="text-sky-700 font-bold">Sketchfab Viewer API (JavaScript)</span>:スクリーンショットの保存 </h1> <iframe id="sketchfab-iframe" class="w-full" style="height:500px;"></iframe> <div class="text-center mt-3"> <button id="screenshot-button" class="bg-sky-600 text-white px-4 py-2 rounded">スクリーンショットを保存する</button> </div> </div> <script type="text/javascript" src="https://static.sketchfab.com/api/sketchfab-viewer-1.12.1.js"></script> <script src="https://cdn.tailwindcss.com/3.4.15"></script> <script> const iframe = document.getElementById('sketchfab-iframe'); const version = '1.12.1'; const uid = 'c599b3aa82eb46f7ba3bb2d22bd9dfc6'; // 3DモデルのUID const client = new Sketchfab(version, iframe); window.addEventListener('load', () => { client.init(uid, { success(api) { api.start(); const button = document.getElementById('screenshot-button'); button.addEventListener('click', () => { api.getScreenShot('image/png', (err, base64String) => { if (! err) { const fileName = `screenshot-${Date.now()}.png`; const downloadLink = document.createElement('a'); document.body.appendChild(downloadLink); downloadLink.href = base64String; downloadLink.target = '_self'; downloadLink.download = fileName; downloadLink.click(); } }); }); }, error() { console.log('初期化に失敗しました..'); } }); }); </script> </body> </html>
注意が必要なのが、データはbase64形式(文字列)として取得される点です。
今回のコードのようにリンクの移動先としてセットすれば、データの変換は不要です。
企業様へのご提案
Sketchfabを使うと、ウェブ上で3Dコンテンツを提供できるようになります。
つまり、店舗に行かなくても実物を想像しやすい販売ができるわけです。
繰り返しになりますが、冒頭部分で紹介した以下3つのような活用をすることで、より来店時に近い形でのセールスにつなげてはいかがでしょうか。
- 賃貸物件:ウェブ上で内覧
- 商品販売:より詳しい質感を確かめられる
- オーダーメイド:好みの色を指定して注文できる
もしこういった機能をご希望でしたら、ぜひお問い合わせから無料相談してくだい。
お待ちしております😊
おわりに
ということで、今回は久しぶりにブログ記事を書きました!
以前は「毎週書かなきゃダメ!」という制約があり、細部が荒くなることもありましたが、不定期となるとじっくり記事を書けるので、これもメリットだなと感じています。
それにしても、ブログ記事ってひとつ書くだけでも、なかなか労力がいりますね。自分でもよく毎週投稿なんてやってたなってカンジです(笑)
その分スキルアップを実感できているので、ぜひ皆さんもやってみてくださいね😊
ではでは〜!
「チョコボールの銀エンゼルが連続で出たら、
そんなに欲しくなくても次買っちゃうね(笑)」