我的嘛也!实现一个时间轴无缝轮播居然如此简单......

废话不多说,先贴效果图

看图片可以把这个分割成两部分 1.时间轴 2.图片展示

  1. 首先来分析一下时间轴 可视范围这样 实际长度 操作 给实际长度添加动画效果 css部分 :style="{ '--translateX' : translateX }" transform: translateX(calc(var(--translateX) * 1px));//1px是因为要用postcss转rem transition: transform 0.6s ease-out; js部分 const translateX = ref(0); 这就是主要实际长度的主要代码,是不是很简单translateX 的值根据自己需求偏移量计算
  2. 接下来分析时间点: 分析一波:点主要是间隔分布,用间隔倍数来绝对定位确定每个点的位置 const dots = ref([])点的数组 const dotSpacing = 251.5;点间距 css部分 :style="{'--x': ${index * dotSpacing}}" left: calc(var(--x) * 1px); 确定好样式了接下来就来实现点击轮播了 先实现位置的重新计算direction 是传的值,1,-1表示左右🙂 const newPosition = Number((translateX.value + direction * dotSpacing)); 将值赋给偏移量就实现动画了 translateX.value = newPosition; 是不是比较简单嘿! 那怎么实现无限无缝的轮播呢?
  3. 无限轮播 无缝循环轮播的要点就是: 1.前后复制一组数据,避免出现空白 2.在复制的数据在到达另一个边界的时候,回到原来的位置,利用屏幕刷新率,也就是帧率骗过用户的眼睛,达到无缝循环的视觉错觉 前后各复制一组数据 const clonedDots = [ ...dots.map(d => ({ ...d, cloned: true })), ...dots, ...dots.map(d => ({ ...d, cloned: true })), ]; const newPosition = Number((translateX.value + direction * dotSpacing));获得偏移量 if (newPosition <= -(dots.length * dotSpacing))如果b到达a的边界 translateX.value = newPosition继续进行偏移 translateX.value = 0;偏移完成后回到原点 transition: transform 0.6s ease-out因为我们设置了过渡效果,所以会有动画回到原点 那么我们就应该在b到达a点后禁用过渡立即重置,这里使用的是定时器,然后我们在下一帧的时候重新启用过渡效果 setTimeout(() => { trackRef.value!.style.transition = 'transform 0s'; translateX.value = 0; setTimeout(() => { trackRef.value!.style.transition = 'transform 0.6s ease-out'; },16); },600); 一般屏幕的刷新率都是16,也可以设置为0 这样我们就实现了无缝循环了,是不是还可以,但还是有点小问题,用户快速点击还是会有瑕疵的 所以我们应该添加一个防抖函数或者标识 那我们怎么去给中间的点添加动态的样式呢? 我这里用的是 const currentIndex = ref(2); 根据我自己的需要设置默认第二个是在中间的 这样就只需要累加的方式就可以了 direction < 0 ? currentIndex.value ++: currentIndex.value -- ; 然后重置的也就是比较死板 currentIndex.value = 2; currentIndex.value = dots.length + 1; 不知道有没有什么更灵活的方式 这样就完成了时间轴的绘制了👌👌👌 然后底下的切换也是比较简单 可以手写或者像我一样使用vue的组件transition-group 因为我们只需要展示三个就不用去复制了 const currentItem = computed(() => clonedDots[currentIndex.value]); const prevItem = computed(() => clonedDots[currentIndex.value - 1]); const nextItem = computed(() => clonedDots[currentIndex.value + 1]); const transitionName = ref('slide-next'); 然后用effect函数监听变化 watch(currentIndex, (newVal, oldVal) => { transitionName.value = newVal > oldVal ? 'slide-next' : 'slide-prev'; }); 剩下的就只需要css去动画就可以了

点击查看代码

css 复制代码
.slide-next-enter-active,
.slide-next-leave-active,
.slide-prev-enter-active,
.slide-prev-leave-active {
  transition: all 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  transform-style: preserve-3d; /* 保持3D变换 */
}
.slide-next-enter-from {
  transform: scale(0.8) translateX(500px) translateZ(-100px);
}
.slide-next-enter-to {
  transform: scale(1) translateX(0) translateZ(0);
}
.slide-next-leave-active {
  z-index: 0; /* 确保离开元素在下层 */
}
.slide-next-leave-to {
  transform: scale(0.8) translateX(-500px) translateZ(-100px);
}
/* 上一张进入动画 */
.slide-prev-enter-from {
  transform: scale(0.8) translateX(-500px) translateZ(-100px);
}
.slide-prev-enter-to {
  transform: scale(1) translateX(0) translateZ(0);
}
.slide-prev-leave-active {
  z-index:0 !important; /* 确保离开元素在下层 */
}
.slide-prev-leave-to {
  transform: scale(0.8) translateX(500px) translateZ(-100px);
  z-index: 0 !important;
}

  /* 当前激活项样式 */
  .swiper-item:not(.prev):not(.next) {
    z-index: 4;
    box-shadow: 0 10px 25px rgba(0,0,0,0.2);
  }
  /* 相邻项样式 */
  .prev, .next {
    transform: scale(0.8) translateZ(-100px);

  }
  .prev {
    transform: scale(0.8) translateX(-500px) translateZ(-100px);

  }
  .next {
    transform: scale(0.8) translateX(500px) translateZ(-100px);
  }

到这里我们理顺了这个组件的实现方法😄

相关推荐
恋猫de小郭1 小时前
Android Studio Cloud 正式上线,不只是 Android,随时随地改 bug
android·前端·flutter
清岚_lxn6 小时前
原生SSE实现AI智能问答+Vue3前端打字机流效果
前端·javascript·人工智能·vue·ai问答
ZoeLandia6 小时前
Element UI 设置 el-table-column 宽度 width 为百分比无效
前端·ui·element-ui
橘子味的冰淇淋~6 小时前
解决 vite.config.ts 引入scss 预处理报错
前端·vue·scss
小小小小宇8 小时前
V8 引擎垃圾回收机制详解
前端
lauo9 小时前
智体知识库:ai-docs对分布式智体编程语言Poplang和javascript的语法的比较(知识库问答)
开发语言·前端·javascript·分布式·机器人·开源
拉不动的猪9 小时前
设计模式之------单例模式
前端·javascript·面试
一袋米扛几楼989 小时前
【React框架】什么是 Vite?如何使用vite自动生成react的目录?
前端·react.js·前端框架
Alt.99 小时前
SpringMVC基础二(RestFul、接收数据、视图跳转)
java·开发语言·前端·mvc
进取星辰10 小时前
1、从零搭建魔法工坊:React 19 新手村生存指南
前端·react.js·前端框架