【发布时间】:2019-02-12 22:02:50
【问题描述】:
我正在使用 jquery.parallax-scroll.js (J.P-S),它依赖于 window.requestAnimationFrame 来做滚动动画。 我的脚本在滚动以到达并重叠位于页面下方某处的目标元素时,会在 x 轴和 y 轴上对元素的移动进行动画处理。
只要不调整窗口大小,它就可以很好地工作。 调整窗口大小时,两个元素的位置都会发生变化,但已经进行动画的坐标不会发生变化,这会导致移动元素在滚动到目标时不再与目标重叠(未对齐)。 调整大小后刷新页面可以纠正错位,但由于显而易见的原因,这不是一个可接受的解决方案。
使用 $(window).on('resize', handler),我能够在调整大小时更新 DOM 中动画元素的“数据视差”属性。 这些是为 J.P-S 提供起点和终点坐标以及行进距离的控制属性。 但是,我无法使用更新的坐标重新启动动画。 J.P-S 确实在文档准备好时加载。 我的想法是,如果我可以让 J.P-S 脚本在使用调整大小事件的窗口更新“数据-”属性后重新启动,则将使用新更新的坐标呈现新动画,并且可以纠正错位...... 这可能是正确的方法,也可能不是正确的方法,但我的想法已经不多了……J.P-S 的 API 非常有限,除了初始调用之外没有任何事件挂钩……
一个最小的、完整的和可验证的例子位于https://codepen.io/decam/pen/daKeyj。请参阅下面的 sn-p。
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>
【问题讨论】:
标签: jquery scroll jquery-plugins window-resize requestanimationframe