Создаём сложный лабиринт в фоне веб-страницы (на клиенте)

от автора

Мне показалось немного странным, желание автора этого поста, генерировать изображения на сервере, в то время как современные браузеры позволяют делать это на клиенте. Поэтому хочу предложить другой, а точнее даже два других способа генерации фона.

Сразу оговорюсь что, скорее всего, без доработки они будут работать не во всех современных браузерах (тестировал только в 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *