Фоновые изображения на основе холста

Программная анимация фоновых изображений

Существует два основных способа анимации фоновых изображений :

  1. Используйте CSS-спрайты для обновления background-position в JavaScript.
  2. Использование .toDataURL() для обхода ограничений.

The first works great if you have the image ahead of time, but what if your source needs to be programmatically generated, say, by a <canvas> ? The solution to #1 is to use .toDataURL() on the canvas and set the background to the generated URL:

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

Здесь есть две проблемы:

  1. data: URL-адреса увеличивают размер результирующего изображения примерно на 33%.
  2. Множество взаимодействий с DOM ( el.style ).

Оба этих метода неэффективны: неприемлемы для веб-приложения, работающего с плавной частотой 60 кадров в секунду.

Использование двухмерного холста в качестве фона.

Демонстрация использования Canvas в качестве фонового изображения.
ДЕМО

Оказывается, в WebKit уже много лет существует нестандартный API, который может использовать canvas в качестве источника для фона. К сожалению, опубликованной спецификации для этой функции нет .

Во-первых, вместо указания URL-адреса для обратной стороны:

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

Используйте -webkit-canvas() , указав строковый идентификатор контекста холста:

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

Далее нам необходимо создать двумерный контекст с помощью специальной версии метода .getContext() :

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

Дополнительную информацию можно получить у Дэйва Хайатта:

Анимации

As seen in the demo, we can reuse requestAnimationFrame() to drive an animation. This is great, because once things are hooked up, the association between CSS and the canvas element is preserved . There's no need to fiddle with the DOM.

Демонстрация не отображается с анимацией в Chrome?

The current stable channel of Chrome (version 23) has crbug.com/161699 , which prevents a requestAnimationFrame() animation from updating the background properly. This has been fixed in Chrome 25 (currently Canary). The demo also should work well in the current Safari.

Преимущества в производительности

We're talking canvas here. Hardware accelerated animations are now fully in play (at least for the browsers this feature works in). And just to reiterate, there's no need to molest the DOM from JS.

Использование WebGL в качестве фона

Hold on a sec. Does this mean we can power a CSS background using webgl? Of course it does! WebGL is merely a 3d context for canvas. Just swap in "experimental-webgl" instead of "2d", and voila.

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

Вот демонстрационный пример, содержащий div, фон которого отрисовывается с помощью вершинных и фрагментных шейдеров: DEMO

Другие подходы

Стоит отметить, что Mozilla уже довольно давно использует функцию -moz-element() ( MDN ). Она является частью спецификации CSS Image Values ​​and Replaced Content Module Level 4 и позволяет создавать изображения, генерируемые из произвольного HTML-кода: видео, canvas, DOM-контента и т.д. Однако полный доступ к снимкам DOM-элементов сопряжен с проблемами безопасности. Именно поэтому другие браузеры не внедрили эту функцию.