用户3096723
用户3096723
  • 发布:2026-07-09 09:26
  • 更新:2026-07-09 09:26
  • 阅读:15

Stack组件实现Swiper堆叠动画效果

分类:uni小程序sdk

问题现象
Swiper如何实现卡片堆叠样式:

上下堆叠:Swiper内容像卡片堆叠,在底部留部分空间显示下一页的内容,上下滑实现卡片切换。
左右堆叠:Swiper内容像卡片堆叠,在右侧留部分空间显示下一页的内容,左右滑实现卡片切换。
背景知识
Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。
Stack是堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。
gesture可以为组件绑定手势方法进行相应处理,如滑动手势事件PanGesture。
animateTo指定由于闭包代码导致的状态变化插入过渡动效。
解决方案
上下堆叠实现。
自定义实现卡片堆叠的组件:使用Stack组件堆叠需要展示的图片,设置最上面的图片向上偏移部分距离,露出下一张图片的底部。为Stack绑定上下滑动的手势处理,实现切换图片逻辑,同时使用animateTo接口设置图片切换动画。

export class SwiperData {
imageSrc: Resource;

constructor(imageSrc: Resource) {
this.imageSrc = imageSrc;
}
}

@Component
export struct SwiperStackComponent {
@Link currentIndex: number;
@Prop swiperData: SwiperData[];
private halfCount: number = Math.floor(3 / 2);
private automaticSlidingDuration: number = 300;

aboutToAppear(): void {
this.currentIndex = 0;
}

// 修改堆叠方向系数计算
getImgCoefficients(index: number): number {
const coefficient = this.currentIndex - index;
const tempCoefficient = Math.abs(coefficient);
if (tempCoefficient <= this.halfCount) {
return coefficient;
}
const dataLength = this.swiperData.length;
let tempOffset = dataLength - tempCoefficient;
if (tempOffset <= this.halfCount) {
return coefficient > 0 ? -tempOffset : tempOffset;
}
return 0;
}

// 修改堆叠方向偏移量计算
getOffSet(index: number): number {
let offsetIndex = this.getImgCoefficients(index);
const tempOffset = Math.abs(offsetIndex);
let offset = 0;
if (tempOffset === 1) {
if (offsetIndex === 1) {
offsetIndex = -1;
}
offset = 50 * offsetIndex;
}
return -offset;
}

startAnimation(isLeft: boolean, duration: number): void {
this.getUIContext().animateTo({ duration: duration, }, () => {
const dataLength: number = this.swiperData.length;
const tempIndex: number = isLeft ? this.currentIndex + 1 : this.currentIndex - 1 + dataLength;
this.currentIndex = tempIndex % dataLength;
});
}

build() {
Stack() {
ForEach(this.swiperData, (item: SwiperData, index: number) => {
Stack({ alignContent: Alignment.Bottom }) {
Image(item.imageSrc)
.objectFit(ImageFit.Cover)
.width('100%')
.height('100%')
.borderRadius(8);
}
.offset({ x: 0, y: this.getOffSet(index) })
.shadow(ShadowStyle.OUTER_DEFAULT_SM)
.backgroundColor(Color.White)
.borderRadius(8)
.blur(index !== this.currentIndex ? 12 : 0)
// 通过animateTo实现动画并且同时改变currentIndex数据中间值来判断组件zIndex实现切换动画
.zIndex(index !== this.currentIndex && this.getImgCoefficients(index) === 0 ?
0 : 2 - Math.abs(this.getImgCoefficients(index)))
.width(310)
.height(index !== this.currentIndex ? 130 : 180);
});
}
.height(200)
.width('100%')
.gesture(
PanGesture({ direction: PanDirection.Vertical })
.onActionStart((event: GestureEvent) => {
this.startAnimation(event.offsetY < 0, this.automaticSlidingDuration);
})
)
.alignContent(Alignment.Center)
.padding({ left: 12, right: 12, top: 12 });
}
}
在页面中直接使用上面封装好的SwiperStackComponent即可,示例如下:传给SwiperStackComponent要堆叠的图片。
https://pastebin.com/m1LSXzRK
https://pastebin.com/cFaDz2JM
https://pastebin.com/94NrGTMh
https://pastebin.com/Yjx17LeK
https://pastebin.com/LqsPJ96h
https://pastebin.com/DPDgXMvK
https://pastebin.com/hSjsmXQA
https://pastebin.com/uKP1SMUS
https://pastebin.com/NzZpsC1T
https://pastebin.com/YYRMvbNK
https://pastebin.com/yMGLZhE6
https://pastebin.com/S95qV0Uz
https://pastebin.com/KkbjxT3u
https://pastebin.com/KtDaV8W6
https://pastebin.com/StWuCs6Y
https://pastebin.com/P1C46HUd
https://pastebin.com/jQVY68MF
https://pastebin.com/pZWdw2nr
https://pastebin.com/hWvq20CX
https://pastebin.com/6gYgutXU
https://pastebin.com/U4bchZ6m
https://pastebin.com/gfaWG0r6
https://pastebin.com/e9Y0r65R
https://pastebin.com/TVxKvWAq
https://pastebin.com/XQf3dgCp
https://pastebin.com/DpcrwpV5
https://pastebin.com/ebTwvrA8
https://pastebin.com/9AVaZHpP
https://pastebin.com/0XNziuPN
https://pastebin.com/5pX3w9Qz
https://pastebin.com/LxBeC4wT
https://pastebin.com/Ts4YH8YT
https://pastebin.com/gtTcZ7WL
https://pastebin.com/9hCAm4pk
https://pastebin.com/ivQAv3W6
https://pastebin.com/kQkScYnm
https://pastebin.com/Pggf2AJf
https://pastebin.com/93YQXuS2
https://pastebin.com/8bT7ebcm
https://pastebin.com/qhwZL1PA
https://pastebin.com/1j9Dfhf3
https://pastebin.com/yr8G62Eb
https://pastebin.com/i6keBveX
https://pastebin.com/8cShExkL
https://pastebin.com/uRpXa4D8
https://pastebin.com/GCWXMvkV
https://pastebin.com/5r8kkafj
https://pastebin.com/gZqmkKFY
https://pastebin.com/uzX4RXb8
https://pastebin.com/NX85Yeya
https://pastebin.com/0bnHmnn1
https://pastebin.com/4TEuJiyp
https://pastebin.com/19ECBLgF
https://pastebin.com/Q6sXfyLu
https://pastebin.com/J3wkaGhA
https://pastebin.com/MV4f7R1P
https://pastebin.com/4dtFguZU
https://pastebin.com/adNJrURC
https://pastebin.com/aTtEKzis
https://pastebin.com/PQrg1GWd
https://pastebin.com/gKTKwvqf
https://pastebin.com/uuYPPvaA
https://pastebin.com/j4Ls35Kc
https://pastebin.com/E0Ukv7Aj
https://pastebin.com/f6k4t5u2
https://pastebin.com/Q1DXAxWt
https://pastebin.com/tjfUhr1N
https://pastebin.com/uU5iHdYy
https://pastebin.com/cRR3KhUL
https://pastebin.com/nCiKrKtB
https://pastebin.com/dSHVsFy0
https://pastebin.com/2XAKUkn6
https://pastebin.com/Jppiihgb
https://pastebin.com/h3yaiqzz
https://pastebin.com/2JWDAsub
https://pastebin.com/tmPvc6uP
https://pastebin.com/FUnWQQwV
https://pastebin.com/Gp2UtxKN
https://pastebin.com/h95wHCfg
https://pastebin.com/fsCpD2Z8
https://pastebin.com/zJr9HCpS
https://pastebin.com/0PvFpNur
https://pastebin.com/VJyawuD5
https://pastebin.com/ba848eTS
https://pastebin.com/RACk8XWR
https://pastebin.com/0hwQHBAn
https://pastebin.com/sm0bEg5B
https://pastebin.com/KQVK1Ux4
https://pastebin.com/RzSuT9wU
https://pastebin.com/9zX0dafY
https://pastebin.com/vkitG9Jw
https://pastebin.com/BcsGM1ug
https://pastebin.com/mj2Ugnd4
https://pastebin.com/qUZmarS4
https://pastebin.com/db2sFPQt
https://pastebin.com/0Quw6jc1
https://pastebin.com/bPBJjv7K
https://pastebin.com/85VrwdEB
https://pastebin.com/ShwKYbhk
https://pastebin.com/n90Pae7n
https://pastebin.com/SKapsvXq
https://pastebin.com/jchhgXp5
https://pastebin.com/PKj7m3Lc
https://pastebin.com/uGYXHZAJ
https://pastebin.com/1Q4Smy2t
https://pastebin.com/sm9Guq40
https://pastebin.com/mwR9cXpE
https://pastebin.com/yJwCfxSP
https://pastebin.com/CBCVt6RG
https://pastebin.com/g5h9tUZ3
https://pastebin.com/LCgxSJzf
https://pastebin.com/VTQUWA8N
https://pastebin.com/qjDyTgv1
https://pastebin.com/6dFvv5Fp
https://pastebin.com/JaPKffGq
https://pastebin.com/92nW5dg4
https://pastebin.com/gH5hqPqi
https://pastebin.com/s6MKA67r
https://pastebin.com/8wtXs6PD
https://pastebin.com/jMc5xGpz
https://pastebin.com/EzDZD9aa
https://pastebin.com/p0AmhcjH
https://pastebin.com/QS1iAeCm
https://pastebin.com/X7QsHtdw
https://pastebin.com/0b4Y7fQY
https://pastebin.com/Y0sEGX9d
https://pastebin.com/6Vhw047x
https://pastebin.com/m7VxYsWv
https://pastebin.com/rDK9zsnw
https://pastebin.com/Z37U43eV
https://pastebin.com/80dR4QFi
https://pastebin.com/uB10GAXp
https://pastebin.com/8ts4FMmm
https://pastebin.com/y6TXLitK
https://pastebin.com/xPQ81CN6
https://pastebin.com/3hqhfZua
https://pastebin.com/aamUFtH2
https://pastebin.com/Lgh7nvP5
https://pastebin.com/x7Wg8naG
https://pastebin.com/aW7iLfRT
https://pastebin.com/Y7sTZ6Vb
https://pastebin.com/ZGPVkCwr
https://pastebin.com/jbcbQ9SV
https://pastebin.com/dxRWmQfk
https://pastebin.com/s02yGqxb
https://pastebin.com/1hB6AGkw
https://pastebin.com/hbcaCTpF
https://pastebin.com/pa2dcEuK
https://pastebin.com/2DV3gLRS
https://pastebin.com/wXieGb5z
https://pastebin.com/QDuKzm2f
https://pastebin.com/KzNj7grC
https://pastebin.com/89UWyNL0
https://pastebin.com/DGiiVVM6
https://pastebin.com/p1c3MvZT
https://pastebin.com/ecWTPGqn
https://pastebin.com/x6xBU9WV
https://pastebin.com/6yDL7fCa
https://pastebin.com/zjV0dLrr
https://pastebin.com/5d6FK30q
https://pastebin.com/EAxBa9Rm
https://pastebin.com/fwUrdJ4g
https://pastebin.com/VfBQU7Wb
https://pastebin.com/qwmVxX40
https://pastebin.com/71mdDTym
https://pastebin.com/qKrKiQbA
https://pastebin.com/z4WQJNkG
https://pastebin.com/1cdSJ8z5
https://pastebin.com/RtJXd9SW
https://pastebin.com/awkWi3s0
https://pastebin.com/xYkp2v8B
https://pastebin.com/rVehqExV
https://pastebin.com/Ws1Rd9bX
https://pastebin.com/8rXf1587
https://pastebin.com/9rfqNX50
https://pastebin.com/xVW5XQ2C
https://pastebin.com/dtHPSD6d
https://pastebin.com/mZD42AGm
https://pastebin.com/mXgU9d1f
https://pastebin.com/wTcD42mF
https://pastebin.com/KWqcG3if
https://pastebin.com/36p4EnHw
https://pastebin.com/TgjikqB4
https://pastebin.com/JHfBjWDg
https://pastebin.com/YhNpnZ3J
https://pastebin.com/TfC4Wa6F
https://pastebin.com/AFbL5S7E
https://pastebin.com/tVynY480
https://pastebin.com/bCevMY23
https://pastebin.com/7D3RhcvW
https://pastebin.com/sx5zBNRT
https://pastebin.com/6BEu5JtE
https://pastebin.com/LLdT59KZ
https://pastebin.com/qVaqen3E
https://pastebin.com/teqJ5Faw
https://pastebin.com/iYGt5cfB
https://pastebin.com/PvxNyjNd
https://pastebin.com/7LrBhZtK
https://pastebin.com/Uw6gnw98
https://pastebin.com/EiurXwH0
https://pastebin.com/jqRuvh0m
https://pastebin.com/geBdNDtb
https://pastebin.com/zQKdEZza
https://pastebin.com/QYFjE08P
https://pastebin.com/TBLAMRQF
https://pastebin.com/CzT8XHXy
https://pastebin.com/MBYQTUi5
https://pastebin.com/PCfCFgCR

0 关注 分享

要回复文章请先登录注册