uni-app小程序折叠3D轮播图效果实现。
uni-app封装折叠轮播组件
先来看效果图
实现原理:
通过小程序的触摸事件,来控制图片数组的变化实现动态样式;来改变图片的样式。
贴上轮播组件完整代码
<template>
<view :style="{ height: height 'px' }" class="box">
<view class="swiper-container">
<view
class="swiper-item"
v-for="(item, index) in list" :key="index"
@tap="imageTap(item)"
@touchstart="touchStart"
@touchend="touchEnd"
:style="{filter:styleList[index].filter, transform: styleList[index].transform, zIndex: styleList[index].zIndex, opacity: styleList[index].opacity,display:styleList[index].display}">
<view class="wrap">
<image class="image" :src="item" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
/**
* 图片url列表
*/
list: {
type: Array,
default: []
}
},
data() {
return {
/**
* 开始触摸点坐标
*/
start: {
x: 0,
y: 0
},
/**
* 每个item样式列表
*/
styleList: [],
height: 0
};
},
created() {
this.list.forEach((item, index) => {
this.styleList.push(this.addStyle(index))
})
},
mounted () { //防止页面翻页抖动
setTimeout(() => {
const query = uni.createSelectorQuery().in(this);
query.select('.image').boundingClientRect(data => {
this.height = data.height
}).exec();
}, 1500)
},
methods: {
imageTap(item) { // 图片的点击事件
this.$emit('image-tap', item)
},
/**
* 计算每个item样式
* @param {Object} idx
*/
addStyle(idx) {
const len = this.list.length;
if (idx > len / 2) {
//这里是数组后一半的item放在左边,平移位置由远到近,例如共6个,后2个处理在这里
var left = len - idx
return {
transform: 'scale(' (1 - left / 10) ') translate(-' (left * 25) '%,0px)',
zIndex: 9999 - left,
filter: `blur(${left==0?0:5}px)`, //滤镜
display: idx == len - 1 ? "block" : "none"
}
} else {
//这里是数组前一半item放在右边,平移位置由近到远,例如共6个,前4个处理在这里,这里第一个元素始终放在中间位置
return {
transform: 'scale(' (1 - idx / 10) ') translate(' (idx * 25) '%,0px)',
zIndex: 9999 - idx,
filter: `blur(${idx==0?0:5}px)`, //滤镜
display: idx > 1 ? "none" : "block"
}
}
},
/**
* 触摸开始
* @param {Object} e
*/
touchStart(e) {
this.start.x = e.changedTouches[0] ? e.changedTouches[0].pageX : 0;
this.start.y = e.changedTouches[0] ? e.changedTouches[0].pageY : 0;
},
/**
* 触摸结束
* @param {Object} e
*/
touchEnd(e) {
var newStyleList = JSON.parse(JSON.stringify(this.styleList))
let tx = e.changedTouches[0].pageX - this.start.x
let ty = e.changedTouches[0].pageY - this.start.y
if (Math.abs(tx) > Math.abs(ty)) {
//左右方向滑动
if (tx < 0) {
// 向左滑动
var last = [newStyleList.pop()]
newStyleList = last.concat(newStyleList)
} else if (tx > 0) {
// 向右滑动
newStyleList.push(newStyleList[0])
newStyleList.splice(0, 1)
}
} else {
//这里就不处理上下方向的事件了,有此需求的同仁可以在这里写逻辑
//上下方向滑动
if (ty < 0) {
// 向上滑动
} else if (ty > 0) {
// 向下滑动
}
}
this.styleList = newStyleList
},
/**
* 当前item点击返回索引下标
* @param {Object} idx
*/
}
}
</script>
<style scoped lang="scss">
.box{
.swiper-container {
box-sizing: border-box;
width: 100%;
position: relative;
.swiper-item {
width: 100%;
position: absolute;
top: 0;
left: 0;
transition: all .5s;
.wrap {
padding: 2upx 44upx;
.image {
width: 100%;
border-radius: 20upx;
}
}
}
}
}
</style>
组件使用
<template>
<view class="tabbar-page">
<view class="head">
<image @tap="showBannerLink" :src="banner.imageUrl" style="width: 100%" mode="widthFix"></image>
</view>
<view v-if="imageList.length" class="h1">精彩呈现</view>
<kevy-swiper v-if="imageList.length" :list="imageUrlList" @image-tap="imageTap"></kevy-swiper>
</view>
</template>
<script>
import KevySwiper from '../../components/kevy-swiper/kevy-swiper.vue'
import store from '@/store/index'
import crmApiService from '@/api/crmApi'
export default {
components: {KevySwiper},
data () {
return {
imageList: [],
banner: {}
}
},
watch: {},
computed: {
ossUrl () {
return this.$config.ossUrl
},
imageUrlList () {
return this.imageList?this.imageList.map(item => item.imageUrl) : []
},
activityUrl () {
return this.ossUrl 'test_activity.png'
}
},
methods: {
showBannerLink() {
// uni.navigateTo({ url: '/pages/webview/webview?url=' this.banner.linkUrl })
},
imageTap (url) {
this.imageList.some(item => {
if (item.imageUrl == url) {
uni.navigateTo({ url: '/pages/webview/webview?url=' item.linkUrl })
return true
}
})
}
},
onShow () {
this.setTabBarIndex(2)
crmApiService.getBanners().then(res => {
if (res.success) {
this.banner = res.result
} else {
this.$tip.toast(res.message)
}
})
crmApiService.getCarousels().then(res => {
if (res.success) {
this.imageList = res.result
} else {
this.$tip.toast(res.message)
}
})
}
}
</script>
<style scoped lang="scss">
.h1 {
font-size: 48upx;
color: #111111;
text-align: center;
font-weight: 500;
padding: 44upx 0;
}
.tabbar-page {
padding-bottom: calc(env(safe-area-inset-bottom) 68px);
overflow-x: hidden;
}
.activity-wrap {
padding: 0 44upx;
}
</style>
如果有自动轮播的需求,可以改造下组件加个定时器处理数组就OK了。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgffhha
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13