Web 应用是使用 Interactive Canvas 的 Action 的界面 (UI)。您可以使用现有 Web 技术(例如 HTML、CSS、JavaScript 和 WebAssembly)设计和开发 Web 应用。在大多数情况下,Interactive Canvas 可以像浏览器一样呈现 Web 内容,但对用户隐私和安全施加了一些限制。在开始设计界面之前,请考虑设计准则中列出的设计原则。我们建议使用 Firebase Hosting 部署您的 Web 应用。
您的 Web 应用的 HTML 和 JavaScript 将执行以下操作:
- 初始化 Interactive Canvas JavaScript 库。
- 注册 Interactive Canvas 事件回调。
- 提供用于根据状态更新 Web 应用的自定义逻辑。
本页将介绍构建 Web 应用的推荐方法、如何在对话型 Action 与 Web 应用之间实现通信,以及一般准则和限制。
推荐的库
虽然您可以使用任何方法构建界面,但 Google 建议您使用以下库:
- Greensock:用于制作复杂的动画。
- Pixi.js:用于在 WebGL 上绘制 2D 图形。
- Three.js:用于在 WebGL 上绘制 3D 图形。
- HTML5 画布绘图:适用于简单的绘图。
架构
Google 强烈建议您使用单页应用架构。这种方法可实现最佳性能,并支持持续对话的用户体验。Interactive Canvas 可与 Vue、Angular 和 React 等前端框架结合使用,这些前端框架可帮助您进行状态管理。
HTML 文件
HTML 文件定义界面的外观。此文件还会加载 Interactive Canvas API,该 API 支持您的 Web 应用与对话型 Action 之间的通信。
HTML
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Interactive 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/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/log.js"></script> <script type="module" src="js/main.js"></script> </body> </html>
在对话型 Action 和 Web 应用之间进行通信
构建 Web 应用和对话型 Action 并在 Web 应用文件的 Interactive Canvas 库中加载完成后,您需要定义 Web 应用和对话型 Action 的互动方式。为此,请修改包含 Web 应用逻辑的文件。
action.js
此文件包含用于定义callbacks并通过 interactiveCanvas
调用方法的代码。借助回调,您的 Web 应用可以响应来自对话型 Action 的信息或请求,而方法可提供向对话型 Action 发送信息或请求的方法。
将 interactiveCanvas.ready(callbacks);
添加到 HTML 文件中,以初始化和注册callbacks:
JavaScript
/** * This class is used as a wrapper for Google Assistant Canvas Action class * along with its callbacks. */ export class Action { /** * @param {Phaser.Scene} scene which serves as a container of all visual * and audio elements. */ constructor(scene) { this.canvas = window.interactiveCanvas; this.gameScene = scene; const that = this; this.intents = { GUESS: function(params) { that.gameScene.guess(params); }, DEFAULT: function() { // do nothing, when no command is found }, }; } /** * Register all callbacks used by the Interactive Canvas Action * executed during game creation time. */ setCallbacks() { const that = this; // Declare the Interactive Canvas action callbacks. const callbacks = { onUpdate(data) { const intent = data[0].google.intent; that.intents[intent ? intent.name.toUpperCase() : 'DEFAULT'](intent.params); }, }; // Called by the Interactive Canvas web app once web app has loaded to // register callbacks. this.canvas.ready(callbacks); } }
main.js
main.js
JavaScript 模块会导入 action.js
和 scene.js
文件,并在 Web 应用加载时分别创建这两个文件的实例。此模块还会为 Interactive Canvas 注册回调。
JavaScript
import {Action} from './action.js'; import {Scene} from './scene.js'; window.addEventListener('load', () => { window.scene = new Scene(); // Set Google Assistant Canvas Action at scene level window.scene.action = new Action(scene); // Call setCallbacks to register Interactive Canvas window.scene.action.setCallbacks(); });
scene.js
scene.js
文件用于为您的 Web 应用构建场景。以下代码摘自 scene.js
:
JavaScript
const view = document.getElementById('view'); // initialize rendering and set correct sizing this.radio = window.devicePixelRatio; this.renderer = PIXI.autoDetectRenderer({ transparent: true, antialias: true, resolution: this.radio, width: view.clientWidth, height: view.clientHeight, }); this.element = this.renderer.view; this.element.style.width = `${this.renderer.width / this.radio}px`; this.element.style.height = `${(this.renderer.height / this.radio)}px`; 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 Action 可以响应用户的触摸及其语音输入。根据 Interactive Canvas 设计指南,您应将 Action 开发为“语音优先”。不过,一些智能显示屏支持触摸交互。
支持触摸类似于支持对话响应;不过,客户端 JavaScript 会查找触摸互动并使用这些互动更改 Web 应用中的元素,而不是用户的语音响应。
您可以在使用 Pixi.js 库的示例中查看以下示例:
JavaScript
… 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; });
问题排查
虽然您可以在开发期间使用 Actions 控制台中的模拟器测试 Interactive Canvas Action,但在正式版中,您还可以查看用户设备上的 Interactive Canvas Web 应用中发生的错误。您可以在 Google Cloud Platform 日志中查看这些错误。
如需在 Google Cloud Platform 日志中查看这些错误消息,请按以下步骤操作:
- 在 Actions 控制台中打开您的 Actions 项目。
- 点击顶部导航栏中的 Test。
- 点击在 Google Cloud Platform 中查看日志链接。
用户设备中的错误在日志查看器中会按时间顺序显示。
错误类型
Google Cloud Platform 日志中会显示三种类型的 Web 应用错误:
- 未在 10 秒内调用
ready
时发生超时 - 当
onUpdate()
返回的 promise 未在 10 秒内实现时发生超时 - Web 应用中未捕获到的 JavaScript 运行时错误
查看 JavaScript 错误详情
默认情况下,您无法查看 Web 应用中的 JavaScript 运行时错误的详细信息。如需查看 JavaScript 运行时错误的详细信息,请按以下步骤操作:
- 确保您已在 Web 应用文件中配置了适当的跨域资源共享 (CORS) HTTP 响应标头。如需了解详情,请参阅跨域资源共享。
- 将
crossorigin="anonymous"
添加到 HTML 文件中导入的<script>
标记中,如以下代码段所示:
<script crossorigin="anonymous" src="<SRC>"></script>
准则和限制
在开发 Web 应用时,请考虑以下准则和限制:
- 没有 cookie
- 无本地存储空间
- 无地理定位
- 不使用摄像头
- 无音频或视频录制
- 无弹出式窗口
- 不要超过 200 MB 的内存限制
- 在呈现内容(占据屏幕的上半部分)时,请考虑操作名称标头
- 无法为视频应用任何样式
- 一次只能使用一个媒体元素
- 没有 Web SQL 数据库
- 不支持 Web Speech API 的
SpeechRecognition
接口。 - 深色模式设置不适用
- 智能显示屏支持视频播放。如需详细了解支持的媒体容器格式和编解码器,请参阅 Google Nest Hub 编解码器。
跨源资源共享
由于 Interactive Canvas Web 应用托管在 iframe 中,并且来源设置为 null,因此您必须为 Web 服务器和存储资源启用跨域资源共享 (CORS)。此过程可让您的资源接受来自 null 源的请求。
- 如果您的媒体和图片由 Firebase 托管,请参阅创建自定义网域动态链接以配置 CORS。
- 如果您的媒体和图片位于 Cloud Storage 上,请参阅配置跨域资源共享 (CORS) 以配置 CORS。
后续步骤
如需向 Web 应用添加更多功能,请参阅使用客户端或服务器端执行方式继续构建。