Una app web es la IU de una acción que usa Interactive Canvas. Puedes usar
tecnologías web existentes (HTML, CSS y JavaScript) para diseñar y desarrollar
tu aplicación web. En su mayoría, Interactive Canvas puede renderizar contenido web como el siguiente:
un navegador, pero se aplican algunas restricciones
la privacidad y seguridad del usuario. Antes de comenzar a diseñar tu IU, ten en cuenta el
principios de diseño descritos en el Design guidelines
sección.
El código HTML y JavaScript de tu aplicación web permiten hacer lo siguiente:
- Registra las devoluciones de llamada de eventos de Interactive Canvas.
- Inicializa la biblioteca de JavaScript de Interactive Canvas.
- Proporciona una lógica personalizada para actualizar tu app web según el estado.
En esta página, se explican las formas recomendadas de compilar tu app web, cómo habilitarla la comunicación entre tu aplicación web y su entrega, y los lineamientos generales y de manera predeterminada.
Bibliotecas recomendadas
Si bien puedes usar cualquier método para compilar tu IU, Google recomienda usar los siguientes métodos bibliotecas:
- Greensock: Se usa para crear animaciones complicadas.
- Pixi.js: Para dibujar gráficos en 2D con WebGL.
- Three.js: Para dibujar gráficos en 3D con WebGL.
- Dibujo HTML5 en lienzo: Para dibujos simples.
- Elemento DOM: Para contenido estático.
Arquitectura
Google recomienda encarecidamente usar una arquitectura de aplicación de una sola página. Este enfoque permite obtener un rendimiento óptimo y admite y una experiencia conversacional del usuario. El lienzo interactivo puede usarse junto con frameworks de frontend, como Vue, Angular y React. que ayudan con la administración del estado.
Archivo HTML
El archivo HTML define el aspecto de tu IU. Este archivo también carga el Biblioteca JavaScript de Canvas, que permite la comunicación entre tu aplicación web y tu Action conversacional.
<!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>
Comunicación entre la entrega y la aplicación web
Ahora que ya compilaste tu app web y entregas, y cargaste la sección biblioteca de Canvas en tu de la app web, debes definir cómo interactúan tu app web y la entrega. Para Para ello, modifica los archivos que contienen la lógica de tu app web.
action.js
Este archivo contiene el código para definir
devoluciones de llamada
e invocar métodos
hasta el interactiveCanvas
. Las devoluciones de llamada permiten que tu app web responda
información o solicitudes de la acción conversacional, mientras que los métodos
Proporcionar una manera de enviar información o solicitudes a la Acción conversacional
Agrega interactiveCanvas.ready(callbacks);
a tu archivo HTML para inicializar y
registrar devoluciones de llamada:
//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
Este archivo construye la escena para tu app web. En este ejemplo, también controla
los casos de éxito y fracaso de la promesa que se muestra con sendTextQuery()
El
el siguiente es un extracto de 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;
});
Compatibilidad con interacciones táctiles
Tu acción de Interactive Canvas puede responder tanto al tacto del usuario como al sus entradas vocales. Según las Lineamientos de diseño para el lienzo interactivo debes desarrollar tu acción para que "priorice la voz". Dicho esto, algunas implementaciones Las pantallas admiten interacciones táctiles.
La compatibilidad con el tacto es similar a la asistencia para respuestas conversacionales. Sin embargo, en lugar de una respuesta vocal del usuario, el JavaScript del cliente para las interacciones táctiles y las usa para cambiar elementos en la aplicación web.
Puedes ver un ejemplo de esto en la muestra, en el que se usa Biblioteca 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;
});
...
En este caso, el valor de la variable spin
se envía a través del
API de interactiveCanvas
como una devolución de llamada update
La entrega tiene lógica
que activa un intent basado en el valor de spin
.
...
app.intent('pause', (conv) => {
conv.ask(`Ok, I paused spinning. What else?`);
conv.ask(new HtmlResponse({
data: {
spin: false,
},
}));
});
...
Cómo agregar más funciones
Ahora que aprendiste los conceptos básicos, puedes mejorar y personalizar tu Action con las APIs específicas de Canvas. En esta sección, se explica cómo implementar estas APIs en la acción de Interactive Canvas.
sendTextQuery()
El método sendTextQuery()
envía consultas de texto a la acción conversacional.
para invocar un intent de manera programática. En esta muestra, se usa sendTextQuery()
para
reiniciar el juego de triángulos cuando el usuario hace clic en un botón Cuando el usuario
hace clic en "Reiniciar el juego" botón, sendTextQuery()
llama a Restart game
intent y muestra una promesa. Esta promesa da como resultado SUCCESS
si el intent se
y BLOCKED
si no lo está. El siguiente fragmento activa el intent
y maneja los casos de éxito y fracaso de la promesa:
//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}`);
}
});
...
Si la promesa da como resultado SUCCESS
, el intent Restart game
envía un HtmlResponse
.
a tu app web:
//index.js
...
app.intent('restart game', (conv) => {
conv.ask(new HtmlResponse({
data: {
command: 'RESTART_GAME',
},
...
Este HtmlResponse
activa la devolución de llamada onUpdate()
, que ejecuta el código.
En el siguiente fragmento de código 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()
Se llama a la devolución de llamada OnTtsMark()
cuando incluyes una etiqueta <mark>
con un nombre único en
la respuesta de SSML al usuario. En los siguientes extractos de la muestra de Snowman,
OnTtsMark()
sincroniza la animación de la app web con el TTS correspondiente
salida. Cuando la acción le indica al usuario Perdón, te perdiste, la aplicación web escribe
la palabra correcta y muestra las letras al usuario.
El intent Game Over Reveal Word
incluye una marca personalizada en la respuesta al
usuario cuando perdió el juego:
//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());
});
...
Luego, en el siguiente fragmento de código, se registra la devolución de llamada OnTtsMark()
y se verifica el nombre.
de la marca y ejecuta la función revealCorrectWord()
, que actualiza la aplicación web:
//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();
}
},
...
Restricciones
Ten en cuenta las siguientes restricciones cuando desarrolles tu app web:
- No hay cookies
- Sin almacenamiento local
- Sin ubicación geográfica
- No se está usando la cámara
- No hay ventanas emergentes.
- No superes el límite de memoria de 200 MB
- El encabezado de terceros ocupa la parte superior de la pantalla
- No se pueden aplicar estilos a los videos.
- Solo se puede usar un elemento multimedia a la vez
- Sin video de HLS
- Sin base de datos de Web SQL
- No hay compatibilidad con la interfaz
SpeechRecognition
de la API de Web Speech. - Sin grabación de audio o video
- La configuración del modo oscuro no es aplicable
Uso compartido de recursos multiorigen
Porque las apps web de Interactive Canvas se alojan en un iframe y el origen está establecido. como nulo, debes habilitar el uso compartido de recursos entre dominios (CORS) para tus servidores web y recursos de almacenamiento. Esto permite que tus recursos acepten de origen nulo.
- Si tu contenido multimedia y tus imágenes están alojados en Firebase, consulta Crea una canalización vínculos dinámicos de dominio para configurar CORS.
- Si tus imágenes y contenido multimedia están en Cloud Storage, consulta Configura los orígenes cruzados uso compartido de recursos (CORS) para configurar CORS.