javascript - Javascript以恒定速度滚动div
问题描述
我有固定数量的 div 需要水平无限滚动。
因此,当您滚动时,最后会创建一个新的孩子,而另一边会删除一个孩子。像这样的东西:http: //jsfiddle.net/3neoap96/
我在 SO 中的另一个答案中找到了这个动画功能,但问题是我不想从 A 点到 BI 点的动画需要以恒定的速度进行动画,而且这个动画永远不会结束,它会一直持续下去。
这是我目前的功能。它开始正常,但随后进展非常快。
document.addEventListener("DOMContentLoaded", function (event) {
let lastPos = 0;
document.getElementById('scroll').addEventListener('scroll', evt => {
if (lastPos && lastPos - evt.target.scrollLeft > 0) {
document.querySelectorAll('.element').reverse().forEach(elem => {
if (isRightOfContainer(elem)) {
const width = elem.getBoundingClientRect().width;
elem.parentNode.prepend(elem)
elem.parentNode.parentNode.scrollLeft += width;
}
});
} else if (lastPos && lastPos - evt.target.scrollLeft < 0) {
document.querySelectorAll('.element').forEach(elem => {
if (isLeftOfContainer(elem)) {
const width = elem.getBoundingClientRect().width;
elem.parentNode.append(elem)
elem.parentNode.parentNode.scrollLeft -= width;
}
});
}
lastPos = evt.target.scrollLeft;
});
const isLeftOfContainer = element => {
const bounds = element.getBoundingClientRect();
return (-bounds.left + element.parentNode.offsetLeft) >= bounds.width;
};
const isRightOfContainer = element => {
const bounds = element.getBoundingClientRect();
const box = element.parentNode.parentNode.getBoundingClientRect();
return bounds.left - element.parentNode.offsetLeft > box.width;
};
function scrollToX(scrollTargetX, speed, easing) {
// scrollTargetY: the target scrollY property of the window
// speed: time in pixels per second
// easing: easing equation to use
const scroll = document.getElementById('scroll');
const scrollX = scroll.scrollX || scroll.scrollLeft
scrollTargetX = scrollTargetX || 0,
speed = speed || 2000,
easing = easing || 'easeOutSine';
let currentTime = 0;
// min time .1, max time .8 seconds
const time = Math.max(.1, Math.min(Math.abs(scrollX - scrollTargetX) / speed, .8));
// easing equations from https://github.com/danro/easing-js/blob/master/easing.js
const easingEquations = {
easeOutSine: (pos) => {
return Math.sin(pos * (Math.PI / 2));
},
easeInOutSine: (pos) => {
return (-0.5 * (Math.cos(Math.PI * pos) - 1));
},
easeInOutQuint: (pos) => {
if ((pos /= 0.5) < 1) {
return 0.5 * Math.pow(pos, 5);
}
return 0.5 * (Math.pow((pos - 2), 5) + 2);
}
};
// add animation loop
function tick() {
currentTime += 1 / 60;
const p = currentTime / time;
const t = easingEquations[easing](p);
if (p < 1) {
requestAnimationFrame(tick);
scroll.scrollTo(scrollX + ((scrollTargetX - scrollX) * t), 0);
} else {
console.log('scroll done');
scroll.scrollTo(scrollTargetX, 0);
}
}
// call it once to get started
tick();
}
scrollToX(1500, 0, 'easeInOutQuint');
})
我正在使用 Angular 6 顺便说一句。
解决方案
推荐阅读
- python-3.x - twilio/python/flask: TWIMLET 实现的语音邮件超时?
- visual-studio-code - VSCode:不同的终端帐户
- maven - 带有属性激活配置文件的 maven-release-plugin
- excel - 在 Excel 中删除点并保持前导零
- mysql - 使用 OCI 和 MySQL 构建 DLL 和 LabView 一直失败
- rstudio - 手动编辑 RStudio 词典中的拼写条目
- docker - 如何在 Spinnaker 中将 Jfrog Artifactory 添加为 docker 注册表?
- swift - Xcode 10 错误:链接器命令失败,退出代码为 1
- python - PyQt5:使用类创建 Windows
- javascript - 如何检测我的 iFrame 是否被其他网站使用?