该代码参考抖音渡一前端必修课的视频
效果图
页面使用
模板代码
<div v-slide>这是一个方块自行添加样式</div>
模板脚本
import slide from "./directives/slide";
const vSlide = {
mounted: (el) => {
slide.mounted(el);
},
unmounted: (el) => {
slide.unmounted(el);
},
};
slide代码
import { getCssVariable } from "@qhy/common";
// 定义元素滑入动画的距离和持续时间
const DISTANCE: number = 40;
const DURATION: number = 1400;
// 页脚高度
const footerHeight = parseFloat(getCssVariable(`--app-footer-height`));
let isScrollBottom= false; //页面是否向下滚动
let listenersAdded = false; //是否添加过监听
let oldScrollTop = 0
const animations = new WeakMap();
// 创建一个IntersectionObserver实例,用于检测元素是否进入视图区域
const observer = new IntersectionObserver((entries) => {
// 当元素进入视图区域时,获取存储的动画对象并播放动画,然后停止观察该元素
for (const entry of entries) {
// 判断是否出现在视口中
const animation = animations.get(entry.target);
if (animation && isScrollBottom) {
animation.play();
// observer.unobserve(entry.target); // 取消元素观察
}
}
});
// 判断元素是否在视图区域下方
const isBelowViewport = (el: HTMLElement) => {
const rect = el.getBoundingClientRect();
return rect.top - window.innerHeight + footerHeight > 0;
};
const scrollYFun = (e) => {
const scrollTop = e.target.scrollTop;
const scrollStep = scrollTop - oldScrollTop;
oldScrollTop = scrollTop;
isScrollBottom = scrollStep > 0;
};
// 定义滑入动画的类
const slide = {
// 在元素挂载时应用动画
mounted(el: HTMLElement) {
console.log("mounted");
if (!listenersAdded) {
window.addEventListener("scroll", scrollYFun, true);
listenersAdded = true;
}
// 如果元素不在视图区域下方,则无需应用动画
if (!isBelowViewport(el)) {
return;
}
// 创建并设置动画,然后将动画对象存储在WeakMap中,并开始观察元素
const animation = el.animate(
[
{
transform: `translateY(${DISTANCE}px)`,
opacity: 0.5,
},
{
transform: "translateY(0)",
opacity: 1,
},
],
{
duration: DURATION,
easing: "ease",
fill: "forwards",
}
);
animation.pause();
animations.set(el, animation);
observer.observe(el);
},
// 在元素卸载时停止观察
unmounted(el: any) {
observer.unobserve(el);
animations.delete(el); // 清除动画记录
if (listenersAdded) {
window.removeEventListener("scroll", scrollYFun, true);
}
},
};
export default slide;
脚本获取scss变量的值
我这里的getCssVariable
方法是封装好的获取变量值的
const getCssVariable = (variableName: string): string => {
return getComputedStyle(document.documentElement)
.getPropertyValue(variableName)
.trim();
};
console.log(getCssVariable('--变量名'))