Главная/Статьи/Простой параллакс на JavaScript и CSS Transforms
JavaScript

Простой параллакс на JavaScript и CSS Transforms

Реализация эффекта параллакса, реагирующего на движение мыши. Решение на чистом JavaScript и современном CSS для имитации зеркального отражения при перемещении курсора.

Структура разметки

Основа состоит из контейнера с изображением и текстовым блоком:

Что такое Lorem Ipsum?

Lorem Ipsum - это текст-"рыба"...

Стили CSS

Контейнер:

#boxercontainer {
  width: 80%;
  max-width: 900px;
  background-image: url(concrete-background.jpg);
  background-size: 120% 120%;
  background-position: 50% 50%;
  overflow: hidden;
}

Текстовый блок:

#boxercontainer div {
  position: absolute;
  width: 60%;
  background: rgba(0,0,0,0.2);
}

Изображение:

#boxercontainer img {
  position: absolute;
  filter: drop-shadow(-200px 200px 50px #000);
  z-index: 2;
}

JavaScript логика

Основной принцип: определить положение мыши и смещать элемент в противоположном направлении.

Инициализация переменных:

const boxer = boxercontainer.querySelector("img"),
  maxMove = boxercontainer.offsetWidth / 30,
  boxerCenterX = boxer.offsetLeft + (boxer.offsetWidth / 2),
  boxerCenterY = boxer.offsetTop + (boxer.offsetHeight / 2);

Определение координат мыши:

function getMousePos(xRef, yRef) {
  let panelRect = boxercontainer.getBoundingClientRect();
  return {
    x: Math.floor(xRef - panelRect.left) /
      (panelRect.right - panelRect.left) * boxercontainer.offsetWidth,
    y: Math.floor(yRef - panelRect.top) /
      (panelRect.bottom - panelRect.top) * boxercontainer.offsetHeight
  };
}

Обработчик события мыши:

document.body.addEventListener("mousemove", function(e) {
  let mousePos = getMousePos(e.clientX, e.clientY),
    distX = mousePos.x - boxerCenterX,
    distY = mousePos.y - boxerCenterY;
  if (Math.abs(distX) < 500 && distY < 200) {
    boxer.style.transform =
      "translate(" + (-1 * distX) / 12 + "px," + (-1 * distY) / 12 + "px)";
  }
})

Движение фона:

boxercontainer.style.backgroundPosition =
  \`calc(50% + \${distX / 50}px) calc(50% + \${distY / 50}px)\`;

Адаптивность

Проверка минимальной ширины viewport:

let fluidboxer = window.matchMedia("(min-width: 726px)");

if (Math.abs(distX) < 500 && distY < 200 && fluidboxer.matches) { … }

Важные замечания

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

Комбинация CSS-трансформаций с JavaScript-событиями обеспечивает простую реализацию параллакс-эффекта с минимальными математическими расчётами.