javascript - 如何在页面上的特定滚动位置启动功能?
问题描述
我正在试验以下代码,其中图像在画布中翻转。
如果我把画布放在页面的中间,我想知道是否有一种方法可以只在查看者到达页面的特定部分时才让图像翻转。
现在,从外观上看,图像在页面顶部开始翻转,当您向下滚动时立即开始。当您到达实际画布所在的页面中间时,图像已经完成翻转,并且在最后一帧停止。
我假设我必须将该功能设置为仅在用户滚动到 Y 轴上特定数量的像素后触发?最好的方法是什么?
请看下面的代码。
谢谢!
var images = new Array();
var currentLocation = 0;
var totalImages = 200;
for (var i = 1; i < totalImages; i++) {
var img = new Image;
var slug = '000' + i;
img.src = 'https://s3.amazonaws.com/clearmotion/hero/high-min/frame' + slug.slice(-3) + '-low.jpg'
images.push(img);
}
var c = document.getElementById("background");
var ctx = c.getContext("2d");
var mouseWheel = function() {
var newLocation = null;
window.addEventListener('wheel', function(e) {
e.preventDefault(); // No scroll
// update our variable at high frequency
var delta = Math.max(-1, Math.min(1, e.deltaY));
if (delta == -1) currentLocation += 1;
if (delta == 1) currentLocation -= 1;
if (currentLocation < 0) currentLocation = 0;
if (currentLocation >= (totalImages - 1)) currentLocation = (totalImages - 1);
if (newLocation === null) { // if set, we already are waiting to draw
requestAnimationFrame(setImage);
}
newLocation = currentLocation;
});
function setImage() {
if (images[newLocation]) {
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(images[newLocation], 0, 0, 1000, 1000);
}
newLocation = null; // so the throttler knows we can draw again
}
}
images[0].onload = function() {
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(images[currentLocation], 0, 0, 1000, 1000);
mouseWheel();
};
<canvas id="background" width="1000" height="1000"></canvas>
解决方案
一旦查看器进入页面的特定部分,您实际上可以使用Intersection Observer API开始让图像翻转
所以你必须检测你的元素何时在视口中,在这种情况下是画布。
为此,您有多种方法。
通过使用观察者 API
const element = document.querySelector("#background")
const Ob = new IntersectionObserver((entries) => {
if (entries[0].intersectionRatio <= 0) {
// Not in the viewport
} else {
// In the viewport
// You're code here
}
});
Ob.observe(element);
或者,如果您想自己做。
您可以使用它并在需要时对其进行调整
function elementInViewport(el) {
var top = el.offsetTop
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
}
return (
top >= window.pageYOffset &&
(top + height) <= (window.pageYOffset + window.innerHeight)
);
}
推荐阅读
- c++ - std::conditional_t 用于类类型与非类类型
- postfix-mta - Postfix 中继主机是否用于到达同一域的电子邮件?
- java - Spring boot: java.sql.SQLSyntaxErrorException: 你的 SQL 语法有错误;检查手册
- next.js - Next.js:getServerSideProps 中的 res.redirect(res.redirect 不是函数)
- r - 无法安装任何 R 包,无法转换为本机编码
- java - 生成所有变体的算法
- c++ - 如果我们尝试从 C++ 中的字符中减去一个数字,结果是什么?
- javascript - 在 HTML 中使用 NodeJS 中的 Array 创建表单选项
- php - 使用 php 制作以前的下一篇文章时出现问题
- ios - 如何在完成处理程序Swift中为表格视图单元格赋值