Eine Webanwendung ist die Benutzeroberfläche für eine Aktion, die den interaktiven Canvas verwendet. Sie können vorhandene Webtechnologien (HTML, CSS und JavaScript) für den Entwurf und die Entwicklung Ihrer Webanwendung verwenden. In den meisten Fällen können Sie mit Interactive Canvas Webinhalte wie in einem Browser rendern. Allerdings gelten für den Datenschutz und die Sicherheit einige Einschränkungen. Bevor Sie mit dem Entwerfen der UI beginnen, sollten Sie sich die im Abschnitt Design guidelines
beschriebenen Designprinzipien ansehen.
Der HTML- und JavaScript-Code für Ihre Webanwendung führen folgende Schritte aus:
- Registrieren Sie callbacks für das Interactive Canvas-Ereignis.
- Initialisieren Sie die Interactive Canvas JavaScript-Bibliothek.
- Geben Sie eine benutzerdefinierte Logik zum Aktualisieren Ihrer Web-App basierend auf dem Status an.
Auf dieser Seite werden die empfohlenen Methoden zum Erstellen einer Webanwendung, die Kommunikation zwischen der Webanwendung und der Auftragsausführung sowie allgemeine Richtlinien und Einschränkungen erläutert.
Empfohlene Bibliotheken
Sie können jede Methode zum Erstellen Ihrer UI verwenden. Google empfiehlt jedoch die folgenden Bibliotheken:
- Greensock: Zum Erstellen komplizierter Animationen.
- Pixi.js: Zum Zeichnen von 2D-Grafiken mit WebGL.
- Three.js: Zum Zeichnen von 3D-Grafiken in WebGL
- HTML5 Canvas-Zeichnung: Für einfache Zeichnungen.
- DOM-Element: Für statische Inhalte.
Architektur
Google empfiehlt dringend, eine Single-Page-Anwendungsarchitektur zu verwenden. Dieser Ansatz ermöglicht eine optimale Leistung und unterstützt eine kontinuierliche Konversation für Nutzer. Interactive Canvas kann in Verbindung mit Front-End-Frameworks wie Vue, Angular und React verwendet werden, die die Statusverwaltung vereinfachen.
HTML-Datei
Die HTML-Datei definiert, wie Ihre Benutzeroberfläche aussieht. Mit dieser Datei wird auch die Interactive Canvas JavaScript-Bibliothek geladen, die die Kommunikation zwischen Ihrer Webanwendung und der konversationellen Aktion ermöglicht.
<!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>
Kommunikation zwischen Auftragsausführung und Webanwendung
Nachdem Sie Ihre Webanwendung und die Auftragsausführung erstellt und in die Webanwendungsdatei in der interaktiven Canvas-Bibliothek geladen haben, müssen Sie festlegen, wie Ihre Webanwendung und die Auftragsausführung interagieren. Ändern Sie dazu die Dateien, die die Logik Ihrer Webanwendung enthalten.
action.js
Diese Datei enthält den Code zum Definieren von callbacks und zum Aufrufen von Methoden über interactiveCanvas
. Callbacks ermöglichen es der Webanwendung, auf Informationen oder Anfragen von der dialogorientierten Aktion zu antworten. Methoden bieten eine Möglichkeit, Informationen oder Anfragen an die dialogorientierte Aktion zu senden.
Fügen Sie der HTML-Datei interactiveCanvas.ready(callbacks);
hinzu, um callbacks zu initialisieren und zu registrieren:
//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
Diese Datei erstellt die Szene für Ihre Webanwendung. In diesem Beispiel werden auch die Erfolgs- und Fehlerfälle des Promise-Objekts verarbeitet, das mit sendTextQuery()
zurückgegeben wurde. Das ist ein Auszug aus 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;
});
Touch-Interaktionen unterstützen
Die Interactive Canvas Action kann sowohl auf Berührungen als auch auf Gesangseingaben des Nutzers reagieren. Gemäß den Designrichtlinien für Interactive Canvas solltest du deine Aktion so programmieren, dass sie sprachorientiert ist. Einige Smart Displays unterstützen Touch-Interaktionen.
Eine unterstützende Berührung ist mit der Unterstützung von Konversationsantworten vergleichbar. Statt einer gesprochenen Antwort des Nutzers sucht Ihr clientseitiges JavaScript jedoch nach Touch-Interaktionen und verwendet diese, um Elemente in der Webanwendung zu ändern.
Ein Beispiel dafür finden Sie im Beispiel, in dem die Pixi.js verwendet wird:
...
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;
});
...
In diesem Fall wird der Wert der Variable spin
über die interactiveCanvas
API als update
-Callback gesendet. Die Auftragsausführung hat eine Logik, die einen Intent basierend auf dem Wert von spin
auslöst.
...
app.intent('pause', (conv) => {
conv.ask(`Ok, I paused spinning. What else?`);
conv.ask(new HtmlResponse({
data: {
spin: false,
},
}));
});
...
Weitere Funktionen hinzufügen
Nachdem du jetzt mit den Grundlagen vertraut bist, kannst du deine Aktion mit Canvas-spezifischen APIs optimieren und anpassen. In diesem Abschnitt wird erläutert, wie Sie diese APIs in Ihrer Interactive Canvas Action implementieren.
sendTextQuery()
Die Methode sendTextQuery()
sendet Textabfragen an die dialogorientierte Aktion, um einen Intent programmatisch aufzurufen. In diesem Beispiel wird sendTextQuery()
verwendet, um das sich drehende Spiel neu zu starten, wenn der Nutzer auf eine Schaltfläche klickt. Wenn der Nutzer auf die Schaltfläche „Spiel neu starten“ klickt, ruft sendTextQuery()
den Intent Restart game
auf und gibt ein Versprechen zurück. Dieses Versprechen führt zu SUCCESS
, wenn der Intent ausgelöst wird, und zu BLOCKED
, wenn dies nicht der Fall ist. Das folgende Snippet löst den Intent aus und verarbeitet die Erfolgs- und Fehlerfälle des 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}`);
}
});
...
Wenn das Promise SUCCESS
ergibt, sendet der Intent Restart game
ein HtmlResponse
an Ihre Webanwendung:
//index.js
...
app.intent('restart game', (conv) => {
conv.ask(new HtmlResponse({
data: {
command: 'RESTART_GAME',
},
...
Diese HtmlResponse
löst den onUpdate()
-Callback aus, der den Code im folgenden RESTART_GAME
-Code-Snippet ausführt:
//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()
Der OnTtsMark()
-Callback wird aufgerufen, wenn Sie in die SSML-Antwort an den Nutzer ein <mark>
-Tag mit einem eindeutigen Namen einfügen. In den folgenden Auszügen aus dem Snowman-Beispiel synchronisiert OnTtsMark()
die Animation der Webanwendung mit der entsprechenden TTS-Ausgabe. Wenn die Aktion zum Nutzer Du hast leider verloren gesagt hat, buchstabiert die Web-App das richtige Wort und zeigt dem Nutzer die Buchstaben an.
Der Intent Game Over Reveal Word
enthält eine benutzerdefinierte Markierung in der Antwort an den Nutzer, wenn er das Spiel verloren hat:
//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());
});
...
Mit dem folgenden Code-Snippet wird dann der OnTtsMark()
-Callback registriert, der Name der Marke geprüft und die Funktion revealCorrectWord()
ausgeführt, mit der die Webanwendung aktualisiert wird:
//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();
}
},
...
Einschränkungen
Berücksichtigen Sie bei der Entwicklung Ihrer Webanwendung die folgenden Einschränkungen:
- Keine Cookies
- Kein lokaler Speicher
- Keine Standortbestimmung
- Keine Kameranutzung
- Keine Pop-ups
- Unter dem Arbeitsspeicherlimit von 200 MB bleiben
- Drittanbieter-Header nimmt den oberen Teil des Bildschirms ein
- Auf Videos können keine Stile angewendet werden
- Es kann jeweils nur ein Medienelement verwendet werden
- Kein HLS-Video
- Keine Web SQL-Datenbank
- Keine Unterstützung für die
SpeechRecognition
-Schnittstelle der Web Speech API. - Keine Audio- oder Videoaufzeichnung
- Dunkler Modus nicht anwendbar
Cross-Origin Resource Sharing
Da Interactive Canvas-Webanwendungen in einem iFrame gehostet werden und der Ursprung auf null gesetzt ist, müssen Sie das Cross-Origin Resource Sharing (CORS) für Ihre Webserver und Speicherressourcen aktivieren. So können Ihre Assets Anfragen von Null-Ursprüngen akzeptieren.
- Wenn Ihre Medien und Bilder mit Firebase gehostet werden, finden Sie Informationen zum Konfigurieren von CORS unter Benutzerdefinierte dynamische Domainlinks erstellen.
- Wenn sich Ihre Medien und Bilder in Cloud Storage befinden, finden Sie unter Cross-Origin Resource Sharing (CORS) konfigurieren Informationen zum Konfigurieren von CORS.