时间:2025-04-10 15:15
人气:
作者:admin
废话不多说,先贴效果图

看图片可以把这个分割成两部分
1.时间轴
2.图片展示
:style="{ '--translateX' : translateX }"transform: translateX(calc(var(--translateX) * 1px));//1px是因为要用postcss转remtransition: transform 0.6s ease-out;const translateX = ref(0);const dots = ref([])点的数组const dotSpacing = 251.5;点间距:style="{'--x': ${index * dotSpacing}}"left: calc(var(--x) * 1px);const newPosition = Number((translateX.value + direction * dotSpacing));translateX.value = newPosition;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因为我们设置了过渡效果,所以会有动画回到原点setTimeout(() => {trackRef.value!.style.transition = 'transform 0s';translateX.value = 0; setTimeout(() => {trackRef.value!.style.transition = 'transform 0.6s ease-out'; },16);},600);const currentIndex = ref(2); direction < 0 ? currentIndex.value ++: currentIndex.value -- ;currentIndex.value = 2;currentIndex.value = dots.length + 1;transition-groupconst currentItem = computed(() => clonedDots[currentIndex.value]);const prevItem = computed(() => clonedDots[currentIndex.value - 1]);const nextItem = computed(() => clonedDots[currentIndex.value + 1]);const transitionName = ref('slide-next');watch(currentIndex, (newVal, oldVal) => { transitionName.value = newVal > oldVal ? 'slide-next' : 'slide-prev'; });.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);
}
到这里我们理顺了这个组件的实现方法????
下一篇:记录---纯前端实现分享短链接



