Изменение размера окна вызывает смещение элементов в анимации прокрутки, которая использует requestAnimationFrame - PullRequest
0 голосов
/ 13 февраля 2019

Я использую jquery.parallax-scroll.js (JP-S), который использует window.requestAnimationFrame для анимации прокрутки.Мой сценарий анимирует перемещение элемента по осям x и y при прокрутке, чтобы достичь и перекрыть целевой элемент, расположенный где-то внизу страницы.

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

Используя $ (window) .on ('resize', обработчик), я могу - при изменении размера - обновитьатрибуты «data-parallax» анимированного элемента в DOM.Это управляющие атрибуты, которые предоставляют JP-S начальные и конечные координаты, а также расстояние до места прохождения.Однако я не смог перезапустить анимацию с обновленными координатами.JP-S действительно загружается, когда документ готов.Я думаю, что если бы я мог заставить скрипт JP-S перезапуститься после того, как атрибуты «data-» были обновлены с помощью окна при событии изменения размера, новая анимация была бы визуализирована с новыми обновленными координатами, и смещение было бы исправлено ...может или не может быть правильным подходом, но у меня заканчиваются идеи ... JP-S имеет очень ограниченный API без перехватчиков событий, кроме начального вызова ...

Минимальный, полный и проверяемый пример находится по адресуhttps://codepen.io/decam/pen/daKeyj. См. Также фрагмент ниже.

jquery.parallax-scroll.js находится по адресу https://github.com/alumbo/jquery.parallax-scroll.

Как можно исправить смещение, вызванное изменением размера окна, без перезагрузкистраница?

'use strict';

$(function() {
  ScrollAnimations.init();
});

let ScrollAnimations = {
  init: function() {
    this.setAnimations();
  },

  setAnimations: function() {
    setDataPararllax();

    function setDataPararllax() {
      // Get the bullet element's top and left
      // coordinates from declared CSS
      let $bullet = $('#bullet');
      let bullet_top = parseFloat($bullet.css('top'));
      let bullet_left = parseFloat($bullet.css('left'));

      // Get the target element's relative top and
      // left coordinates
      let $target = $('#target');
      let target_top = $target.position().top;
      let target_left = $target.position().left;

      // Calculate x and y distance offsets
      let x_distance = target_left - bullet_left;
      let y_distance = target_top - bullet_top;

      // Prepare JSON objects with the controlling parameters
      // required by the jquery-Parallax-Scrolling.js script
      // to be added as data- attributes of the bullet element
      let data_consts = `"from-scroll": ${bullet_top}, "to-scroll": ${target_top - bullet_top}, "smoothness": 10`;
      let data_p_y = `{"y": ${y_distance}, ${data_consts}}`;
      let data_p_x = `{"x": ${x_distance}, ${data_consts}}`;

      // Add the data- attributes to the bullet element
      $bullet.attr({
        'data-parallax': data_p_y,
        'data-parallax2': data_p_x
      });
    }
  }
};
html,
body,
.panel {
  padding: 0;
  margin: 0;
  color: #96b38a;
  font-family: sans-serif;
  font-size: 20px;
  font-weight: 400;
}


/* Set bullet absolute position to any
  value using top and left properties */

#bullet {
  position: absolute;
  top: 50vh;
  left: 75vw;
}

#top {
  height: 120vh;
  background-color: #333333;
  text-align: center;
}

#bottom {
  height: 250vh;
  background-color: #666666;
}

.panel {
  display: flex;
  align-items: center;
  justify-content: center;
}

span {
  font-size: 2em;
  color: #ddca7e;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1" />
  <title>Scroll Bullet->Target Animation</title>
</head>

<body>
  <svg id="bullet" height="10" width="10">
      <circle cx="5" cy="5" r="5" fill="white" />
    </svg>
  <div id="top" class="panel">
    <p><span>Scroll down...</span><br> Window resizing is NOT yet supported...<br> If white bullet doesn't overlap the black target after scrolling,<br>you've resized the window...<br> Refresh the browser and try again.<br> I'm currently working on a solution...
    </p>
  </div>
  <div id="bottom" class="panel">
    <svg id="target" height="10" width="10">
        <rect width="10" height="10" fill="black" />
      </svg>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/gh/alumbo/jquery.parallax-scroll/js/jquery.parallax-scroll.js"></script>
</body>

</html>

1 Ответ

0 голосов
/ 15 февраля 2019

Я нашел решение и отвечаю на свой вопрос на случай, если кто-нибудь еще столкнется с чем-то похожим в будущем.

Скрипт JP-S работает, анимируя стиль элемента DOM на основе настроек JSON.передается через атрибуты data-parallax.Сценарий добавляет атрибут style с анимациями.

Чтобы элементы (и их анимации) выровнялись при изменении размера окна, я вызываю функцию для события изменения размера окна, чтобы заменить атрибуты data-parallax.Я удаляю все атрибуты data-parallax и style из элемента DOM, а не только их значения, и присоединяю новые атрибуты данных с другим именем и новыми значениями.Используя счетчик, я создаю и прикрепляю новые атрибуты данных.Например, data-1parallax для первого события изменения размера, data-2parallax для второго и так далее.Затем я вызываю небольшую функцию, добавленную в сценарий JP-S, которая заменяет имена атрибутов данных, которые используются сценарием для получения параметров и анимации элемента.Это имя заменяется соответствующим именем, сгенерированным для события изменения размера (я передаю значение счетчика);Очевидно, я сделал имя атрибута данных в сценарии переменной.

В результате я получаю новые данные - [#] атрибуты параллакса со значениями JSON, рассчитанными после изменения размера (предыдущие данные- [#] атрибуты параллакса были удалены), а затем скрипт генерирует новый атрибут стиля с правильными значениями.Отмена события гарантирует, что я запускаю этот процесс только один раз для каждого пользователя при изменении размера окна.Если кому-то понадобятся дополнительные разъяснения или код, пожалуйста, оставьте комментарий, и я предоставлю.

Я обновил CodePen с исправленной версией, и вы можете продемонстрировать сценарий с изменяемым размером там.См. Ссылку на CodePen внутри вопроса.

...