#Руководства
- 23 июн 2020
-
12
JavaScript добавляет на страницы сайта очень интересные эффекты. Один из них — параллакс. Разбираемся, что это и как его создать самостоятельно.
vlada_maestro / shutterstock
Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.
Параллакс — это иллюзия движения объекта относительно фона, которая появляется, если движется наблюдатель. Такой эффект легко увидеть, если поднести к лицу палец и посмотреть на него сперва одним глазом, а потом вторым.
В этой статье мы рассмотрим, как создать движущиеся фон и другие элементы для сайта на JavaScript.
Исходный код вы найдёте на GitHub.
Для начала подготовим два изображения, которые нам нужны, — передний и задний планы. Для заднего плана я взял фотографию космоса:
Для переднего плана вырезал простой пейзаж с другой фотографии:
Теперь нужно сверстать элементы, в которых выводятся изображения:
<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);
}
}
Теперь можно посмотреть, как это работает:
Конечно, тут ещё многое можно улучшить: изменить размер и форму частиц на разных слоях, поработать с перспективой и размытием. Найти подходящие значения можно только перебором.
Параллакс чаще всего используют на лендингах, и это всё ещё достаточно модный эффект. Вы можете модифицировать представленный в статье код или использовать формулы, чтобы создать какой-нибудь новый эффект на основе параллакса.
Учись бесплатно:
вебинары по программированию, маркетингу и дизайну.
Участвовать
Научитесь: Профессия Frontend-разработчик
Узнать больше
Если вы хотите, чтобы сайт вызывал «вау-эффект», а ссылками на него делились, используйте параллакс. С ним сайты выглядят объёмно, а элементы могут плавно перемещаться при прокрутке страницы или движении курсора.
В этой статье мы покажем, как сделать параллакс на чистом CSS и JavaScript, поговорим про некоторые JS-библиотеки и посмотрим, как оптимизировать анимацию.
На чём делать параллакс-эффект: CSS или JavaScript
Параллакс при прокрутке страниц создают с помощью 3D трансформаций: transform-style: preserve-3d, perspective, transform: translateZ и других.
Делать такие эффекты на JavaScript слишком ресурсозатратно, потому что браузеру приходится отслеживать движение по событию scroll
, вызывать функцию перерасчёта положения блоков и смещать их. В результате страницы тормозят, а скролл становится прерывистым.
А вот параллакс по движению мыши создаётся на JavaScript. В CSS пока нет подходящих для этого свойств, но с его помощью можно оптимизировать параллакс-эффект.
Как сделать параллакс на чистом CSS
Как задать элементу глубину
Чтобы задать элементу глубину, нужно применить к нему transform: translateZ;
и указать значение свойства perspective
.
Разработчики позиционируют элементы на странице по двум осям: Х и Y, по вертикали и горизонтали. Но есть и третья ось — Z, которая отражает глубину элемента и его расстояние до пользователя. Если просто сдвинуть элемент по этой оси, задав ему свойство transform: translateZ
, то мы не увидим разницы. Элемент пока находится в двухмерной плоскости, ведь экран смартфона или монитор ноутбука не обладают глубиной.
Сделать плоскость трёхмерной можно с помощью CSS-свойства perspective
. В качестве значения оно принимает расстояние от элемента до пользователя по оси Z — чем больше это значение, тем дальше элемент от вас находится, и наоборот. Часто для perspective
указывают значение в 1px — этого достаточно, чтобы установить глубину перспективы.
Пример параллакса на чистом CSS
Сделаем параллакс при прокрутке страницы. Сначала подготовим разметку блока с параллаксом. Добавляем <div>
— родитель с классом parallax
. Внутри него создаём два элемента-слоя с классами parallax-layer
. Первый элемент — <div>
с изображением, второй — <span>
с текстом. Указываем для <div>
дополнительный класс parallax-image
, а для <span>
— parallax-text
.
<div class="wrapper parallax">
<div class="parallax-layer parallax-image">
<img src="<https://i.pinimg.com/originals/9e/20/fc/9e20fc9ba2e1456ff29caa6780521cb7.jpg>" alt="Сад изящных слов">
</div>
<span class="parallax-layer parallax-text">Сад изящных слов</span>
</div>
Задаём <div>
-родителю свойство perspective: 1px
. Оно создаёт виртуальную 3D-плоскость, указывая, что центр блока parallax
— исходная точка построения перспективы. Добавляем overflow-y: auto
, чтобы прокручивать элементы-потомки относительно фиксированной точки.
.parallax {
perspective: 1px;
height: 100vh;
overflow-y: auto;
}
Теперь удаляем внутренние элементы с классом parallax-layer
из общего потока и растягиваем на всю площадь родителя.
.parallax-layer {
position: absolute;
inset: 0; // вместо top, bottom, left, right: 0;
}
Остаётся задать смещение по оси Z. Текст будет дальше от пользователя, а фон ближе — за счёт этого мы создадим параллакс-эффект.
.parallax-image {
transform: translateZ(0);
}
.parallax-text {
transform: translateZ(-2px);
}
Добавим стили и получим результат:
See the Pen
Untitled by Mikhail (@smfms)
on CodePen.
Если открыть вкладку с CSS, можно заметить, что для блока parallax-text
задан scale(3)
— то есть элемент увеличен в три раза. Зачем мы это сделали?
Дело в том, что элемент, отдаляясь от нас в 3D-плоскости, визуально уменьшается в размерах. И наоборот, приближаясь — увеличивается. Чтобы компенсировать эти изменения, мы используем scale
. А его значение вычисляем по формуле:
1 + (translateZ * −1) / perspective
В нашем случае вычисление будет таким:
1 + (-2 * −1) / −1
Мы добились параллакс-эффекта на чистом CSS. Все использованные свойства поддерживаются современными браузерами. При желании можно добавить другие элементы в блок parallax
и играть с их смещением по оси Z. Главное — не забывайте, что при изменении положения по этой оси меняются и размеры элемента, поэтому значение scale
надо корректировать.
See the Pen
Sass parallax example by Scott Kellum (@scottkellum)
on CodePen.
Как сделать параллакс на JavaScript
Теперь создадим параллакс-эффект на JavaScript: сделаем карточку с несколькими элементами, которые будут смещаться при движении курсора — каждый со своей скоростью. Так как элементы смещаются по осям X и Y, это будет 2D-параллакс.
Для начала напишем разметку, похожую на ту, что мы использовали в прошлом примере. Нам нужны <div>
-обёртка и внутренние анимируемые элементы:
<div class="parallax">
<div class="parallax__inner">
<h1 class="parallax__layer title">
Здорово быть енотом!
</h1>
<button class="parallax__layer button" type="button">
Стать енотом
</button>
<div class="parallax__layer circle"></div>
</div>
</div>
Стили:
.parallax__inner {
position: relative;
overflow: hidden;
}
.parallax__layer {
transition: transform 0.3s linear;
}
Уже сейчас можно задать характер анимации при смещении элементов, указав свойство transition
для элементов параллакса. Для более точной настройки можно использовать кривые Безье. Но не рекомендуем использовать значение ease-in-out
: могут появиться «рывки» при быстром движении курсора, ведь функция не обладает достаточной линейностью.
Перейдём к JavaScript. Найдём параллакс-родитель и все параллакс-элементы, а затем добавим обработчик на родитель. Будем слушать движение курсора мыши — mousemove
.
const wrapper = document.querySelector('.parallax__inner');
const layers = document.querySelectorAll('.parallax__layer');
wrapper.addEventListener('mousemove', initParallax);
Опишем функцию initParallax
, в которой будем вести расчёты. Далее декомпозируем задачу: сначала найдём координаты курсора относительно карточки, а затем вычислим новые координаты для элементов при срабатывании события мыши.
Всегда вычисляйте координаты относительно того блока, на котором слушается событие мыши — тогда расчёты будут точными. Если вычислять координаты курсора относительно вьюпорта, то смещение параллакс-элементов будет рассчитываться неправильно, так как пропорции вьюпорта и карточки, скорее всего, не будут совпадать.
Сначала вычислим координаты. В JS нет метода, который возвращал бы координаты курсора относительно нужного блока. Свойство clientX
возвращает положение по оси X относительно начала вьюпорта. Чтобы начало блока parallax
совпадало с 0 по оси X, надо из положения относительно экрана вычесть левый отступ блока parallax
. В этом нам поможет метод getBoundingClientRect()
.
Перейдём к вычислениям. Для удобства записываем текущую координату в переменную и следом добавляем переменную parallaxLeftOffset
с внешним отступом блока wrapper
от границ экрана. Будем вычитать отступ из текущей позиции курсора и записывать это в переменную coordX
:
const initParallax = (evt) => {
const clientX = evt.clientX;
const clientY = evt.clientY;
const parallaxLeftOffset = wrapper.getBoundingClientRect().left;
const coordX = clientX - parallaxLeftOffset;
const coordY = clientY - parallaxTopOffset;
}
Теперь левая граница параллакс-блока совпадает с координатой 0. Это не совсем правильно, ведь мы можем отслеживать изменения курсора только вправо. Нужно сделать так, чтобы центр блока совпадал с координатой 0. Для этого дополнительно вычтем половину ширины блока.
const coordX = clientX - parallaxLeftOffset - (0.5 * wrapper.offsetWidth);
const coordX = clientY - parallaxTopOffset - (0.5 * wrapper.offsetHeight);
Чтобы получить ширину, используем свойство offsetWidth
. Теперь центр враппера — точка с координатами 0.0. Можно двигаться к самому интересному.
Мы вычислили положение курсора относительно параллакс-блока. Теперь мы можем рассчитать смещение его элементов и задать им его:
layers.forEach((layer)=>{
const x = (coordX).toFixed(2);
const y = (coordY).toFixed(2);
layer.setAttribute('style', `transform: translate(${x}px, ${y}px);`)
});
Округляем координату с помощью метода toFixed
и задаём каждому элементу трансформацию по обеим осям. Вот что получилось:
See the Pen
Untitled by Mikhail (@smfms)
on CodePen.
Теперь элементы следуют за курсором. Добавляем коэффициент скорости, который будет замедлять трансформацию элементов. Пусть он будет равен 0.5 — слишком большое значение лучше не устанавливать, так как трансформация должна быть плавной.
Будем умножать вычисленную координату на этот коэффициент.
See the Pen
Untitled by Mikhail (@smfms)
on CodePen.
Код работает, но мы забыли о сути параллакса. Параллакс — это смещение элементов с разной скоростью, а сейчас все элементы двигаются с одинаковой.
Изменим это. Коэффициент скорости будем хранить прямо в разметке в data-атрибуте, так как это удобно.
<div class="parallax">
<div class="parallax__inner">
<h1 class="parallax__layer title" data-speed="0.03">
Здорово быть енотом!
</h1>
<button class="parallax__layer button" type="button" data-speed="0.05">
Стать енотом
</button>
<div class="parallax__layer circle" data-speed="0.18"></div>
</div>
</div>
Значение не должно быть слишком большим, чтобы элементы двигались плавно. Допишем скрипт с поправкой на скорость:
layers.forEach((layer)=>{
const layerSpeed = layer.dataset.speed;
const x = (coordX * layerSpeed).toFixed(2);
const y = (coordY * layerSpeed).toFixed(2);
layer.setAttribute('style', `transform: translate(${x}px, ${y}px);`)
});
Теперь элементы двигаются с разной скоростью. Последний штрих: инвертируем значение смещаемых координат, чтобы при движении мыши влево элементы смещались вправо, и наоборот. Готово!
See the Pen
Untitled by Mikhail (@smfms)
on CodePen.
Как оптимизировать параллакс
В начале статьи мы упомянули, что параллакс ресурсозатратен для браузера — на каждое движение мыши вызывается несколько команд по перерасчёту координат. Что можно с этим сделать?
Не смещайте элементы с помощью свойств top, left, right, bottom
. Вместо них лучше использовать transform: translateX, translateY
— они снижают нагрузку на графический процессор.
В CSS есть свойство will-change. Если задать ему значение transform
, то браузер ещё до анимирования выполнит оптимизации. Это снизит нагрузку на графический процессор, и анимация будет работать плавнее, без рывков.
Теоретически, можно использовать декоратор throttle
на событии мыши. Но чаще всего у вас будут появляться нежелательные рывки при трансформации. Поэтому задавать задержку стоит с осторожностью.
Заключение
Мы показали простые способы создания параллакса на CSS и JS, но иногда нужны более сложные эффекты. Для таких случаев есть специальные библиотеки, например, Loco Scroll, parallax JS или rellax. С их помощью можно управлять направлением движения элементов, фиксировать слайды при прокрутке, создавать эффект «спешки» или «задержки» анимации.
А если хотите научиться сами делать анимации разного уровня сложности, записывайтесь на наш курс. Вы узнаете, как анимировать слайдер, бургер-меню и аккордеон. Научитесь создавать карточки товаров с 3D-эффектом, многослойный параллакс и параллакс шапки. А ещё узнаете, как оптимизировать анимации, чтобы сайт быстрее работал.
Узнать больше
- Зачем нужны анимации в вебе и как их создавать
- Как сделать интерактивную SVG-диаграмму
Время на прочтение
4 мин
Количество просмотров 164K
В этой статье показывается, как с помощью CSS трансформаций и махинаций с 3d сделать параллакс-эффект на сайте на чистом CSS.
Параллакс почти всегда создаётся с помощью JavaScript и, чаще всего, получается ресурсоёмким, из-за вешания листенеров на событие скролла, модификации DOM напрямую и срабатывания ненужных перерисовок и перестановок. Всё это происходит асинхронно с потоком, в котором браузер рендерит страницу, из-за чего скролл начинает подтормаживать, а картинка рваться на части. Более правильные реализации параллакса отслеживают скролл и используют отложенные обновления DOM с помощью requestAnimationFrame
. Получается качественной другой результат, но почему бы вообще не избавиться от JavaScript?
Перенос параллакс эффекта в CSS спасает от проблем с производительностью и лишних манипуляций, позволяя браузеру самому всё регулировать за счёт аппаратного ускорения. В результате, почти все ресурсоёмкие процессы обрабатываются напрямую браузерным движком. Частота кадров (FPS) остаётся стабильной, а картинка становится плавной. Плюс, можно сразу комбинировать параллакс с другими CSS фишками — media queries или supports. Отзывчивый параллакс — каково?
Смотреть демо
Теория
Прежде, чем погрузиться в понимание работы этого механизма, создадим необходимую разметку:
<div class="parallax">
<div class="parallax__group">
<div class="parallax__layer parallax__layer--back">
...
</div>
<div class="parallax__layer parallax__layer--base">
...
</div>
</div>
<div class="parallax__group">
...
</div>
</div>
И базовые стили:
.parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
}
.parallax__layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px);
}
Вся магия происходит в классе parallax
. Определение свойств стилей height
и perspective
установит перспективу элемента в его центре, создав фиксированный 3D вьюпорт. overflow-y: auto
позволит контенту внутри элемента нормально скроллиться, при этом потомки элемента будут отрисовываться относительно фиксированной перспективы. В этом и заключается ключ к созданию параллакс эффекта.
Далее, класс parallax__layer
. Как и следует из имени, он определяет слой контента, к которому будет применен параллакс эффект. Элемент с этим классом выдирается из общего потока контента и позиционируется так, чтобы заполнить свой контейнер.
Наконец, у нас есть классы-модификаторы parallax__layer--base
и parallax__layer--back
. Они нужны, чтобы регулировать скорость скролла параллакс элементов, смещая их по оси Z (удаляя или приближая к вьюпорту). Для краткости я сделал всего две скорости скролла — позже мы добавим еще несколько.
Смотреть демо
Коррекция глубины
Так как параллакс эффект создаётся за счёт 3D преобразований, смещение элемента по оси Z имеет побочный эффект — размеры элемента меняются, в зависимости от того, ближе или дальше он к вьюпорту. Чтобы исправить это, нам нужно применять scale()
трансформацию, чтобы элемент отрисовывался в своём изначальном размере:
.parallax__layer--back {
transform: translateZ(-1px) scale(2);
}
Коэффицент скейла можно посчитать по формуле 1 + (translateZ * -1) / perspective)
. Например, если перспектива вьюпорта задана как 1px
и мы смещаем элемент на -2px
по оси Z, то коэффицентом будет scale(3)
.
.parallax__layer--deep {
transform: translateZ(-2px) scale(3);
}
Смотреть демо с скорректированной глубиной
Регулирование скорости слоя
Скорость слоя регулируется комбинацией значений перспективы и смещения по Z. Элементы с отрицательными значениями Z будут скроллиться медленнее, чем элементы с положительными значениями. Чем больше разность значения от 0, тем явнее параллакс эффект
( т.е. translateZ(-10px)
будет скроллиться медленнее, чем translateZ(-1px)
).
Создание разных участков параллакс эффекта
Предыдущие примеры демонстрировали базовую технику использования простого контента, но ведь большинство параллакс сайтов делят страницу на разные участки с разными эффектами. Вот как можно реализовать это в нашем методе.
Во-первых, нам нужен элемент parallax__group
, чтобы сгруппировать наши слои вместе:
<div class="parallax">
<div class="parallax__group">
<div class="parallax__layer parallax__layer--back">
...
</div>
<div class="parallax__layer parallax__layer--base">
...
</div>
</div>
<div class="parallax__group">
...
</div>
</div>
для него CSS будет выглядеть так:
.parallax__group {
position: relative;
height: 100vh;
transform-style: preserve-3d;
}
В этом примере я хочу, чтобы каждая группа заполнила вьюпорт, поэтому я задаю height: 100vh
, хотя, если нужно, число для каждой группы может быть разным. transform-style: preserve-3d
не даёт браузеру сделать плоскими элементы с parallax__layer
, а position: relative
позволяет дочерним parallax__layer
элементам позиционироваться относительно их группы.
Важное правило, которое нужно помнить — при группировке элементов мы не можем обрезать контент внутри группы, тк overflow: hidden
у элемента parallax__group
сломает весь параллакс эффект. Необрезанный контент приведёт к тому, что дочерние элементы будут выступать за рамки. Поэтому нужно пошаманить с значением z-index
у группы, чтобы быть уверенным, что контент будет корректно прятаться и показываться по мере того, как пользователь будет скроллить сайт.
Нет никаких жестких или быстрых правил по поводу работы со слоями и разные методы подразумевают разную реализацию. Но, чтобы упростить отладку позиционирования слоёв, можно применить простую трансформацию групповых элементов:
.parallax__group {
transform: translate3d(700px, 0, -800px) rotateY(30deg);
}
Взгляните на следующий пример и обратите внимание на галочку debug
!
Смотреть демо с группами.
Поддержка браузеров
- Firefox, Safari, Opera и Chrome — все поддерживают эти эффекты
- Firefox работает, но у него есть небольшая проблема с выравниванием.
- IE пока не поддерживает
preserve-3d
(на подходе), поэтому параллакс работать не будет. Но это нормально, тк всё равно нужно дизайнить так, чтобы контент был адекватным и без параллакса – Ну, progressive enhancement и всё такое!
Статья — перевод (оригинал на blog.keithclark.co.uk — «Pure CSS parallax scrolling websites»)
Параллакс — это эффект, который создаёт иллюзию глубины. Например, когда вы едете в поезде и смотрите в окно, столбы проносятся мимо вас быстро, деревья и дома — со средней скоростью, а горы на фоне почти статичны. Вот эта разная скорость перемещения объектов на разной глубине и есть параллакс.
В вебе параллакс стал моден в 2010-х: обычно для этого брали фоновую картинку и скроллили её медленнее, чем контент на переднем плане. Это чисто визуальный эффект, никакого смысла в нём нет. Сегодня мы сделаем то же самое, причём двумя способами.
Простой способ — параллакс в шапке сайта
Самый простой способ что-то добавить на страницу — использовать готовое решение. В нашем случае мы будем использовать простой скрипт parallax.js — автор выложил исходный код на Гитхаб и объяснил, как им пользоваться.
Скачиваем оптимизированную минимальную версию parallax.min.js и подключаем через тег script
:
<script src="parallax.min.js"></script>
Ещё нам понадобится jQuery — без него скрипт работать не будет. Также мы скачали картинку с сервиса Unsplash, чтобы использовать её для фона.
Чтобы добавить эффект на сайт, нам теперь достаточно пометить блок с картинкой, которая останется на месте. Для этого картинке добавляем свойство data-parallax=»scroll», а остальное сделает подключённый скрипт. Чтобы было что прокручивать ниже, добавим на страницу текст из статьи про то, как работает алгоритм автомобильного навигатора.
Читайте комментарии в коде и смотрите результат на нашем тестовом сервере:
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Параллакс</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- подключаем файл со стилями -->
<link rel="stylesheet" type="text/css" href="style.css" />
<!-- подключаем jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- и скачанный скрипт -->
<script src="parallax.min.js"></script>
</head>
<body>
<!-- формируем шапку сайта и сразу указываем параметр для параллакса -->
<header class="head" data-parallax="scroll" data-image-src="header.jpg">
<h1>КОД</h1>
<h2>Журнал Яндекс Практикума</h2>
</header>
<!-- блок с основным контентом страницы -->
<div class="content">
<h2>Что ещё учитывает навигатор </h2>
<p>Чтобы алгоритм оставался простым и работал только со временем, все остальные параметры дорог тоже привязывают ко времени. Покажем, как это работает, на паре примеров.</p>
<p><strong>Комфорт</strong>. Если нам нужно построить не самый быстрый, а самый комфортный маршрут, то мы можем отдать предпочтение автомагистралям и дорогам с несколькими полосами — на них обычно и асфальт получше, и резких поворотов поменьше. Чтобы навигатор выбирал именно такие дороги, им можно присвоить коэффициент 0,8 — это виртуально сократит время на дорогу по ним на 20%, а навигатор всегда выберет то, что быстрее.</p>
<p>С просёлочными и грунтовыми дорогами ситуация обратная. Они редко бывают комфортными, а значит, им можно дать коэффициент 1,3, чтобы они казались алгоритму более долгими и он старался их избегать. А лесным дорогам можно поставить коэффициент 5 — навигатор их выберет, только если это единственная дорога то точки назначения.</p>
<p><strong>Сложность маршрута и реальное время</strong>. Маршрут из А в Б почти никогда не бывает прямым — на нём всегда есть повороты, развороты и съезды, которые отнимают время. Чтобы навигатор это учитывал, в графы добавляют время прохождения поворота — либо коэффициентом, либо отдельным параметром. Из-за этого алгоритм будет искать действительно быстрый маршрут с учётом геометрии дорог.</p>
<p><strong>Пробки</strong>. Если есть интернет, то всё просто: навигатор получает данные о состоянии дорог и добавляет разные коэффициенты в зависимости от загруженности. Иногда навигатор ведёт дворами, когда трасса свободна — это не ошибка навигатора, а его прогноз на время поездки: если через 10 минут в этом месте обычно собираются пробки, то там лучше не ехать, а заранее поехать в объезд.</p>
<p>Если интернета нет, то алгоритм просто использует усреднённую модель пробок на этом участке. Эта модель скачивается заранее и постоянно обновляется в фоновом режиме.</p>
</div>
</body>
</html>
/* настройки шапки страницы */
.head{
/* высота картинки с параллаксом */
min-height: 420px;
}
/* Настройки заголовков в шапке */
/* заголовок первого уровня */
.head h1{
/* размер шрифта */
font-size: 80px;
/* выравнивание по центру */
text-align: center;
/* тень текста */
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.7);
/* отступ сверху */
padding-top:50px;
/* цвет */
color: yellow;
}
/* заголовок второго уровня */
.head h2{
font-size: 44px;
color: yellow;
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.7);
text-align: center;
}
/* настройки блока с основным содержимым */
.content{
/* максимальная ширина */
max-width: 920px;
/* отступы по краям блока */
padding: 20px;
margin: 0 auto;
}
/* настройки абзаца внутри блока с содержимым */
p{
/* размер шрифта */
font-size: 24px;
}
Варварский способ — настройка стилей вручную
CSS поддерживает ещё один способ создать такой эффект — зафиксировать изображение и не дать его скроллить. Для этого есть свойство background-attachment:fixed
— то есть фоновая картинка намертво вклеивается в свои координаты и никуда не двигается ни при каком скролле.
Общая идея такая:
- Добавляем два блока — один будет с зафиксированной картинкой, второй с текстом. Но пока что не кладём картинку внутрь первого блока, он должен быть пустым.
- Блоку для картинки присваиваем отдельный класс CSS. Блок всё ещё пустой.
- В присвоенный класс добавляем свойство background-image, в которое прописываем путь до нужной нам картинки.
- С помощью магии CSS делаем так, чтобы блок занимал какую-то высоту и ширину, чтобы сквозь него просвечивала нужная картинка.
- Запрещаем картинке двигаться с места и подгоняем её масштаб под размер блока.
- Для текстового блока указываем, что его высота должна равняться высоте блока.
В итоге у нас получится два новых стиля:
/* настройки второго параллакса */
.parallax-img {
/* фоновая картинка */
background-image: url("map.png");
/* высота прокрутки картинки */
min-height: 500px;
/* привязываем фоновую картинку, чтобы она не двигалась */
background-attachment: fixed;
/* размещаем её по центру */
background-position: center;
/* выключаем повторения картинки */
background-repeat: no-repeat;
/* подгоняем масштаб картинки под размер блока, в котором она лежит */
background-size: cover;
}
.parallax-text {
/* ограничиваем высоту текста размером блока, в котором он лежит */
height:block;
}
Добавим на ту же страницу в блок «content
» новый раздел и карту с автомобильным маршрутом из статьи:
<h2>Как построить маршрут по всей России</h2>
<p>Если нам нужно построить маршрут из Брянска в Тулу, то с точки зрения компьютера это безумно сложная задача: ему нужно перебрать десятки тысяч улиц и миллионы перекрёстков, чтобы понять, какой путь выбрать. С этим плохо справляется даже обычный компьютер, не говоря уже о телефоне.</p>
<p>Если мы в Яндекс Картах построим такой маршрут, то навигатор нам предложит сразу 4 варианта:</p>
<div class="parallax-img"></div>
<div class = "parallax-text" >
<p>Но мы не ждали полчаса, пока сервер на той стороне посчитает все перекрёстки, а получили результат через пару секунд. Хитрость в том, что алгоритм использует уже заранее просчитанные варианты маршрутов и подставляет их для ускорения.</p>
<p>Например, если мы поедем в Тулу не из Брянска, а из Синезёрок, то поменяется только начальный маршрут по трассе М3, а всё остальное останется прежним.</p>
<p>Получается, что навигатору не нужно всё пересчитывать — он находит только ключевые точки пути, а маршрут между ними уже просчитан до этого. Этот приём работает и при перестроении маршрута во время движения: навигатор смотрит, как нужно поменять путь, чтобы вернуть вас на уже известную дорогу</p>
</div>
Видно, что всё работает, но карта видна не полностью. Это особенность работы с параллаксом — в погоне за красотой мы пожертвовали информативностью. По этой причине картинки для параллакса специально выбирают такие, чтобы если что обрезалось — то и ничего страшного.
Посмотреть работу второго параллакса на странице проекта.
Вёрстка:
Кирилл Климентьев
Simple Parallax — это крошечная и очень простая JS библиотека,
которая позволяет сделать параллакс эффект на любых изображения.
Параллакс эффект добавляется непосредственно на теги img, вам не нужно использовать свойство background-image, как во многих других параллакс библиотеках.
В принципе, вы можете добавить эффекты параллакса на уже готовый сайт,
не нарушая его макет. Перед началом работы не забудьте посмотреть наш топ 10 сайтов с параллакс эффектом
Библиотека simple Parallax
Вы также можете применить параллакс к тегам picture и srcset.
Реализовать эффект просто, а анимация получается плавная и естественная.
Установка
Установить библиотеку просто, достаточно скачать simple Parallax и добавить скрипт в свой html:
HTML
<script src="simpleParallax.js"></script>
<!--либо CDN-->
<script src="https://cdn.jsdelivr.net/npm/simple-parallax-js@5.0.2/dist/simpleParallax.min.js"></script>
Или можно установить библиотеку через пакетный менеджер npm/yarn:
#npm
npm install simple-parallax-js
#yarn
yarn add simple-parallax-js
После установки с помощью пакетного менеджера вы можете импортировать ее следующим образом:
import simpleParallax from 'simple-parallax-js';
Инициализация
Вы можете использовать любые изображения, чтобы добавить на них js параллакс. Например:
HTML
<img class="thumbnail" src="image.jpg" alt="моя картинка">
Просто добавьте следующий JavaScript код:
JS
var image = document.getElementsByClassName('thumbnail');
new simpleParallax(image);
simpleParallax — по умолчанию
Параллакс возможно применить сразу на нескольких изображениях:
JS
var images = document.querySelectorAll(img);
new simpleParallax(images);
Основы
Если вы не зададите никаких параметров, по умолчанию simpleParallax будет
использовать направление вверх. Это приведет к смещению изображения снизу вверх
при прокрутке вниз, и сверху вниз при прокрутке вверх.
Можно выбрать следующие направления:
- up
- right
- down
- left
- up left
- up right
- down left
- down right
Чтобы применить разные настройки к разным изображениям, можно инициализировать несколько
экземпляров simpleParallax, это не скажется на производительности.
HTML
<img class="left" src="image.jpg" alt="первая картинка">
<img class="right" src="image.jpg" alt="вторая картинка">
JS
var imageLeft = document.querySelector('.left'),
imageRight = document.querySelector('.right');
new simpleParallax(imageLeft, {
orientation: 'left'
});
new simpleParallax(imageRight, {
orientation: 'right'
});
simpleParallax — orientation: ‘left’
simpleParallax — orientation: ‘right’
Дополнительные настройки
JS параллакс создается с помощью scale — масштабирования, применяемого
к изображению. Scale можно легко изменить (значение по умолчанию-1.3). Чем выше будет
значение scale, тем быстрее и заметнее будет эффект параллакса.
JS
new simpleParallax(image, {
scale: 1.8
});
simpleParallax — scale: 1.8
Overflow — еще одна интересная настройка. По умолчания overflow имеет значение flase.
Если установлено значение true, изображение будет вырвано из потока.
JS
new simpleParallax(image, {
overflow: true
});
simpleParallax — overflow: true, orientation: ‘left’
Если установить параметр delay, то есть задержку. Когда
пользователь прекратит прокрутку, изображение ненадолго продолжит движение.
Это дает очень хороший эффект
В связке с delay работает настройка transition. Она добавит любой CSS эффект к настройке delay
JS
new simpleParallax(image, {
delay: .6,
transition: 'cubic-bezier(0,0,0,1)'
});
simpleParallax — delay и transition
Надеюсь, что этот туториал был вам полезен. А что, если вы хотите сделать параллакс из нескольких слоев? Тогда вам стоит посмотреть нашу статью про классный параллакс скроллинг для сайта.
Вводная: про параллакс написано много статей, а сам эффект уже лет 5 как не тренд дизайна. Если вы читаете эту статью, значит вы примерно понимаете что это такое и просто не реализовывали такую красоту раньше)
Простым языком,
параллакс (parallax)
— эффект, при котором скорость движения объектов на переднем и заднем фоне различается.
Наша задача: максимально быстро сотворить что-то вроде этого:
Но не будем тратить время, начнем.
Шаг 1 — Рисуем объекты
Создадим 4 дива и зададим каждому свой класс:
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
<div class="c4"></div>
Для каждого класса задаем position: fixed, начальное положение (left, top) и размер (width, height). Подбирайте на глаз, как вам больше нравится. Чуть ниже я выложу свой вариант. Не забываем про z-index, чтоб наши блоки не перекрывали основной контент страницы.
Теперь самое интересное: форма. Я реализовывал летающие объекты блоками с бордер-радиусами. Кто не в теме: с помощью CSS можно задать баббл практически любой формы одним простым параметром: border-radius.
Свойство поддерживает от 1 до 4 наборов значений и разделение слешем.
border-radius: 5%; — задает скругление для всех 4 углов.
border-radius: 5% 6%; — задает скругление 5% для левого верхнего и правого нижнего угла, и 6% — для двух других.
border-radius: 5% 6% 7%; — 5% — для левого верхнего, 6% — для правого верхнего и левого нижнего, 7% — для правого нижнего
border-radius: 5% 6% 7% 8%; — поочередно для левого верхнего, правого верхнего, правого нижнего и левого нижнего.
Самое инересное кроется в разделении слешем. Оно позволяет задать эллиптические углы. Вот вам картинка с htmlbook, которая демонстрирует разницу:
Но если вы думаете, что я предложу вам рисовать блоки вручную, то вы сильно ошибаетесь. Нам ведь нужно уложиться в 5 минут!)
Переходим сюда: https://9elements.github.io/fancy-border-radius/, рисуем блок нужно формы и копируем полученный набор параметров в border-radius, -webkit-border-radius и -moz-border-radius. Поддержку старых браузеров не забываем:)
Чтоб было по красоте, цвет зададим градиентами:
background: linear-gradient(130deg, #974382, #c24fa4);
Первый параметр — угол, два других — конечные цвета градиента. Покрутите угол, чтоб блоки не казались одинаковыми.
Давайте договоримся, что первые два блока будут на заднем фоне, два последние на переднем. В чем разница?
По правилам перспективы, оптики и скандинавской мифологии:
- Предметы на переднем плане движутся быстрее, чем на заднем.
- Предметы вне фокуса (ближе или дальше) размываются.
Итак, первым двум дивам зададим filter: blur(5px), а двум другим — filter: blur(3px). При желании можно задать небольшую прозрачность (opacity: 0.7;). Про скорость поговорим чуть позже, когда займемся анимацией.
Итак, у вас должно получится что-то вроде этого:
Все стили в одном месте:
.c1 {
position: fixed;
right: 160px;
top: 676px;
z-index: -100;
width: 100px;
height: 100px;
background: linear-gradient(#6A2A88, #2d1871);
filter: blur(5px);
opacity: 0.7;
-webkit-border-radius: 21% 79% 57% 43% / 23% 41% 59% 77% ;
-moz-border-radius: 21% 79% 57% 43% / 23% 41% 59% 77% ;
border-radius: 21% 79% 57% 43% / 23% 41% 59% 77% ; }
.c2 {
position: fixed;
left: 99px;
top: 940px;
z-index: -100;
width: 200px;
height: 200px;
background: linear-gradient(100deg,#843984, #4d247f);
filter: blur(5px);
opacity: 0.7;
-webkit-border-radius: 51% 49% 36% 64% / 57% 62% 38% 43%;
-moz-border-radius: 51% 49% 36% 64% / 57% 62% 38% 43%;
border-radius: 51% 49% 36% 64% / 57% 62% 38% 43%;
}
.c3 {
position: fixed;
left: 1602px;
top: -150px;
z-index: -100;
width: 100px;
height: 100px;background: linear-gradient(90deg, #883c84, #532480);
filter: blur(1px);
-webkit-border-radius: 40% 60% 61% 39% / 56% 37% 63% 44%;
-moz-border-radius: 40% 60% 61% 39% / 56% 37% 63% 44%;
border-radius: 40% 60% 61% 39% / 56% 37% 63% 44%;
}
.c4 {
position: fixed;
left: 212px;
top: 480px;
z-index: -100;
width: 100px;
height: 100px;background: linear-gradient(130deg, #974382, #c24fa4);
filter: blur(1px);-webkit-border-radius: 49% 51% 57% 43% / 44% 46% 54% 56% ;
-moz-border-radius: 49% 51% 57% 43% / 44% 46% 54% 56% ;
border-radius: 49% 51% 57% 43% / 44% 46% 54% 56% ;
}
Код скомпонован для удобства восприятия, ни кто вам не мешает выделить общие стили в отдельный класс и убрать лишние переносы строк.
Пришло время заняться анимацией.
Шаг 2 — Параллакс эффект
Раз уж статья называется «parallax за 5 минут», не будем сильно мудрить и воспользуемся готовым решением.
Я буду использовать библиотеку rellax.js (
сайт
|
github
), ну и jQuery, куда без него.
Скачайте библиотеки и подключите в файле проекта. Если ты молодец и используешь npm, воспользуйся командами:
npm install jquery --save
npm install rellax --save
Основная причина, по которой я использую rellax.js — простота. Для того, чтоб добавить эффектную анимацию достаточно написать пару строк:
$(document).ready(function(){
var c1 = new Rellax('.c1', {
speed: 5
});
var c2 = new Rellax('.c2', {
speed: 8
});
var c3 = new Rellax('.c3', {
speed: -4
});
var c4 = new Rellax('.c4', {
speed: -7
});
});
Второй параметр принимает набор характеристик. Самый востребованный — скорость. Вспомним о чем мы говорили: задний фон движется медленнее. Отрицательное значение позволит задать скорость ниже, чем скорость прокрутки страницы. Положительное — быстрее скорости прокрутки.
Готово! Сверяемся с секундомером.
Напоследок пара советов:
- Не забывайте про адаптивность. Тестируйте анимацию при разных разрешениях экрана. В мобильной версии этот эффект вообще лучше отключить. Иначе основной контент страницы будет перекрываться.
- Четко определите для себя «слои», на которых будут располагаться элементы. Скорость и размытие элементов на слое должны совпадать или отличаться незначительно.
- Экспериментируйте с перекрытиями элементов: пусть элементы на переднем фоне накладываются на фоновые, «обгоняют» их. Это добавит глубину.
- Не используйте много элементов, это рассеивает внимание.
- Ознакомьтесь с документацией parallax.js на гитхабе.
В этом уроке мы рассмотрим создание красивого сайта с Parallax-эффектом при скролле. Сегодня я покажу, как происходит разработка таких крутых сайтов и подробно объясню каждый шаг. Ключевой особенностью данного примера является, конечно-же, реализация эффекта Parallax на сайте — вы удивитесь, насколько просто и быстро можно делать подобные вещи, используя современный CSS.
Материалы урока и готовый результат: Скачать
Рекомендуемые уроки и инструменты
- Настройка VS Code для верстки: Ознакомиться с уроком
- Cubic-Bezier CSS Generator: Перейти на сайт
- Пипетка Instant Eyedropper: Скачать
- Урок по EMMET (быстрая верстка): Смотреть на YouTube
- Справочник EMMET (сокращения): Ознакомиться с уроком
Cubic-Bezier анимация для скролла:
Ниже представлен скриншот из сервиса Cubic-Bezier с изображением позиционирования точек Animation/Time. Изменяя положение ползунков на сайте сервиса, вы можете настроить анимации по своему вкусу.
--transition: transform .75s cubic-bezier(.075, .5, 0, 1);
Обновленный метод определения CSS переменной из JavaScript
Чтобы не заставлять браузер ежесекундно проверять cssText и снизить нагрузку, мы можем задать конкретное CSS свойство с переменной и сделать это не для «body», а непосредственно для «documentElement», то-есть для «html» (в CSS это :root). setProperty устанавливает и изменяет конкретное CSS свойство, поэтому в нашем случае, сложение с присваиванием +=, которое влечет за собой дополнительную проверку уже имеющегося набора свойств, использовать не обязательно.
document.documentElement.style.setProperty('--scrollTop', `${this.scrollY}px`)
Премиум уроки от WebDesign Master
Другие уроки по теме «Верстка»
- Создание сайта с крутой анимацией скролла (GSAP) | Материалы урока
- Создание красивого сайта с горизонтальным Parallax эффектом | Материалы урока
- Создание сайта портфолио с крутой анимацией | Материалы урока
- Создание Parallax эффекта на сайте при движении мыши | Материалы урока
- Создание красивого сайта с поддержкой темной темы (HTML, CSS, GSAP) | Материалы урока