Сразу оговорюсь что, скорее всего, без доработки они будут работать не во всех современных браузерах (тестировал только в Chrome 24 и FF 16 под Linux).
background-image
Как известно у background-image в CSS3 можно указывать несколько файлов фонового изображения, а в background-position их координаты. Следовательно, «смещая» всего две небольших картинки можно сгенерировать случайный лабиринт, например таким кодом:
var images = []; // имена файлов картинок var positions = []; // координаты var l = 26; // размер картинок (для простоты квадратные) var src = ['1.png', '2.png']; var body = document.getElementsByTagName('body')[0]; var w = body.scrollWidth/l; var h = body.scrollHeight/l; for(var i=0;i<h;i++){ for(var j=0;j<w;j++){ images.push('url('+src[Math.round(Math.random())]+')'); // выбираем случайную картинку positions.push(j*l+'px '+i*l+'px'); // и её координаты } } // склеиваем и присваиваем body.style.backgroundImage = images.join(', '); body.style.backgroundPosition = positions.join(', '); body.style.backgroundRepeat = "no-repeat";
Думаю не сложно догадаться, что такой лабиринт довольно просто динамически обновлять, например, как-то вот так:
for(var i=0;i<images.length*0.05;i++){ images[Math.floor(images.length*Math.random())]=('url('+src[Math.round(Math.random())]+')'); } body.style.backgroundImage = images.join(', '); body.style.backgroundPosition = positions.join(', '); body.style.backgroundRepeat = "no-repeat";
Серьёзный минус этого способа в том, что он раздувает элемент до неприличных размеров, кроме того он довольно медленный (похоже по той же причине).
Canvas+Blob
Немного подумав, я решил, что можно сделать реализацию на Canvas+Blob. Суть примерно такая:
- создаём холст и устанавливаем у него размер равный размеру элемента, для которого создаём фон;
- заполняем холст рисунком;
- с помощью JavaScript-Canvas-to-Blob конвертируем содержимое в Blob;
- и с помощью URL.createObjectURL получаем URL блоба.
Полученный URL присваиваем свойству body.style.backgroundImage:
var body = document.getElementsByTagName('body')[0]; canvas.toBlob(function(blob){ var url = URL.createObjectURL(blob); body.style.backgroundImage = "url('" + url + "')"; })
Правда и здесь не обошлось без недостатка. При обновлении значения backgroundImage фон на мгновение исчезает. Хотя это довольно легко устраняется, например наложением картинок на время подгруздки:
var url = URL.createObjectURL(blob); body.style.backgroundImage += ", url('" + url + "')"; body.style.backgroundRepeat = "no-repeat"; setTimeout(function(){ body.style.backgroundImage = "url('" + url + "')"; },200);
Пример 1 (background-image)
Пример 2 (Canvas+Blob)
На этом, пожалуй, всё. Я не ставил цель сделать готовое, стабильное, кроссбраузерное (и т.п.) решение мне хотелось лишь описать более рациональный, на мой взгляд, подход к решению задачи генерации фонового изображения.
p.s. Опыта написания статей почти не имею, так что сильно не ругайтесь, ежели чего не так.
ссылка на оригинал статьи http://habrahabr.ru/post/161755/
Добавить комментарий