ウェブアプリは、Interactive Canvas を使用するアクションの UI です。次を使用:
ウェブ テクノロジー(HTML、CSS、JavaScript)を使用して開発、デプロイ
説明します。ほとんどの場合、Interactive Canvas では次のようなウェブ コンテンツをレンダリングできます。
ただし、ブラウザにはいくつかの制限があります。
ユーザーのプライバシーとセキュリティを確保できます。UI の設計を始める前に、
Design guidelines
で概説されているデザイン原則
。
ウェブアプリの HTML と JavaScript では、次のことを行います。
- Interactive Canvas イベントのコールバックを宣言する。
- Interactive Canvas の JavaScript ライブラリを初期化する。
- 状態に基づいてウェブアプリを更新するカスタム ロジックを提供する。
このページでは、ウェブアプリの作成で推奨される方法、 ウェブアプリとフルフィルメントの間の通信、 あります。
推奨ライブラリ
UI はどの方法でも作成できますが、以下を使用することをおすすめします。 ライブラリ:
- Greensock: 複雑なアニメーションを作成する場合。
- Pixi.js: WebGL で 2D グラフィックを描画する場合。
- Three.js: WebGL で 3D グラフィックを描画する場合。
- HTML5 Canvas の描画: シンプルな描画の場合。
- DOM 要素: 静的コンテンツの場合。
アーキテクチャ
シングルページ アプリケーション アーキテクチャを使用することを強くおすすめします。 このアプローチにより、最適なパフォーマンスを実現し、継続的な 会話形式でのユーザー エクスペリエンス。Interactive Canvas は、 Vue などのフロントエンド フレームワーク、 Angular、React は、 状態管理に役立ちます。
HTML ファイル
HTML ファイルで UI の外観を定義します。このファイルは、インタラクティブ モードの 通信を可能にする Canvas JavaScript ライブラリ ウェブアプリと会話型アクションの間の関係性を定義します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Immersive Canvas Sample</title>
<!-- Disable favicon requests -->
<link rel="shortcut icon" type="image/x-icon" href="data:image/x-icon;,">
<!-- Load Interactive Canvas JavaScript -->
<script src="https://www.gstatic.com/assistant/df-asdk/interactivecanvas/api/interactive_canvas.min.js"></script>
<!-- Load PixiJS for graphics rendering -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.7/pixi.min.js"></script>
<!-- Load Stats.js for fps monitoring -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
<!-- Load custom CSS -->
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div id="view" class="view">
<div class="debug">
<div class="stats"></div>
<div class="logs"></div>
</div>
</div>
<!-- Load custom JavaScript after elements are on page -->
<script src="js/main.js"></script>
<script src="js/log.js"></script>
</body>
</html>
フルフィルメントとウェブアプリ間のやり取り
ウェブアプリとフルフィルメントを作成し、インタラクティブ ワークフロー キャンバス ライブラリを ウェブアプリ ファイルを使用する場合、ウェブアプリとフルフィルメントとのやり取りの方法を定義する必要があります。宛先 ウェブアプリのロジックを含むファイルを修正します。
action.js
このファイルには、
コールバック
メソッドの呼び出し
interactiveCanvas
経由で。コールバックを使用すると、ウェブアプリから
会話アクションに情報やリクエストを送信する方法を提供します。
interactiveCanvas.ready(callbacks);
を HTML ファイルに追加して初期化と
コールバックを登録します。
//action.js
class Action {
constructor(scene) {
this.canvas = window.interactiveCanvas;
this.scene = scene;
const that = this;
this.commands = {
TINT: function(data) {
that.scene.sprite.tint = data.tint;
},
SPIN: function(data) {
that.scene.sprite.spin = data.spin;
},
RESTART_GAME: function(data) {
that.scene.button.texture = that.scene.button.textureButton;
that.scene.sprite.spin = true;
that.scene.sprite.tint = 0x0000FF; // blue
that.scene.sprite.rotation = 0;
},
};
}
/**
* Register all callbacks used by Interactive Canvas
* executed during scene creation time.
*
*/
setCallbacks() {
const that = this;
// declare interactive canvas callbacks
const callbacks = {
onUpdate(data) {
try {
that.commands[data.command.toUpperCase()](data);
} catch (e) {
// do nothing, when no command is sent or found
}
},
};
// called by the Interactive Canvas web app once web app has loaded to
// register callbacks
this.canvas.ready(callbacks);
}
}
main.js
このファイルによりウェブアプリのシーンが作成されます。この例では
sendTextQuery()
で返された Promise の成功と失敗のケース。「
以下は main.js
からの抜粋です。
// main.js
const view = document.getElementById('view');
// initialize rendering and set correct sizing
this.renderer = PIXI.autoDetectRenderer({
transparent: true,
antialias: true,
resolution: this.radio,
width: view.clientWidth,
height: view.clientHeight,
});
view.appendChild(this.element);
// center stage and normalize scaling for all resolutions
this.stage = new PIXI.Container();
this.stage.position.set(view.clientWidth / 2, view.clientHeight / 2);
this.stage.scale.set(Math.max(this.renderer.width,
this.renderer.height) / 1024);
// load a sprite from a svg file
this.sprite = PIXI.Sprite.from('triangle.svg');
this.sprite.anchor.set(0.5);
this.sprite.tint = 0x00FF00; // green
this.sprite.spin = true;
this.stage.addChild(this.sprite);
// toggle spin on touch events of the triangle
this.sprite.interactive = true;
this.sprite.buttonMode = true;
this.sprite.on('pointerdown', () => {
this.sprite.spin = !this.sprite.spin;
});
タッチ操作のサポート
Interactive Canvas アクションは、ユーザーのタップ操作にも応答できます。 生成します。「 Interactive Canvas の設計ガイドライン アクションを「音声第一」に開発する必要があります。とはいえ、 ディスプレイはタップ操作をサポートしています。
サポート タッチは、会話形式の応答のサポートに似ています。ただし、 ユーザーの音声による応答ではなく、クライアント側の JavaScript が ウェブアプリの要素を変更する際に使用します。
こちらの例では、 Pixi.js ライブラリ:
...
this.sprite = PIXI.Sprite.from('triangle.svg');
...
this.sprite.interactive = true; // Enables interaction events
this.sprite.buttonMode = true; // Changes `cursor` property to `pointer` for PointerEvent
this.sprite.on('pointerdown', () => {
this.sprite.spin = !this.sprite.spin;
});
...
この場合、spin
変数の値は
update
コールバックとしての interactiveCanvas
API。フルフィルメントにロジックが含まれている
spin
の値に基づいてインテントをトリガーする。
...
app.intent('pause', (conv) => {
conv.ask(`Ok, I paused spinning. What else?`);
conv.ask(new HtmlResponse({
data: {
spin: false,
},
}));
});
...
その他の機能の追加
基本を学んだので、次はアクションを拡張してカスタマイズします。 Canvas 固有の API を使用しますこのセクションでは、これらの API の実装方法について説明します。 Interactive Canvas アクションで行えます。
sendTextQuery()
sendTextQuery()
メソッドは、会話アクションにテキストクエリを送信します。
プログラムでインテントを呼び出すことができます。このサンプルでは sendTextQuery()
を使用して、
ユーザーがボタンをクリックしたときに、三角形が回転するゲームを再開する。ユーザーが
ユーザーが [ゲームを再開] をクリックするボタンの場合、sendTextQuery()
は Restart game
を呼び出します。
Promise を返します。インテントが次の場合、この Promise は SUCCESS
になります。
トリガーされ、トリガーされていない場合は BLOCKED
。次のスニペットはインテントをトリガーします。
Promise の成功と失敗のケースを処理します。
//main.js
...
that.action.canvas.sendTextQuery('Restart game')
.then((res) => {
if (res.toUpperCase() === 'SUCCESS') {
console.log(`Request in flight: ${res}`);
that.button.texture = that.button.textureButtonDisabled;
that.sprite.spin = false;
} else {
console.log(`Request in flight: ${res}`);
}
});
...
Promise の結果が SUCCESS
の場合、Restart game
インテントは HtmlResponse
を送信します。
ウェブアプリに追加します。
//index.js
...
app.intent('restart game', (conv) => {
conv.ask(new HtmlResponse({
data: {
command: 'RESTART_GAME',
},
...
この HtmlResponse
が onUpdate()
コールバックをトリガーし、これによりコードが実行されます。
次の RESTART_GAME
コード スニペットに置き換えます。
//action.js
...
RESTART_GAME: function(data) {
that.scene.button.texture = that.scene.button.textureButton;
that.scene.sprite.spin = true;
that.scene.sprite.tint = 0x0000FF; // blue
that.scene.sprite.rotation = 0;
},
...
OnTtsMark()
OnTtsMark()
コールバックは、一意の名前を持つ <mark>
タグを
レスポンスを作成します。以下は、スノーマン サンプルからの抜粋です。
OnTtsMark()
は、ウェブアプリのアニメーションを対応する TTS と同期します。
出力です。アクションがユーザーに「申し訳ありませんが、負けました」と言った場合、ウェブアプリは
正しい単語を出力し、文字をユーザーに表示します。
インテント Game Over Reveal Word
のレスポンスにカスタムマークが含まれています。
ユーザーがゲームに負けた場合、次のようになります。
//index.js
...
app.intent('Game Over Reveal Word', (conv, {word}) => {
conv.ask(`<speak>Sorry, you lost.<mark name="REVEAL_WORD"/> The word is ${word}.` +
`${PLAY_AGAIN_INSTRUCTIONS}</speak>`);
conv.ask(new HtmlResponse());
});
...
その後、次のコード スニペットは OnTtsMark()
コールバックを登録し、
revealCorrectWord()
関数を実行してウェブアプリを更新します。
//action.js
...
setCallbacks() {
const that = this;
// declare assistant canvas action callbacks
const callbacks = {
onTtsMark(markName) {
if (markName === 'REVEAL_WORD') {
// display the correct word to the user
that.revealCorrectWord();
}
},
...
制限事項
ウェブアプリを開発するときは、以下の制限事項を考慮してください。
- Cookie は使用不可
- ローカル ストレージは使用不可
- 位置情報は使用不可
- カメラは使用不可
- ポップアップは使用不可
- メモリの上限は 200 MB
- 3P ヘッダーが画面上部を占める
- 動画へのスタイルの適用は不可
- 一度に使用できるメディア要素は 1 つのみ
- HLS 動画は使用不可
- ウェブ SQL データベースは使用不可
SpeechRecognition
インターフェースの Web Speech API。- 録音または録画は不可
- ダークモード設定を適用できません
クロスオリジン リソース シェアリング
Interactive Canvas のウェブアプリは iframe でホストされ、オリジンが設定されているため クロスオリジン リソース シェアリング(CORS)を有効にする必要があります。 ウェブサーバーとストレージ リソースを保護します。これにより、アセットは null の生成元からのリクエストを受け入れることができます。
- メディアと画像が Firebase でホストされている場合は、カスタム ドメインの Dynamic Links CORS を構成します
- メディアと画像が Cloud Storage 上にある場合は、クロスオリジンの設定 リソース シェアリング(CORS) CORS を構成します