Ứng dụng web là giao diện người dùng cho một Hành động sử dụng Canvas tương tác. Bạn có thể sử dụng
các công nghệ web hiện có (HTML, CSS và JavaScript) để thiết kế và phát triển
ứng dụng web của bạn. Trong hầu hết trường hợp, Canvas tương tác có thể hiển thị nội dung web như
trình duyệt, nhưng có một vài hạn chế được thực thi đối với
quyền riêng tư và bảo mật của người dùng. Trước khi bắt đầu thiết kế giao diện người dùng, hãy cân nhắc
nguyên tắc thiết kế được nêu trong Design guidelines
.
HTML và JavaScript cho ứng dụng web của bạn sẽ thực hiện những việc sau:
- Đăng ký lệnh gọi lại sự kiện Canvas tương tác.
- Khởi chạy thư viện JavaScript tương tác Canvas.
- Cung cấp logic tuỳ chỉnh để cập nhật ứng dụng web dựa trên trạng thái.
Trang này giới thiệu các cách đề xuất để xây dựng ứng dụng web của bạn, cách bật hoạt động giao tiếp giữa ứng dụng web và phương thức thực hiện, cũng như các nguyên tắc chung và hạn chế.
Thư viện đề xuất
Mặc dù bạn có thể sử dụng bất kỳ phương pháp nào để xây dựng giao diện người dùng, nhưng bạn nên sử dụng các phương pháp sau thư viện:
- Greensock: Để tạo ảnh động phức tạp.
- Pixi.js: Dùng để vẽ đồ hoạ 2D trên WebGL.
- Three.js: Để vẽ đồ hoạ 3D trên WebGL.
- Bản vẽ Canvas HTML5: Dành cho các bản vẽ đơn giản.
- Phần tử DOM: Dành cho nội dung tĩnh.
Kiến trúc
Bạn nên sử dụng cấu trúc ứng dụng trang đơn. Phương pháp này mang lại hiệu suất tối ưu và hỗ trợ trải nghiệm trò chuyện của người dùng. Canvas tương tác có thể được sử dụng cùng với các khung giao diện người dùng như Vue, Góc và Phản ứng, để giúp quản lý trạng thái.
Tệp HTML
Tệp HTML xác định giao diện người dùng của bạn. Tệp này cũng tải trang báo cáo Tương tác Thư viện JavaScript Canvas, hỗ trợ giao tiếp giữa ứng dụng web và Hành động trò chuyện.
<!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>
Giao tiếp giữa phương thức thực hiện và ứng dụng web
Lúc này, bạn đã tạo xong ứng dụng web và phương thức thực hiện, đồng thời đã tải ứng dụng Tương tác Thư viện Canvas trong ứng dụng web, bạn cần xác định cách ứng dụng web và phương thức thực hiện tương tác. Người nhận để thực hiện việc này, hãy sửa đổi các tệp chứa logic ứng dụng web của bạn.
action.js
Tệp này chứa mã để xác định
lệnh gọi lại
và gọi phương thức
thông qua interactiveCanvas
. Lệnh gọi lại cho phép ứng dụng web của bạn phản hồi
thông tin hoặc yêu cầu từ Hành động trò chuyện, trong khi các phương thức
cung cấp phương thức gửi thông tin hoặc yêu cầu đến Hành động trò chuyện.
Thêm interactiveCanvas.ready(callbacks);
vào tệp HTML để khởi chạy và
đăng ký lệnh gọi lại:
//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
Tệp này tạo cảnh cho ứng dụng web của bạn. Trong ví dụ này, thẻ này cũng xử lý
các trường hợp thành công và không thành công của lời hứa được trả về bằng sendTextQuery()
. Chiến lược phát hành đĩa đơn
sau đây là một phần trích dẫn từ 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;
});
Hỗ trợ tương tác chạm
Thao tác trên Canvas tương tác có thể phản hồi lại thao tác chạm của người dùng cũng như âm thanh đầu vào. Theo Nguyên tắc thiết kế Canvas tương tác, bạn nên phát triển Hành động của mình thành "ưu tiên giọng nói". Dù vậy, một số chiến dịch Thông minh Màn hình hỗ trợ tương tác chạm.
Việc hỗ trợ thao tác chạm cũng tương tự như việc hỗ trợ phản hồi khi trò chuyện; tuy nhiên, thay vì phản hồi bằng giọng nói của người dùng, JavaScript phía máy khách sẽ có giao diện cho các tương tác chạm và sử dụng các tương tác đó để thay đổi các thành phần trong ứng dụng web.
Bạn có thể xem ví dụ về điều này trong mẫu, sử dụng phương thức Thư viện 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;
});
...
Trong trường hợp này, giá trị của biến spin
được gửi thông qua
API interactiveCanvas
làm lệnh gọi lại update
. Phương thức thực hiện có logic
kích hoạt một ý định dựa trên giá trị của spin
.
...
app.intent('pause', (conv) => {
conv.ask(`Ok, I paused spinning. What else?`);
conv.ask(new HtmlResponse({
data: {
spin: false,
},
}));
});
...
Thêm tính năng khác
Giờ đây, sau khi đã tìm hiểu kiến thức cơ bản, bạn có thể nâng cao và tuỳ chỉnh Hành động của mình bằng các API dành riêng cho Canvas. Phần này giải thích cách triển khai các API này trong Interactive Canvas Action (Thao tác trên vải canvas tương tác).
sendTextQuery()
Phương thức sendTextQuery()
gửi truy vấn dạng văn bản đến Hành động trò chuyện
để gọi một ý định theo phương thức lập trình. Mẫu này sử dụng sendTextQuery()
để
khởi động lại trò chơi quay hình tam giác khi người dùng nhấp vào một nút. Khi người dùng
hãy nhấp vào nút "Khởi động lại trò chơi" nút, sendTextQuery()
sẽ gọi Restart game
và trả về một lời hứa. Lời hứa này sẽ dẫn đến SUCCESS
nếu ý định là
được kích hoạt và BLOCKED
nếu chưa được kích hoạt. Đoạn mã sau đây kích hoạt ý định
và xử lý các trường hợp thành công và thất bại của cam kết:
//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}`);
}
});
...
Nếu lời hứa dẫn đến SUCCESS
, ý định Restart game
sẽ gửi một HtmlResponse
vào ứng dụng web của bạn:
//index.js
...
app.intent('restart game', (conv) => {
conv.ask(new HtmlResponse({
data: {
command: 'RESTART_GAME',
},
...
HtmlResponse
này kích hoạt lệnh gọi lại onUpdate()
để thực thi mã
trong đoạn mã RESTART_GAME
bên dưới:
//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()
Lệnh gọi lại OnTtsMark()
được gọi khi bạn thêm một thẻ <mark>
với một tên riêng biệt trong
phản hồi SSML của bạn cho người dùng. Trong các phần trích dẫn sau từ Mẫu Người tuyết,
OnTtsMark()
đồng bộ hoá ảnh động của ứng dụng web với TTS tương ứng
đầu ra. Khi Hành động nói với người dùng Rất tiếc, bạn đã thua, ứng dụng web sẽ hiển thị thông báo
từ đúng và hiển thị chữ cái cho người dùng.
Ý định Game Over Reveal Word
bao gồm một dấu tuỳ chỉnh để phản hồi
của người dùng khi họ thua cuộc:
//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());
});
...
Sau đó, đoạn mã sau đây sẽ đăng ký lệnh gọi lại OnTtsMark()
, kiểm tra tên
của dấu đó rồi thực thi hàm revealCorrectWord()
. Hàm này cập nhật ứng dụng 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();
}
},
...
Quy định hạn chế
Hãy cân nhắc các hạn chế sau khi bạn phát triển ứng dụng web của mình:
- Không có cookie
- Không có bộ nhớ cục bộ
- Không có định vị vị trí
- Không sử dụng máy ảnh
- Không có cửa sổ bật lên
- Không vượt quá giới hạn bộ nhớ 200 MB
- Tiêu đề của bên thứ ba chiếm phần trên của màn hình
- Không thể áp dụng kiểu cho video
- Bạn chỉ có thể sử dụng một phần tử nội dung nghe nhìn tại một thời điểm
- Không có video HLS
- Không có cơ sở dữ liệu Web SQL
- Không hỗ trợ giao diện
SpeechRecognition
của Web Speech API. - Không có bản ghi âm hoặc video
- Không áp dụng được chế độ tối
Chia sẻ tài nguyên trên nhiều nguồn gốc
Vì các ứng dụng web Canvas tương tác được lưu trữ trong iframe và nguồn gốc được đặt thành rỗng, bạn phải bật tính năng chia sẻ tài nguyên trên nhiều nguồn gốc (CORS) cho máy chủ web và tài nguyên lưu trữ của bạn. Điều này cho phép thành phần của bạn chấp nhận các yêu cầu từ các nguồn gốc rỗng.
- Nếu nội dung nghe nhìn và hình ảnh của bạn được lưu trữ bằng Firebase, hãy xem bài viết Tạo đường liên kết động của miền để định cấu hình CORS.
- Nếu nội dung nghe nhìn và hình ảnh của bạn có trên Cloud Storage, hãy xem phần Định cấu hình nhiều nguồn gốc chia sẻ tài nguyên (CORS) để định cấu hình CORS.