调整窗口大小会导致使用requestAnimationFrame

时间:2019-02-12 22:02:50

标签: jquery scroll jquery-plugins window-resize requestanimationframe

我使用的jquery.parallax-scroll.js(J.P-S)依赖window.requestAnimationFrame来进行滚动动画。 我的脚本为元素在X和y轴上的移动动画设置动画,同时滚动以到达并重叠位于页面下方某处的目标元素。

只要不调整窗口大小,它就可以很好地工作。 调整窗口大小时,两个元素的位置都会改变,但是已经进行中的动画的坐标不会改变,这会导致移动元素在滚动到目标时不再与目标重叠(未对齐)。 调整大小后刷新页面可纠正未对齐问题,但是出于明显的原因,这不是可接受的解决方案。

使用$(window).on('resize',handler),我能够-在调整大小时-更新DOM中动画元素的“数据视差”属性。 这些是为J.P-S提供起点和终点坐标以及行进距离的控制属性。 但是,我无法使用更新的坐标重新启动动画。 文档准备就绪后,实际上已加载了J.P-S。 我的想法是,如果我可以使用resize事件上的窗口更新“ data-”属性后重新启动J.P-S脚本,则将使用新的更新坐标渲染新动画,并纠正不对齐的情况…… 这可能是正确的方法,但可能是不合适的,但我的想法已荡然无存……J.P-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 :(得分:0)

我找到了解决方案,并回答自己的问题,以防将来其他人遇到类似情况。

J.P-S脚本根据通过数据视差属性传递的JSON设置来动画化DOM元素的样式。 该脚本将style属性与动画一起添加。

要在调整窗口大小时使元素(及其动画)重新对齐,我在Windows调整大小事件上调用一个函数来替换数据视差属性。 我从DOM元素中删除了整个数据视差和样式属性,而不仅仅是它们的值,并使用其他名称和新值附加了新数据属性。 使用计数器,我创建并附加了新的数据属性。例如。 data-1parallax用于第一个调整大小事件,data-2parallax用于第二个调整事件,依此类推。 然后,我调用添加到J.P-S脚本中的一个小函数,该函数替换脚本用来获取参数和为元素设置动画的数据属性名称。 该名称将替换为在调整大小事件中生成的匹配名称(我传递了计数器值); 显然,我已经在脚本中将数据属性名称设置为变量。

结果,我最终得到新的data-[#]视差属性,并在调整大小后计算出JSON值(删除了先前的data-[#]视差属性),然后脚本生成了具有正确值的新样式属性。 取消事件的弹跳可确保每个用户调整窗口大小仅运行一次此过程。 如果有人需要更多说明或代码,请发表评论,我会提供。

我已经用正确的版本更新了CodePen,您可以在那里演示可调整大小的脚本。请参阅问题内指向CodePen的链接。