是否可以每隔 scroll/pixel 触发 Intersection Observer 回调?
Is it possible to trigger Intersection Observer callback every scroll/pixel?
我正在使用 Intersection Observer API 而不是我的动画滚动事件,但我 运行 在尝试根据滚动位置沿 offset-path
设置 SVG 动画时遇到了问题和滚动值。
path.style.offsetDistance = element.intersectionRatio * 100 + "%";
由于 Intersection Observer 回调每次通过 options
对象中定义的 threshold
值时都会触发,因此使用 element.intersectionRatio
为 offset-distance
设置动画会给我带来仅触发的故障动画每 25% 的滚动百分比。我可以将每 1% 放入选项对象中作为阈值,如下所示:
let options = {
root: null,
rootMargin: "20px",
threshold: [0.01, 0.02, 0.03, 0.04, .....]
};
但是是否有更好的解决方案,或者我是否应该切换到良好的旧滚动事件并在公式中使用 scrollY 值来平滑地计算每个 scroll/pixel 的偏移距离?
其余代码:
let options = {
root: null,
rootMargin: "20px",
threshold: [0, 0.25, 0.5, 0.75, 1]
};
let callback = (entries, observer) => {
entries.forEach(element => {
if (element.isIntersecting) {
element.target.querySelectorAll("path").forEach(path => {
path.setAttribute("style", "offset-path: path('M" + generateRandomAnimationPathM() +" " + generateRandomAnimationPathM() + " L " + generateRandomAnimationPathLine() + " " + generateRandomAnimationPathLine() + "')", "offset-rotate: 0deg");
path.style.offsetDistance = element.intersectionRatio * 100 + "%";
});
}
});
}
let generateRandomAnimationPathM = () => {
return Math.floor(Math.random() * Math.floor(100));
}
let generateRandomAnimationPathLine = () => {
return Math.floor(Math.random() * Math.floor(200));
}
let observer = new IntersectionObserver(callback, options);
document.querySelectorAll('section').forEach(section => {
console.log(section)
observer.observe(section);
});
值得注意的是,您提出的 阈值技巧 是一种 hack,不能保证 100% 的时间都有效。
这是因为 IntersectionObserver API 在内部使用 window.requestIdleCallback 将请求浏览器仅在有时间且用户未与其交互时才执行回调。这意味着即使在每 0.01 步设置一次阈值之后,动画仍然会出现故障,因为某些步骤可能会被跳过。
正如您已经说过的,通过使用 window.scrollY 计算元素在 scrollEvents 上的交集比,可以轻松实现您想要实现的目标。
我正在使用 Intersection Observer API 而不是我的动画滚动事件,但我 运行 在尝试根据滚动位置沿 offset-path
设置 SVG 动画时遇到了问题和滚动值。
path.style.offsetDistance = element.intersectionRatio * 100 + "%";
由于 Intersection Observer 回调每次通过 options
对象中定义的 threshold
值时都会触发,因此使用 element.intersectionRatio
为 offset-distance
设置动画会给我带来仅触发的故障动画每 25% 的滚动百分比。我可以将每 1% 放入选项对象中作为阈值,如下所示:
let options = {
root: null,
rootMargin: "20px",
threshold: [0.01, 0.02, 0.03, 0.04, .....]
};
但是是否有更好的解决方案,或者我是否应该切换到良好的旧滚动事件并在公式中使用 scrollY 值来平滑地计算每个 scroll/pixel 的偏移距离?
其余代码:
let options = {
root: null,
rootMargin: "20px",
threshold: [0, 0.25, 0.5, 0.75, 1]
};
let callback = (entries, observer) => {
entries.forEach(element => {
if (element.isIntersecting) {
element.target.querySelectorAll("path").forEach(path => {
path.setAttribute("style", "offset-path: path('M" + generateRandomAnimationPathM() +" " + generateRandomAnimationPathM() + " L " + generateRandomAnimationPathLine() + " " + generateRandomAnimationPathLine() + "')", "offset-rotate: 0deg");
path.style.offsetDistance = element.intersectionRatio * 100 + "%";
});
}
});
}
let generateRandomAnimationPathM = () => {
return Math.floor(Math.random() * Math.floor(100));
}
let generateRandomAnimationPathLine = () => {
return Math.floor(Math.random() * Math.floor(200));
}
let observer = new IntersectionObserver(callback, options);
document.querySelectorAll('section').forEach(section => {
console.log(section)
observer.observe(section);
});
值得注意的是,您提出的 阈值技巧 是一种 hack,不能保证 100% 的时间都有效。
这是因为 IntersectionObserver API 在内部使用 window.requestIdleCallback 将请求浏览器仅在有时间且用户未与其交互时才执行回调。这意味着即使在每 0.01 步设置一次阈值之后,动画仍然会出现故障,因为某些步骤可能会被跳过。
正如您已经说过的,通过使用 window.scrollY 计算元素在 scrollEvents 上的交集比,可以轻松实现您想要实现的目标。