# 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/data | Array | — |
| height | 组件高度 | String / Number | '200px' |
| autoplay | 是否自动播放 | Boolean | true |
| current | 当前索引 | Number | 0 |
| duration | 动画时长(ms) | Number | 600 |
| interval | 自动播放间隔(ms) | Number | 3500 |
| circular | 是否循环 | Boolean | true |
| imageFit | 图片填充模式,fill / cover | String | 'cover' |
| swipeThreshold | 滑动阈值(px),超过才触发切换 | Number | 60 |
| indicatorDots | 是否显示指示点 | Boolean | true |
| dotColor | 指示点默认颜色 | String | — |
| dotActiveColor | 指示点激活颜色 | String | — |
| dotSize | 指示点大小 | Number | — |
| dotBottom | 指示点底部距离 | Number | — |
| radius | 圆角半径(px) | Number | 16 |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| change | 切换时触发 | number(当前索引) |
| click | 点击当前项时触发 | { item, index } |
Slots
无内置插槽,所有内容通过 list 属性配置。
注意事项
- 基于 Canvas 渲染,不支持内置插槽,内容通过
list数据驱动 list中每项支持image、color、title、text、data字段imageFit为cover时图片裁剪填充,fill时拉伸填充- 通过
swipeThreshold控制滑动的灵敏度 - 指示点相关属性(dotColor / dotActiveColor / dotSize / dotBottom)不传时使用组件默认值