Как сделать параллакс-эффект с помощью JavaScript

JavaScript добавляет на страницы сайта очень интересные эффекты. Один из них — параллакс. Разбираемся, что это и как его создать самостоятельно.

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

В этой статье мы рассмотрим, как создать движущиеся фон и другие элементы для сайта на JavaScript.

Исходный код вы найдёте на GitHub.

Евгений Кучерявый

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


Параллакс-эффект фона

Для начала подготовим два изображения, которые нам нужны, — передний и задний планы. Для заднего плана я взял фотографию космоса:

Для переднего плана вырезал простой пейзаж с другой фотографии:

Теперь нужно сверстать элементы, в которых выводятся изображения:

<div class="parallax background-space" id="background-space"></div>
<div class="parallax background-tree" id="background-tree"></div>

Альтернативный вариант: установить один из фонов для body, а второй для wrapper — адаптируйте код под свой проект. Далее добавляем стили:

.parallax
{
   position: fixed;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
}
 
.background-space
{
   background: url(../images/space.png);
   background-size: 100% 100%;
   z-index: 1;
}
 
.background-tree
{
   background: url(../images/tree.png);
   background-size: 105% 105%;
   z-index: 2;
   filter: blur(1px);
}

У элементов фиксированная позиция на странице — один элемент (дерево) расположен поверх другого (космос). Также мы добавили фильтр размытости для дерева, чтобы скрыть неровности и создать ощущение расфокуса.

Остаётся написать скрипт:

//Получаем элемент фона с деревом
const bgTree = document.getElementById("background-tree");
 
//При движении мышью вызываем функцию, которая меняет положение фона
document.addEventListener("mousemove", function (e) { MoveBackground(e); });
 
function MoveBackground(e)
{
   //Рассчитываем, насколько далеко от начала оси находится курсор: 0 - 0, 0.5 - середина экрана, 1 - ширина экрана (например, 1920)
   //Затем умножаем получившееся число на 30 - настолько будет сдвигаться фон
   //Например, если курсор находится посередине страницы (0.5), то при умножении получится 15
   //Далее отнимаем половину от 30, чтобы фон мог двигаться как влево, так и вправо
   let offsetX = (e.clientX / window.innerWidth * 30) - 15;
   let offsetY = (e.clientY / window.innerHeight * 10) - 5;
 
   //Меняем положение фона
   bgTree.setAttribute("style", "background-position: " + offsetX + "px " + offsetY + "px;");
}

Теперь посмотрим на результат:

Вы можете использовать столько слоёв, сколько вам необходимо. При этом более дальние слои должны двигаться медленнее, как в нашем случае: если зритель пройдёт несколько шагов, то на положение звёзд это никак не повлияет. А вот дерево находится близко к смотрящему, поэтому оно двигается быстрее.

Параллакс-эффект для частиц

Параллакс работает не только для фона, но и для передних планов.
Что-то подобное любят использовать в Apple на своих лендингах.

Мы добавим на страницу частицы, которые окажутся над основным контентом и будут двигаться вместе с прокруткой страницы.

Для начала нужен блок, куда мы поместим частицы:

<div class="particles" id="particles"></div>

Сам блок не виден пользователю — он нужен нам как контейнер. Теперь подготовим стили:

.particles
{
   position: absolute;
   left: -9999999px;
}
 
.particle
{
   position: fixed;
   top: 0;
   left: 0;
   border-radius: 50%;
   display: block;
   width: 100px;
   height: 100px;
   filter: blur(0px);
   z-index: 1;
   box-shadow: 0 0 10px rgba(0,0,0,0.5);
}

Основные свойства частицам задаём с помощью скрипта.

//Создаём класс для частиц
class Particle
{
   //Конструктор принимает положение частицы по трём осям и цвет
   constructor(x, y, z, color)
   {
       this.x = x;
       this.y = y;
       this.z = z;
 
       //Размытие и скорость зависят от положения частицы по оси Z
       //Чем выше частица, тем более размытой она будет и тем быстрее она будет двигаться
       let blurs = [ 0, 2, 1, 0 ];
 
       this.blur = blurs[z];
       this.speed = z;
       this.color = color;
   }
 
   //Метод движения частицы
   Move(d)
   {
       this.y += this.speed * d;
   }
}
 
//Позиция полосы прокрутки
let scrollPosition = 0;
 
//Получаем контейнер для частиц
const particlesContainer = document.getElementById("particles");
 
//Создаём массив с частицами
const particles =
[
   new Particle(1650, 450, 3, "#FF7019"),
   new Particle(1700, 450, 1, "#FF7019"),
   new Particle(220, 500, 3, "#FF7019"),
   new Particle(600, 700, 1, "#FF7019"),
   new Particle(900, 600, 4, "#FF7019"),
   new Particle(1200, 900, 2, "#FF7019"),
];
 
//Это функция вывода частицы на страницу
Fill();
 
//При каждой прокрутке вызываем функцию Scroll(), которая двигает частицы
window.addEventListener("scroll", function (e) { Scroll(e); });
 
function Scroll(e)
{
   //Определяем, в каком направлении была прокрутка
   let d = 0;
 
   if(window.pageYOffset > scrollPosition)
   {
       d = 1;
   }
   else
   {
       d = -1;
   }
  
   scrollPosition = window.pageYOffset;
 
   //Двигаем все частицы в заданном направлении
   for(let i = 0; i < particles.length; i++)
   {
       particles[i].Move(d);
   }
 
   //Выводим всё на страницу
   Fill();
}
 
function Fill()
{
   //Очищаем контейнер
   particlesContainer.innerHTML = "";
 
   //Создаём новые элементы с обновлёнными свойствами и помещаем их в контейнер
   for(let i = 0; i < particles.length; i++)
   {
       let div = document.createElement("div");
       div.className = "particle";
 
       div.setAttribute("style", "top: " + particles[i].y + "px; left: " + particles[i].x + "px; z-index: " + particles[i].z + "px; filter: blur(" + particles[i].blur + "px); background: " + particles[i].color + "; ");
       particlesContainer.appendChild(div);
   }
}

Теперь можно посмотреть, как это работает:

Конечно, тут ещё многое можно улучшить: изменить размер и форму частиц на разных слоях, поработать с перспективой и размытием. Найти подходящие значения можно только перебором.

Заключение

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

Конечно, для этого нужно хорошо разбираться в JavaScript, знать о событиях и свойствах страниц и ООП. Всему этому можно научиться на нашем курсе по frontend-разработке. Кроме того, вы изучите популярные фреймворки для более сложных задач и соберёте портфолио.

Курс

Frontend-разработчик


Ноутбук, ваши навыки и знания, а также стабильный интернет — это всё, что нужно для эффективной работы. Толковые веб-разработчики высоко ценятся в международных компаниях и часто получают приглашения о работе. На курсе вы научитесь верстать сайты и создавать интерфейсы, а также соберёте два проекта в портфолио и получите современную профессию.

Хочешь получать крутые статьи по программированию?
Подпишись на рассылку Skillbox