אפליקציית אינטרנט היא ממשק המשתמש של פעולה שמשתמשת בלוח הציור האינטראקטיבי. אפשר להשתמש
טכנולוגיות אינטרנט קיימות (HTML, CSS ו-JavaScript) כדי לעצב ולפתח
אפליקציית האינטרנט שלך. בדרך כלל, לוח הציור האינטראקטיבי יכול לעבד תוכן מהאינטרנט,
בדפדפן מסוים, אבל יש כמה הגבלות שנאכפות
פרטיות ואבטחה של המשתמשים. לפני שמתחילים לעצב את ממשק המשתמש, כדאי לחשוב על
עקרונות התכנון המפורטים במאמר Design guidelines
.
קוד ה-HTML וה-JavaScript של אפליקציית האינטרנט מבצעים את הפעולות הבאות:
- רישום callbacks לאירוע Interactive Canvas.
- לאתחל את ספריית ה-JavaScript של לוח הציור האינטראקטיבי.
- צריך לספק לוגיקה מותאמת אישית לעדכון אפליקציית האינטרנט על סמך המדינה (State).
בדף הזה מפורטות הדרכים המומלצות לבניית אפליקציית האינטרנט שלכם, איך להפעיל תקשורת בין אפליקציית האינטרנט שלכם למילוי הזמנות, והנחיות כלליות ההגבלות.
ספריות מומלצות
אפשר להשתמש בכל שיטה כדי לבנות את ממשק המשתמש, אבל Google ממליצה להשתמש בשיטות הבאות ספריות:
- Greensock: ליצירת אנימציות מורכבות.
- Pixi.js: לציור גרפיקה דו-ממדית ב-WebGL.
- Three.js: לשרטוט גרפיקה בתלת-ממד ב-WebGL.
- שרטוט על קנבס ב-HTML5: לשרטוטים פשוטים.
- רכיב DOM: לתוכן סטטי.
ארכיטקטורה
Google ממליצה מאוד להשתמש בארכיטקטורת אפליקציה עם דף יחיד. הגישה הזו מאפשרת ביצועים אופטימליים והיא תומכת ברציפות וחוויית המשתמש בממשק צ'אט עם AI. אפשר להשתמש בלוח הציור האינטראקטיבי בשילוב עם frameworks חזיתיות כמו Vue, Angular ו-React, שעוזרים בניהול מדינות.
קובץ HTML
קובץ ה-HTML מגדיר את המראה של ממשק המשתמש. הקובץ הזה טוען גם את הכרטיסייה 'אינטראקטיבי' ספריית 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
הקובץ הזה מכיל את הקוד להגדרה
קריאות חוזרות (callback)
ולהפעיל methods
עד interactiveCanvas
. קריאות חוזרות (callback) מאפשרות לאפליקציית האינטרנט שלך להגיב
מידע או בקשות מהפעולה בשיחה, אבל שיטות
לספק דרך לשלוח מידע או בקשות אל הפעולה בשיחה.
הוספת interactiveCanvas.ready(callbacks);
לקובץ ה-HTML כדי לאתחל ו
רישום callbacks:
//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()
.
היא קטע מתוך 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;
});
אינטראקציות מגע עם התמיכה
הפעולה האינטראקטיבית של קנבס יכולה להגיב למגע של המשתמש וגם את קלט הקול שלהם. בהתאם הנחיות לעיצוב לוח שיתופי אינטראקטיבי, עליכם לפתח את הפעולה כ-'voice-first'. עם זאת, כמה המסכים תומכים באינטראקציות במגע.
מגע תומך באופן דומה לתשובות בשיחות תמיכה; עם זאת, במקום תגובה קולית מהמשתמש, נראה קוד ה-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
נשלח דרך
API של interactiveCanvas
כקריאה חוזרת (callback) של update
. יש לוגיקה למילוי הזמנות
שמפעילה Intent על סמך הערך של spin
.
...
app.intent('pause', (conv) => {
conv.ask(`Ok, I paused spinning. What else?`);
conv.ask(new HtmlResponse({
data: {
spin: false,
},
}));
});
...
הוספת עוד תכונות
עכשיו, אחרי שלמדת את העקרונות הבסיסיים, אפשר לשפר את הפעולה ולהתאים אותה אישית באמצעות ממשקי API ספציפיים ללוח הציור. בקטע הזה מוסבר איך להטמיע את ממשקי ה-API האלה בפעולה האינטראקטיבית של לוח הציור.
sendTextQuery()
השיטה sendTextQuery()
שולחת שאילתות טקסט לפעולה בשיחה
כדי להפעיל כוונה באופן פרוגרמטי. הדוגמה הזו משתמשת ב-sendTextQuery()
כדי
להפעיל מחדש את המשחק המסתובב במשולש כשמשתמש לוחץ על לחצן. כשהמשתמש
לוחץ על 'הפעלת המשחק מחדש' לחצן, sendTextQuery()
קורא ל-Restart game
בכוונה טובה, ומחזירה הבטחה. ההבטחה הזו תוביל ל-SUCCESS
אם הכוונה היא
מופעלת ו-BLOCKED
אם היא לא מופעלת. קטע הקוד הבא מפעיל את הכוונה
ומטפל במקרים של הצלחה או כישלון של ההבטחה:
//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}`);
}
});
...
אם ההבטחה מובילה לערך SUCCESS
, ה-Intent 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()
הקריאה החוזרת (callback) של OnTtsMark()
מתבצעת כשכוללים תג <mark>
עם שם ייחודי ב-
את תגובת SSML למשתמש. בקטעים הבאים מתוך מדגם איש השלג,
OnTtsMark()
מסנכרן את האנימציה של אפליקציית האינטרנט עם ה-TTS התואם
הפלט. כשהפעולה נאמרת למשתמש מצטערים, אבד, אפליקציית האינטרנט מאייתת
את המילה הנכונה ולהציג למשתמש את האותיות.
ה-Intent 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
- אין אחסון מקומי
- אין מיקום גיאוגרפי
- לא נעשה שימוש במצלמה
- ללא חלונות קופצים
- לא לחרוג ממגבלת הזיכרון של 200MB
- כותרת של צד שלישי תופסת את החלק העליון של המסך
- אי אפשר להחיל סגנונות על סרטונים
- ניתן להשתמש רק ברכיב מדיה אחד בכל פעם
- אין סרטון HLS
- אין מסד נתונים של Web SQL
- אין תמיכה בממשק
SpeechRecognition
של Web Speech API. - ללא הקלטת אודיו או וידאו
- הגדרת מצב כהה לא רלוונטית
שיתוף משאבים בין מקורות
כי אפליקציות אינטרנט אינטראקטיביות של Canvas מתארחות ב-iframe, והמקור מוגדר לערך null, צריך להפעיל שיתוף משאבים בין מקורות (CORS) עבור שרתי האינטרנט ומשאבי האחסון שלך. כך הנכסים יתקבלו בקשות ממקורות null.
- אם המדיה והתמונות מתארחות ב-Firebase, אפשר לעיין במאמר יצירת מדיה בהתאמה אישית קישורים דינמיים של דומיין כדי להגדיר CORS.
- אם המדיה והתמונות שלכם נמצאים ב-Cloud Storage, עיינו במאמר הגדרת הרשאות גישה ממקורות שונים שיתוף משאבים (CORS) כדי להגדיר CORS.