Параллакс эффект перемещением курсора мыши на сайт (jQuery)

Параллакс эффект перемещением курсора мыши на сайт (jQuery) - Дмитрий Языков

Задача: разработать параллакс эффект движущейся толпы, реагирующей на передвижение курсора мыши без бустовых библиотек вроде rellax.js.

Для начала, вот что должно получиться:


Мы с вами уже реализовывали простой параллакс эффект в предыдущей статье. Если не видели - вот ссылка.

В отличие от предыдущего примера, мы не будем использовать готовую библиотеку, а значит придется немного поколдовать над математикой.

Шаг 1 - Подготовка

Для начала нам нужно найти и подготовить изображение. Я пользовался бесплатным стоком Unsplash и искал в нем картинки по запросу crowd (толпа) и concert (концерт). Вы можете выбрать и скачать любое понравившееся изображение, но для упрощения дальнейшей работы воспользуйтесь парой советов:

  • Позиция камеры (точка, откуда осуществлялась съемка) должна находиться за спинами людей.
  • Силуэты людей должны быть различимы. Если возьмете изображение, на котором людей практически не видно - будет сложнее вырезать их и развести по разным слоям в фотошопе.
  • Чем больше места (по высоте) на изображении занимает толпа, тем эффектнее получится результат.

В остальном ни в чем себя не ограничивайте: выбирайте то, что понравится.

Шаг 2 - Магия фотошопа

Итак, у вас есть подходящее изображение. Если все еще нет - вернитесь к первому шагу.

Открываем в изображение в фотошопе или любом другом редакторе. И начинаем методично вырезать людей ряд за рядом.

экран photoshop

Берем инструмент лассо и обводим контуры людей, находящихся ближе всего к нам (к позиции камеры). Стараемся чтоб в итоге получилось выделение от левого до правого края изображения примерно одинаковой высоты. У меня получилось вот так:

вырезанный слой с людьми

У вас, конечно, получится аккуратнее)

Вырезаем выделенную область и помещаем на новый слой. Заливаем фоновым цветом прозрачные области ниже вырезанного фрагмента. Прозрачные области выше оставляем как есть. Повторяем действия.

В итоге у меня получилось 4 слоя. Самым нижним будет сцена, а дальше слои с людьми: сверху те, что находятся на изображении ближе к камере, снизу те, что находятся дальше от камеры (ближе к сцене):

Вот так это выглядит в фотошопе:

слои в фотошоп

А вот так наглядно.

слои наглядно

Надеюсь проблем с этим не возникло, но если что - добро пожаловать в комментарии:)

Последним этапом сохраняем слои как отдельные изображения в png формате (нам важна прозрачность).

Шаг 3 - Разметка и стили (html и css)

С html все просто: контейнер, в нем под каждый "слой" - свой div, в дивах изображения:

<div class="container">
        <div id="scene" class='parallax' data-speed="-4">
            <img src="https://ydmitry.ru/upload/blog/crowd/scene.png">
        </div>
        <div id="crowd-first" class='parallax'>
            <img src="https://ydmitry.ru/upload/blog/crowd/crowd-first.png">
        </div>
        <div id="crowd-second" class='parallax' data-speed="-2">
            <img src="https://ydmitry.ru/upload/blog/crowd/crowd-second.png">
        </div>
        <div id="crowd-third" class='parallax' data-speed="-3">
            <img src="https://ydmitry.ru/upload/blog/crowd/crowd-third.png">
        </div>
</div>

Data-speed мы будем использовать для корректировки скорости движения блоков.

По стилям. Для контейнера задаем ширину и высоту по размеру изображения, а также overflow: hidden чтобы содержимое обрезалось, когда мы будем его двигать. Ну и position: relative, относительно этого контейнера мы будем позиционировать все вложенные блоки. Все остальные стили - по вкусу. В моем случае это центрирование и задание цвета фона.

.container {
    position: relative;
    bottom: 0;
    background: #1f2c2c;
    height: 800px;
    width: 1200px;
    margin: 0 auto;
    overflow: hidden;
}

Всем блокам под изображения задаем класс parallax. Им ставим position: absolute. Блокам с изображениями проставляем z-index.

.parallax {
    position: absolute;
}
#scene {
    z-index: 100;
}
#crowd-third {
  z-index: 200;
}
#crowd-second {
  z-index: 300;
}
#crowd-first {
  z-index: 400;
}

Шаг 4 - JavaScript (джейквайри детектед)

Как всегда, код оформлен для лучшего понимания, кто захочет - отрефакторит для продакшена :)

$(document).ready(function(){
  var elem = $('.container'),         //    Контейнер, в котором будем проводить анимацию
      pos = elem.offset(),            //    Позиция элемента
      elem_left = pos.left,           //    Слева
      elem_top = pos.top,             //    Сверху
      elem_width = elem.width(),      //    Ширина элемента
      elem_height = elem.height(),    //    Высота элемента
      x_center,    //    Координаты центра по оси X
      y_center;    //    Координаты центра по оси Y
//    Обрабатываем событие перемещения курсора мыши
  $('.container').mousemove(function(e){    
//    Определяем центр элемента (формула легко гуглится)
    x_center = ( elem_width / 2 ) - ( e.pageX - elem_left );
    y_center = ( elem_height / 2 ) - ( e.pageY - elem_top );
//    Проходим по всем блокам с изображениями)
    $('.parallax').each(function(){
      var speed = $(this).attr('data-speed'),     //    Определяем скорость
          xPos = Math.round(-1*x_center/20*speed),//    Высчитываем позицию по оси X, движения будут инвертированы (-1). Формула подбиралась на глаз
          yPos = Math.round(y_center/20*speed);   //    Высчитываем позицию по оси Y
//    Перемещение по оси Y делаем до определенной точки, потом перемещение останавливаем
      if (yPos < 0)
        yPos = -2*speed;
//    Непосредственно перенос      
      $(this).css('transform', 'translate3d('+xPos+'px, '+yPos+'px, 0px)');
       });
    });
});
Вот и все. Весь код и параллакс в действии можно посмотреть на codepen.  

Услуги

Подпишись на меня в Телеграм, не пропускай новые статьи

К выступлениям