如何实现一个无缝无限轮播时间轴
笔记哥 /
04-10 /
36点赞 /
0评论 /
607阅读
废话不多说,先贴效果图

看图片可以把这个分割成两部分
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去动画就可以了
点击查看代码
```csharp
.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);
}
```
到这里我们就完成了这个组件
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/2142
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利