Skip to content
# t-swiper-stretcheffect

SwiperStretchEffect 横向拉伸轮播组件 — 基于 Canvas 实现的拉伸效果轮播,当前项横向压缩滑出,下一项横向展开。

t-swiper-stretcheffect 组件介绍 ​

t-swiper-stretcheffect 是一个使用 Canvas 渲染的轮播组件,提供独特的横向拉伸切换动画效果。当前项在滑动时横向压缩并移出,下一项从另一侧横向拉伸展开。支持自动播放、循环轮播、指示点和点击事件。

t-swiper-stretcheffect 基础用法 ​

vue
<template>
	<view class="p-15">
		<t-card class="mb-15"
				title="StretchXEffect 横向拉伸轮播"
				sub-title="当前项向外滑出并横向压缩,下一项从另一侧横向展开。该示例使用 t-swiper-stretcheffect 独立组件演示。"></t-card>

		<t-swiper-stretcheffect ref="stretchRef"
								class="mb-20"
								height="220px"
								:list="bannerList"
								:autoplay="autoplay"
								:interval="3200"
								:duration="650"
								:circular="true"
								@change="onChange"
								@click="onClick"></t-swiper-stretcheffect>

		<view class="panel mb-15">
			<text class="panel-title">当前状态</text>
			<text class="panel-value">当前索引:{{ current + 1 }} / {{ bannerList.length }}</text>
			<text class="panel-value">当前标题:{{ currentTitle }}</text>
			<text class="panel-tip">点击轮播项会触发 click,左右滑动可手势切换。</text>
		</view>

		<view class="action-row mb-15">
			<t-button type="primary"
					  class="action-btn"
					  @click="prev">上一张</t-button>
			<t-button type="primary"
					  class="action-btn"
					  @click="next">下一张</t-button>
		</view>

		<view class="action-row mb-15">
			<t-button class="action-btn"
					  @click="switchTo(0)">切到 1</t-button>
			<t-button class="action-btn"
					  @click="switchTo(1)">切到 2</t-button>
			<t-button class="action-btn"
					  @click="switchTo(2)">切到 3</t-button>
		</view>

		<view class="action-row">
			<t-button class="action-btn"
					  @click="toggleAutoplay">{{ autoplay ? '暂停自动播放' : '恢复自动播放' }}</t-button>
			<t-button class="action-btn"
					  @click="resetToFirst">重置到首张</t-button>
		</view>
	</view>
</template>

<script setup
		lang="uts">
	const stretchRef = ref<ComponentPublicInstance | null>(null)
	const autoplay = ref<boolean>(true)
	const current = ref<number>(0)
	const bannerList = ref<UTSJSONObject[]>([
		{
			image: '/static/image/D1.jpg',
			title: '品牌视觉 Banner'
		},
		{
			image: '/static/image/D2.jpg',
			title: '商品专题封面'
		},
		{
			image: '/static/image/D3.jpg',
			title: 'Tui 主题展示'
		}
	])

	const currentTitle = computed(() : string => {
		const item = bannerList.value[current.value]
		if (item == null) {
			return ''
		}
		return item.getString('title') ?? ''
	})

	function getStretchInstance() : ComponentPublicInstance | null {
		return stretchRef.value
	}

	function prev() {
		getStretchInstance()?.$callMethod('prev')
	}

	function next() {
		getStretchInstance()?.$callMethod('next')
	}

	function switchTo(index : number) {
		getStretchInstance()?.$callMethod('switchToIndex', index)
	}

	function toggleAutoplay() {
		autoplay.value = !autoplay.value
		if (autoplay.value) {
			getStretchInstance()?.$callMethod('resume')
			return
		}
		getStretchInstance()?.$callMethod('pause')
	}

	function resetToFirst() {
		getStretchInstance()?.$callMethod('stop')
		current.value = 0
		if (autoplay.value) {
			getStretchInstance()?.$callMethod('start')
		}
	}

	function onChange(index : number) {
		current.value = index
	}

	function onClick(e : UTSJSONObject) {
		const item = e.getAny('item') as UTSJSONObject | null
		const title = item == null ? '' : item.getString('title') ?? ''
		uni.showToast({
			title: title == '' ? '点击了轮播项' : title,
			icon: 'none'
		})
	}
</script>

<style>
	.panel {
		display: flex;
		flex-direction: column;
		padding: 16px;
		border-radius: 16px;
		background-color: #ffffff;
	}

	.panel-title {
		font-size: 15px;
		font-weight: 700;
		color: #111827;
	}

	.panel-value {
		margin-top: 8px;
		font-size: 13px;
		color: #334155;
	}

	.panel-tip {
		margin-top: 10px;
		font-size: 12px;
		line-height: 18px;
		color: #64748b;
	}

	.action-row {
		display: flex;
		flex-direction: row;
	}

	.action-btn {
		flex: 1;
		margin-right: 10px;
	}
</style>

t-swiper-stretcheffect API ​

Props ​

属性名说明类型默认值
list轮播数据,支持 image/color/title/text/dataArray—
height组件高度String / Number'200px'
autoplay是否自动播放Booleantrue
current当前索引Number0
duration动画时长(ms)Number600
interval自动播放间隔(ms)Number3500
circular是否循环Booleantrue
imageFit图片填充模式,fill / coverString'cover'
swipeThreshold滑动阈值(px),超过才触发切换Number60
indicatorDots是否显示指示点Booleantrue
dotColor指示点默认颜色String—
dotActiveColor指示点激活颜色String—
dotSize指示点大小Number—
dotBottom指示点底部距离Number—
radius圆角半径(px)Number16

Events ​

事件名说明回调参数
change切换时触发number(当前索引)
click点击当前项时触发{ item, index }

Slots ​

无内置插槽,所有内容通过 list 属性配置。

注意事项 ​

  • 基于 Canvas 渲染,不支持内置插槽,内容通过 list 数据驱动
  • list 中每项支持 image、color、title、text、data 字段
  • imageFit 为 cover 时图片裁剪填充,fill 时拉伸填充
  • 通过 swipeThreshold 控制滑动的灵敏度
  • 指示点相关属性(dotColor / dotActiveColor / dotSize / dotBottom)不传时使用组件默认值