
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、最近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つのような活用をすることで、より来店時に近い形でのセールスにつなげてはいかがでしょうか。
- 賃貸物件:ウェブ上で内覧
- 商品販売:より詳しい質感を確かめられる
- オーダーメイド:好みの色を指定して注文できる
もしこういった機能をご希望でしたら、ぜひお問い合わせから無料相談してくだい。
お待ちしております
おわりに
ということで、今回は久しぶりにブログ記事を書きました!
以前は「毎週書かなきゃダメ!」という制約があり、細部が荒くなることもありましたが、不定期となるとじっくり記事を書けるので、これもメリットだなと感じています。
それにしても、ブログ記事ってひとつ書くだけでも、なかなか労力がいりますね。自分でもよく毎週投稿なんてやってたなってカンジです(笑)
その分スキルアップを実感できているので、ぜひ皆さんもやってみてくださいね
ではでは〜!
「チョコボールの銀エンゼルが連続で出たら、
そんなに欲しくなくても次買っちゃうね(笑)」