こんにちは、ナレコム前川です。
Sumerian のチュートリアルにSumerian Beginner Course というものが新しく追加されていました!
まだ確認していない方は確認してみてください。
今回は、Amazon Sumerian の公式チュートリアルの
Iframe Communication を進めていきたいと思います。
私達は、Iframe を使用することによって Sumerian で作成したシーンを Web ページに簡単に埋め込むことができます。
このときに、Iframe の外部でマウスの動きを把握することができるようになっています。
今回は、このマウスの動きを把握できるようにする方法について説明していきます。
ここで大まかに学ぶことは、
・スクリプトについて
・Iframe について
・postMessage について
・Mesh Color の変更について
の4つです。
それでは、進めていきましょう。
1. シーンの作成
はじめにシーンを作成し、環境を整えていきましょう。
① ダッシュボードからDefault Lighting を選択。
② シーン名を「Iframe Communication」にし、作成。
③ Create Entity から Box を追加。
④ 追加した Box に Script コンポーネントを追加。
⑤ + ボタン -> Custom を選択。
2. マウス動作の把握方法
マウスの動作を把握する方法についていくつか紹介していきます。
① オブジェクト上にマウス動作についてのスクリプトを入れ込む
先程追加した Box を選択し、Script コンポーネントからエディタを開いてください。
開いたら、以下のコードを書き込みます。
1 2 3 4 5 6 7 8 9 10 |
var setup = function(args, ctx) { ctx.listener = function(evt) { console.log(evt.clientX, evt.clientY); }; window.addEventListener('mousemove', ctx.listener); } var cleanup = function(args, ctx) { window.removeEventListener('mousemove', ctx.listener); } |
書き込んだら保存して、エディタを閉じます。
閉じたらシーンを公開してください。
1 |
<iframe id="sumerian-scene" src="https://YOUR_PUBLISH_URL.scen/yoursceneID.scene"></iframe> |
上記のコードをブラウザの Web ページに埋め込みます。
埋め込んだあと、JavaScriptコンソールを開くと、マウスが Iframe 内にある時だけマウスの位置が記録されます。
Google Chrome で確認したい場合は、シーンを埋め込んだ Web ページを開き、
右クリック -> 検証 をクリックしたあと、Console を開くと確認することができます。
② window.parent でマウス位置を把握する
次は、先程のコードを以下のコードと書き換えてください。
1 2 3 4 5 6 7 8 9 10 11 |
// This will throw a cross-origin error! var setup = function(args, ctx) { ctx.listener = function(evt) { console.log(evt.clientX, evt.clientY); }; window.parent.addEventListener('mousemove', ctx.listener); } var cleanup = function(args, ctx) { window.parent.removeEventListener('mousemove', ctx.listener); } |
書き換えたら保存し、公開し直します。
ここで、すぐに確認したいところですが、以下のようなエラーが発生します。
1 |
Uncaught DOMException: Blocked a frame with origin "https://YOUR_PUBLISH_URL.scen" from accessing a cross-origin frame. |
この場合は、シーンを Web ページとしてダウンロードし、
メインの Web ページと同じドメインに置くことで解決できるそうです。
③ postMessageの使用
公開したシーンを独自のサーバーに置くことなく、Iframe 内に含まれるようにしていきましょう。
HTMLの埋め込みコードを次のように変更します。
Web ページに以下のコードを書き込んでください。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<iframe id="sumerian-scene" src="https://YOUR_PUBLISH_URL.scen/yoursceneID.scene"></iframe> <script> var iframe = document.getElementById('sumerian-scene'); iframe.onload = function() { window.addEventListener('mousemove', function(event) { var data = { clientX: event.clientX, clientY: event.clientY }; iframe.contentWindow.postMessage(data, '*'); }); }; </script> |
保存して再度公開します。
次に、Box のスクリプトを開いて以下のコードに置き換えます。
1 2 3 4 5 6 7 8 9 10 |
var setup = function(args, ctx) { ctx.listener = function(evt) { console.log(evt.data.clientX, evt.data.clientY); }; window.addEventListener('message', ctx.listener); } var cleanup = function(args, ctx) { window.removeEventListener('message', ctx.listener); } |
スクリプトを保存して再公開を行います。
この設定によってiframe と iframe の外側の両方からログメッセージが取得できるようになりました。
マウス位置に応じてメッシュの色を変更する
マウスの位置でメッシュの色を変更したい場合には、以下のようなコードに書き換える必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!-- Embed the sumerian scene --> <iframe id="sumerian-scene" src="..."></iframe> <!-- When the iframe loads, send in the mouse position --> <script> var iframe = document.getElementById('sumerian-scene'); iframe.onload = function() { window.addEventListener('mousemove', function(event) { // Send the mouse position (relative to the upper-left iframe corner) to the iframe. var rect = iframe.getBoundingClientRect(); var data = { myEvent: true, x: event.clientX - rect.left, y: event.clientY - rect.top }; iframe.contentWindow.postMessage(data, '*'); }); }; </script> |
以下のスクリプトは、マウスの位置に応じて、キューブの拡散色を設定したい時に使えます。
スクリプト内のコードを書き換えてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
var setup = function(args, ctx) { // Listen for messages from the parent window window.addEventListener('message', ctx.messageListener = function(evt) { if(evt.data.myEvent){ // Set the color of the mesh on the entity var color = [ 0.5 * Math.sin(evt.data.x / ctx.domElement.width) + 0.5, 0.5 * Math.sin(evt.data.y / ctx.domElement.height) + 0.5, 0, 1 ]; ctx.entity.meshRendererComponent.materials[0].uniforms.materialDiffuse = color; } }); // Listen for mouse movement on the iframe window. // This is needed because mouse events on the iframe // can't be caught by the parent window. window.addEventListener('mousemove', ctx.mousemoveListener = function(evt){ ctx.messageListener({ data: { myEvent: true, x: evt.clientX, y: evt.clientY } }); }); } var cleanup = function(args, ctx) { window.removeEventListener('message', ctx.messageListener); window.removeEventListener('mousemove', ctx.mousemoveListener); } |
それでは、最後に公開し直して下さい。
シーンが正常に実行されると以下のようになります。
今回のチュートリアルは以上です。
お疲れ様でした。