当前位置: 首页 > news >正文

列表元素滚动动画

在这里插入图片描述
基于Vue2以及指令的列表滚动显示动画

<template><div><h2>Scroll Animation Demo</h2><div class="list-container"><div class="spacer">向下滚动查看动画效果...</div><div v-for="item in 10" :key="item" v-slide-in class="list-item">Item {{ item }}</div><div class="spacer">向上滚动不会触发新的动画</div></div></div>
</template><script>
const OFFSET = 200;
const DURATION = 800;
const EASING = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)';
const FILL = 'forwards';// 使用全局 WeakMap 和 IntersectionObserver
const animationMap = new WeakMap();
const animatedElements = new WeakSet(); // 记录已经动画过的元素
let lastScrollY = 0; // 记录上次滚动位置// 滚动事件处理函数
const handleScroll = () => {lastScrollY = window.scrollY;console.log('Scroll position updated:', lastScrollY);
};const intersectionObserver = new IntersectionObserver((entries) => {const currentScrollY = window.scrollY;const isScrollingDown = currentScrollY >= lastScrollY;console.log('Observer triggered:', { currentScrollY, lastScrollY, isScrollingDown,entriesCount: entries.length});entries.forEach((entry) => {console.log('Entry:', { isIntersecting: entry.isIntersecting,alreadyAnimated: animatedElements.has(entry.target)});if (entry.isIntersecting && !animatedElements.has(entry.target)) {const animation = animationMap.get(entry.target);if (animation) {console.log('Playing animation for element');animation.play();animatedElements.add(entry.target); // 标记为已动画}}});
}, {threshold: 0.1,rootMargin: '0px 0px -10px 0px' // 调整为更容易触发
});export default {name: 'TestContent11',directives: {slideIn: {inserted(el) {// 检查浏览器是否支持 Web Animations APIif (!el.animate) {console.warn('Web Animations API not supported');return;}// 设置初始样式,确保元素在动画前是隐藏的el.style.opacity = '0';// 创建动画const animation = el.animate([{transform: `translateY(${OFFSET}px)`,opacity: 0,},{transform: 'translateY(0)',opacity: 1,}], {duration: DURATION,easing: EASING,fill: FILL,});// 暂停动画animation.pause();console.log('Animation created and paused for element');// 开始观察元素intersectionObserver.observe(el);console.log('Element is being observed');// 存储动画引用animationMap.set(el, animation);},unbind(el) {// 停止观察元素intersectionObserver.unobserve(el);// 清理动画引用if (animationMap.has(el)) {const animation = animationMap.get(el);animation.cancel();animationMap.delete(el);}// 清理已动画标记animatedElements.delete(el);}}},data() {return {};},mounted() {// 初始化滚动位置lastScrollY = window.scrollY;console.log('Initial scroll position:', lastScrollY);// 监听滚动事件更新位置window.addEventListener('scroll', handleScroll, { passive: true });},beforeDestroy() {// 移除滚动事件监听window.removeEventListener('scroll', handleScroll);}
};
</script><style scoped>
.list-container {max-width: 600px;margin: 0 auto;padding-bottom: 500px; /* 添加足够的空间以便滚动 */
}.list-item {padding: 30px;margin: 20px 0;background-color: white;border-radius: 15px;box-shadow: 0 8px 25px rgba(0,0,0,0.1);border-left: 5px solid #667eea;transition: transform 0.3s ease, box-shadow 0.3s ease;font-size: 1.5em;font-weight: bold;text-align: center;color: #667eea;
}.list-item:hover {transform: translateY(-5px);box-shadow: 0 15px 35px rgba(0,0,0,0.15);
}.spacer {height: 200px;display: flex;align-items: center;justify-content: center;color: #667eea;font-size: 1.2em;opacity: 0.8;
}
</style>
http://www.dtcms.com/a/263919.html

相关文章:

  • LAN8720 寄存器概览和STM32 HAL库读写测试
  • CSS 安装使用教程
  • FreeRTOS任务切换
  • 力扣网C语言编程题:寻找两个正序数组的中位数
  • RIP 技术深度解析
  • 文心一言开源版测评:能力、易用性与价值的全面解析
  • [创业之路-457]:企业经营层 - 蓝海战略 - 价值创新不仅仅是技术创新
  • Java项目:基于SSM框架实现的智慧养老平台管理系统【ssm+B/S架构+源码+数据库+毕业论文】
  • 大麦基于HarmonyOS星盾安全架构,打造全链路安全抢票方案
  • 【机器学习深度学习】模型微调的基本概念与流程
  • 06会话管理
  • 前端计算机视觉:使用 OpenCV.js 在浏览器中实现图像处理
  • 量化选股策略 聚宽
  • 如何利用Charles中文版抓包工具提升API调试与网络性能
  • 二刷 苍穹外卖day10(含bug修改)
  • 如何使用StartUML绘制类图,用例图,时序图入门
  • 转录组分析流程(二):差异分析
  • MySQL MVCC 详解
  • ChatGPT使用限额记录与插件统计
  • 杭州来未来科技 Java 实习面经
  • [C#] WPF - 自定义样式(Slider篇)
  • 【Hive SQL优化完全指南:从0.x到4.x的性能进化之路】
  • c# IO密集型与CPU密集型任务详解,以及在异步编程中的使用示例
  • [2025CVPR]DE-GANs:一种高效的生成对抗网络
  • 微分几何、旋量理论、李群李代数、黎曼度量、微分流形、SE(3)、SO(3)
  • java微服务-linux单机CPU接近100%优化
  • Jenkins × 容器技术:构建未来DevOps生态的超级引擎
  • 插入排序解析
  • C++ dll lib 以及编译链接加载的底层机制
  • 【从历史数据分析英特尔该如何摆脱困境】