Параллакс-скроллинг изображений при помощи CSS 3D и JavaScript

Параллакс-скроллинг изображений при помощи CSS 3D и JavaScript

От автора: эффекта параллакс-скроллинга можно добиться множеством способов, однако я считаю, что большая их часть лишь имитирует глубину изображения. Взглянув на скринсейвер с OS X, я понял, что CSS 3D позволяет по-настоящему сместить изображения на задний план по оси Z, создавая настоящую перспективу и параллакс-эффект во время прокрутки изображений вверх и вниз.

Код нашего урока всего лишь прототип, но я считаю, что он достаточно интересен, чтобы рассказать вам про него. Заодно взгляните на демо на CodePen.

Основы

Код начинается с одного элемента разметки, тега div:

<div id="parallax-container">
</div>

Этот блок будет наполняться изображениями, которые загружаются через JavaScript. Первым делом необходимо прописать стили для блока DIV и изображений внутри него:

#parallax-container {
    background: #16161d;
    margin: 0;
    overflow: hidden;
    perspective: 1200px;
    height: 100vh;
    width: 100vw;
    transform-style: preserve-3d;
}
#parallax-container img {
    transform-origin: center;
    box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.4);
    position: relative;
}

Прокрутка изображений

По методу прогрессивного улучшения необходимо вставить изображения в разметку, написать CSS код к ним и только потом с помощью JS прятать и управлять ими. Так как это всего лишь демо, я выбрал самый прямой маршрут. Имена наших изображений созданы по одному шаблону (wave1.jpg, wave2.jpg… и т.д.), т.е. я могу при помощи JS генерировать имена изображений. Я буду использовать скрипт ниже наряду с другими глобальными переменными:

var container = document.getElementById("parallax-container"),
waveSrc = [],
waves = [],
imgLoc = "",
j = 0;

for (var i = 0; i < 10; i++) {
    waveSrc = imgLoc+"wave"+(i+1)+".jpg";
}

Мне понадобятся несколько случайных чисел, которые я буду генерировать в функции:

function getRandomInRange(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

Также мне нужны ссылки загружаемых изображений и текущая ширина и высота экрана (с условием, что браузер открыт на весь экран).

var screenWidth = window.screen.width,
screenHeight = window.screen.height;

После загрузки изображений и последовательной вставки в контейнер им задаются свойства .xPlane, .yPlane и zPlane с произвольными значениями. Данные свойства отвечают за позиционирование элементов в 3D пространстве. Мы оставили пустыми атрибуты alt в демо.

function preloadImage(filename){
    var img=new Image();
    img.onload = function(){ 
        img.xPlane = getRandomInRange(-500, screenWidth - 500);
        img.yPlane = getRandomInRange(500, 1000);
        img.zPlane = getRandomInRange(300,2000);
        img.style = "transform: translate3d(" + img.xPlane +"px, " + 
            img.yPlane + "px, -" + img.zPlane +"px)";
       container.appendChild(img);
    };
    imgLoc = "";
    img.src= imgLoc + filename;
    img.alt = "";
    waves[j] = img;
    j++;
}

function loadImages(){
    for (var i = 0; i < waveSrc.length; ++i) {
        var filename = waveSrc;
        preloadImage(filename);
    }
}

И наконец, мы двигаем изображения при помощи функции:

function moveImages(){
    waves.forEach(function(image) {
            image.yPlane = image.yPlane - 2;
            image.style.cssText = "transform: translate3d(" + image.xPlane+"px, 
" + image.yPlane+"px,  -" + image.zPlane + "px); z-index: " + image.zIndex;
        });
    window.requestAnimationFrame(moveImages);
}

Чтобы все заработало, в конце скрипта необходимо вызвать подходящие функции:

loadImages();
window.addEventListener("load", 
	function() { 
		window.requestAnimationFrame(moveImages);
	});

Улучшения

Наш код – это прототип, и он немного грубоват. В него можно внести очевидные улучшения:

Сейчас наш скрипт продолжает работать, когда все изображения исчезают в верхней части контейнера, т.е. он работает бесконечно. В идеале, скрипт должен вырезать изображения из начала массива после их исчезновения и вставлять их в самый низ экрана.

Как ни парадоксально, лучше сделать расположение изображений более предсказуемым. Прямо сейчас в нашем демо изображение может появиться точно за другим изображением или почти на одном уровне с ним (т.е. оба изображения будут двигаться с одной скоростью). Чтобы избежать подобных ситуаций, мне понадобилось бы сравнивать значения расположения новых изображений с теми, что уже прописаны в массиве. Если значения очень близки, мне пришлось бы генерировать новое случайное значение.

Мы создали технику с автоматической прокруткой. Если вы хотите привязать движение изображений к позиции скроллбара на странице, вы можете изменять расположение изображений по window.scrollY.

Источник: http://thenewcode.com/

Редакция: Команда webformyself.

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree