Hình nền dựa trên canvas

Eric Bidelman

Tạo ảnh động cho hình nền theo phương thức lập trình

Có hai cách chính để người dùng tạo ảnh động cho hình nền:

  1. Sử dụng các CSS sprite để cập nhật background-position trong JS .
  2. Video dạng mẹo vặt bằng .toDataURL() .

Cách đầu tiên hoạt động tốt nếu bạn có hình ảnh trước, nhưng nếu nguồn của bạn cần được tạo bằng cách lập trình, chẳng hạn như bằng <canvas> thì sao? Giải pháp cho vấn đề số 1 là sử dụng .toDataURL() trên canvas và đặt nền thành URL được tạo:

while(1) {
    var url = canvas.toDataURL('image/jpeg');
    el.style.background = 'url(' + url + ')';
}

Có hai vấn đề với quá trình này:

  1. URL data: làm tăng mức hao tổn kích thước khoảng 33% cho hình ảnh thu được.
  2. Rất nhiều DOM chạm (el.style).

Cả hai phương pháp này đều không hiệu quả: không chấp nhận được đối với một ứng dụng web luôn mượt mà với tốc độ 60 khung hình/giây.

Sử dụng canvas 2D làm nền

Canvas làm bản minh hoạ nền
BẢN THẢO

Hoá ra, có một API không chuẩn mà WebKit đã có trong nhiều năm có thể lấy canvas làm nguồn làm nền. Tuy nhiên, hiện chưa có quy cách nào được phát hành cho tính năng này.

Đầu tiên, thay vì chỉ định một URL cho mặt sau:

.bg {
    background: url(bg.png) no-repeat 50% 50%;
}

sử dụng -webkit-canvas(), tham chiếu giá trị nhận dạng chuỗi đến ngữ cảnh canvas:

.canvas-bg {
    background: -webkit-canvas(animation) no-repeat 50% 50%;
}

Tiếp theo, chúng ta cần tạo ngữ cảnh 2d bằng phiên bản đặc biệt của .getContext():

var ctx = document.getCSSCanvasContext('2d', 'animation', 300, 300);

Thông tin khác từ Dave Hyatt:

Ảnh động

Như đã thấy trong bản minh hoạ, chúng ta có thể sử dụng lại requestAnimationFrame() để điều khiển ảnh động. Điều này rất tuyệt, vì sau khi mọi thứ được kết nối, mối liên kết giữa CSS và phần tử canvas được giữ nguyên. Bạn không cần phải sử dụng DOM.

Bản minh hoạ không phải là ảnh động trong Chrome?

Kênh ổn định hiện tại của Chrome (phiên bản 23) có crbug.com/161699. Điều này ngăn ảnh động requestAnimationFrame() cập nhật nền đúng cách. Sự cố này đã được khắc phục trong Chrome 25 (hiện là Canary). Bản minh hoạ cũng sẽ hoạt động tốt trong Safari hiện tại.

Lợi ích về hiệu suất

Chúng ta sẽ nói về canvas ở đây. Ảnh động được tăng tốc phần cứng hiện đã hoạt động hoàn toàn (ít nhất là đối với các trình duyệt mà tính năng này hoạt động). Xin nhắc lại là không cần phân phối DOM từ JS.

Sử dụng webgl làm nền

Vui lòng chờ trong giây lát. Điều này có nghĩa là chúng tôi có thể hỗ trợ nền CSS bằng webgl phải không? Tất nhiên là có! WebGL chỉ là một ngữ cảnh 3d cho canvas. Chỉ cần đổi trong "experimental-webgl" thay vì "2d" và voila.

var gl = document.getCSSCanvasContext('experimental-webgl', 'animation', 300, 150);

Sau đây là bằng chứng về khái niệm chứa một div với nền được vẽ bằng trình đổ bóng đỉnh (vertex) và mảnh: demo

Phương pháp khác

Điều đáng chú ý là Mozilla đã sử dụng -moz-element() (MDN) từ khá lâu. Đây là một phần trong quy cách Giá trị hình ảnh CSS và Mô-đun nội dung được thay thế cấp 4 và cho phép bạn tạo hình ảnh được tạo từ HTML tuỳ ý: video, canvas, nội dung DOM, v.v. Tuy nhiên, có một số vấn đề về bảo mật đối với việc có toàn quyền truy cập vào ảnh chụp nhanh của DOM. Đây chủ yếu là lý do các trình duyệt khác không sử dụng tính năng nêu trên.