Các ứng dụng vẽ dựa trên bút cảm ứng được xây dựng cho web từ lâu đã gặp phải các vấn đề về độ trễ vì một trang web phải đồng bộ hoá nội dung cập nhật đồ hoạ với DOM. Trong mọi ứng dụng vẽ, độ trễ dài hơn 50 mili giây có thể ảnh hưởng đến khả năng phối hợp tay và mắt của người dùng, khiến các ứng dụng khó sử dụng.
Gợi ý desynchronized
cho canvas.getContext()
gọi một đường dẫn mã khác bỏ qua cơ chế cập nhật DOM thông thường.
Thay vào đó, gợi ý sẽ yêu cầu hệ thống cơ bản bỏ qua nhiều thành phần kết hợp nhất có thể và trong một số trường hợp, vùng đệm cơ bản của canvas sẽ được gửi trực tiếp đến bộ điều khiển hiển thị của màn hình. Điều này giúp loại bỏ độ trễ do việc sử dụng hàng đợi trình kết xuất trình kết xuất.
Bạn đánh giá như thế nào sản phẩm?
Nếu bạn muốn chuyển đến mã, hãy di chuyển lên phía trước. Để xem ứng dụng này hoạt động, bạn cần có một thiết bị có màn hình cảm ứng và tốt nhất là có bút cảm ứng. (Bạn cũng có thể dùng ngón tay.) Nếu bạn có, hãy thử các mẫu 2d hoặc webgl. Còn những bạn khác, hãy xem bản minh hoạ của Miguel Casas, một trong những kỹ sư đã triển khai tính năng này. Mở bản minh hoạ, nhấn nút phát, sau đó di chuyển thanh trượt qua lại một cách ngẫu nhiên và nhanh chóng.
Ví dụ này sử dụng một đoạn phim dài 1 phút 21 giây trong phim ngắn Sintel của Durian, dự án phim mở của Blender. Trong ví dụ này, phim được phát trong phần tử <video>
có nội dung được kết xuất đồng thời cho phần tử <canvas>
. Nhiều thiết bị có thể làm được điều này mà không bị hiện tượng xé hình, mặc dù các thiết bị có kết xuất vùng đệm trước như ChromeOS có thể bị hiện tượng xé hình. (Phim rất hay nhưng cũng rất đau lòng.
Tôi đã không làm được gì trong một giờ sau khi xem. Hãy coi như bạn đã được cảnh báo.)
Sử dụng gợi ý
Việc sử dụng độ trễ thấp không chỉ đơn thuần là thêm desynchronized
vào canvas.getContext()
. Tôi sẽ lần lượt xem xét các vấn đề.
Tạo canvas
Trên một API khác, tôi sẽ thảo luận về tính năng phát hiện trước. Đối với gợi ý desynchronized
, trước tiên, bạn phải tạo canvas. Gọi canvas.getContext()
và truyền vào đó gợi ý desynchronized
mới có giá trị là true
.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('2d', {
desynchronized: true,
// Other options. See below.
});
Phát hiện tính năng
Tiếp theo, hãy gọi getContextAttributes()
. Nếu đối tượng thuộc tính được trả về có thuộc tính desynchronized
, hãy kiểm thử đối tượng đó.
if (ctx.getContextAttributes().desynchronized) {
console.log('Low latency canvas supported. Yay!');
} else {
console.log('Low latency canvas not supported. Boo!');
}
Tránh hiện tượng nhấp nháy
Có hai trường hợp bạn có thể gây ra hiện tượng nhấp nháy nếu không lập trình đúng cách.
Một số trình duyệt, bao gồm cả Chrome, xoá canvas WebGL giữa các khung. Có thể trình điều khiển màn hình sẽ đọc vùng đệm trong khi vùng đệm trống, khiến hình ảnh đang được vẽ nhấp nháy. Để tránh điều này, hãy đặt preserveDrawingBuffer
thành true
.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('webgl', {
desynchronized: true,
preserveDrawingBuffer: true
});
Hiện tượng nhấp nháy cũng có thể xảy ra khi bạn xoá ngữ cảnh màn hình trong mã vẽ của riêng mình. Nếu bạn phải xoá, hãy vẽ vào vùng đệm khung hình ngoài màn hình rồi sao chép vùng đệm đó vào màn hình.
Kênh alpha
Một phần tử canvas mờ (trong đó alpha được đặt thành true) vẫn có thể bị vô hiệu hoá, nhưng không được có bất kỳ phần tử DOM nào khác phía trên.
Chỉ có thể có một
Bạn không thể thay đổi các thuộc tính ngữ cảnh sau lệnh gọi đầu tiên đến canvas.getContext()
. Điều này luôn đúng, nhưng việc lặp lại có thể giúp bạn tránh được một số phiền toái nếu bạn không biết hoặc đã quên .
Ví dụ: giả sử tôi nhận được một ngữ cảnh và chỉ định alpha là false, sau đó ở một nơi nào đó trong mã, tôi gọi canvas.getContext()
lần thứ hai với alpha được đặt thành true như minh hoạ bên dưới.
const canvas = document.querySelector('myCanvas');
const ctx1 = canvas.getContext('2d', {
alpha: false,
desynchronized: true,
});
//Some time later, in another corner of code.
const ctx2 = canvas.getContext('2d', {
alpha: true,
desynchronized: true,
});
Không rõ ctx1
và ctx2
có phải là cùng một đối tượng hay không. Alpha vẫn là false và ngữ cảnh có alpha bằng true sẽ không bao giờ được tạo.
Các loại canvas được hỗ trợ
Tham số đầu tiên được truyền đến getContext()
là contextType
. Nếu đã quen thuộc với getContext()
, chắc chắn bạn sẽ thắc mắc liệu có loại ngữ cảnh nào khác ngoài "2d" được hỗ trợ hay không. Bảng dưới đây cho thấy các loại ngữ cảnh hỗ trợ desynchronized
.
contextType | Đối tượng loại ngữ cảnh |
---|---|
|
|
|
|
|
|
Kết luận
Nếu bạn muốn xem thêm về vấn đề này, hãy xem các mẫu. Ngoài ví dụ về video đã mô tả, còn có các ví dụ cho thấy cả ngữ cảnh '2d' và 'webgl'.