赞
踩
初始需要给item们放置好位置以及各种层级,然后在切换滑动的过程中对设置的位置、层级、透明度进行替换,加上小程序的wx.createAnimation()动画效果。
<view class="swiper-page" bindtouchmove="touchmove" bindtouchstart="touchstart" bindtouchend="touchend">
<view wx:for="{{imgArray}}" wx:key="index" class="swiper-container">
<view class="item-container" style="z-index:{{indexArray[index]}}">
<view class="item{{index}} item-common" animation="{{animation[index]}}" data-text="{{textArray[index]}}">
<image class="background" src="{{item.image}}" mode='aspectFit'></image>
<text class="item-text">{{item.text}}</text>
</view>
</view>
</view>
<view bindtap="tapLeft" style="position:absolute;top:0;left:20rpx">往左滑</view>
<view bindtap="tapRight" style="position:absolute;top:0;right:20rpx">往右滑</view>
</view>
<view class="swiper-page" bindtouchmove="touchmove" bindtouchstart="touchstart" bindtouchend="touchend">
<view wx:for="{{imgArray}}" wx:key="index" class="swiper-container">
<view class="item-container" style="z-index:{{indexArray[index]}}">
<view class="item{{index}} item-common" animation="{{animation[index]}}" data-text="{{textArray[index]}}">
<image class="background" src="{{item.image}}" mode='aspectFit'></image>
<text class="item-text">{{item.text}}</text>
</view>
</view>
</view>
<view bindtap="tapLeft" style="position:absolute;top:0;left:20rpx">往左滑</view>
<view bindtap="tapRight" style="position:absolute;top:0;right:20rpx">往右滑</view>
</view>
// 位置列表 let posArray = [ 280,120,420] // 缩放列表 let scaArray = [1, .8, .8 ] // 透明度列表 let opaArray = [1,.8, .8] // 高度列表 let indArray = [ 1, 0.8, 0.8] // 当前位置列表 let curPosArray = [ 280,120,420] // 当前缩放列表 let curScaArray = [] // 当前透明度列表 let curOpaArray = [] // 当前高度列表 let curIndArray = [] let left = 0 // 是否可点击,控制点击频率 let canClick = true // px和rpx转换比例,用于横向滑动的时候计算滑动距离(rpx) let screenRate = 1 Page({ data: { imgArray: [{ image:'imgs/image1.png', text:'页面1' },{ image:'imgs/image2.png', text:'页面2' },{ image:'imgs/image3.png', text:'页面3' }], animation: [], indexArray: [2,1,1] }, /** * 生命周期函数--监听页面加载 */ onLoad: function(options) { wx.getSystemInfo({ success: (res) => { screenRate = 750 / res.screenWidth } }) this.animation = [] for (let i = 0; i < 3; i++) { let animation = wx.createAnimation({ duration: 500, timingFunction: 'ease-out', }) this.animation.push(animation) } }, touchstart(e) { left = e.touches[0].pageX }, touchmove(e) { if (this.isMove) { return } let moveLength = (e.touches[0].pageX - left) * screenRate moveLength = moveLength > 60 ? 60 : moveLength moveLength = moveLength < -60 ? -60 : moveLength let rate = moveLength / 60 if (rate == 1) { //从右往左滑 this.isMove = true this.tapLeft() } else if (rate == -1) { //从左往右滑 this.isMove = true this.tapRight() } }, touchend(e) { setTimeout(()=>{ this.isMove = false },500) }, // 往左移 tapLeft() { if (!canClick) { return } canClick = false setTimeout(() => { canClick = true }, 500) curPosArray = this.rollRight(posArray, 1) curScaArray = this.rollRight(scaArray, 1) curOpaArray = this.rollRight(opaArray, 1) curIndArray = this.rollRight(indArray, 1) let animation = this.data.animation for (let j = 0; j < 3; j++) { this.animation[j].scale(curScaArray[j], curScaArray[j]).left(curPosArray[j] + 'rpx').opacity(curOpaArray[j]).step() animation[j] = this.animation[j].export() } this.setData({ animation: animation, indexArray: curIndArray }) }, tapRight() { if (!canClick) { return } canClick = false setTimeout(() => { canClick = true }, 500) curPosArray = this.rollLeft(posArray, 1) curScaArray = this.rollLeft(scaArray, 1) curOpaArray = this.rollLeft(opaArray, 1) curIndArray = this.rollLeft(indArray, 1) let animation = this.data.animation for (let j = 0; j < 3; j++) { this.animation[j].scale(curScaArray[j], curScaArray[j]).left(curPosArray[j] + 'rpx').opacity(curOpaArray[j]).step() animation[j] = this.animation[j].export() } this.setData({ animation: animation, indexArray: curIndArray }) }, rollLeft: function(array, times) { for (let time = 0; time < times; time++) { let length = array.length - 1 let temp = array[0] for (let i = 0; i < length; i++) { array[i] = array[i + 1] } array[length] = temp } return array.concat() }, rollRight: function(array, times) { for (let time = 0; time < times; time++) { let length = array.length - 1 let temp = array[length] for (let i = length; i > 0; i--) { array[i] = array[i - 1] } array[0] = temp } return array.concat() }, })
<view class="swiper-body" bindtouchmove="tauchMove" bindtouchstart="tauchStart" bindtouchend="tauchEnd">
<view class=".swiper-item-box {{item.zIndex==1?'none':''}}" wx:for="{{swiperList}}" wx:key="index" style="--index:{{item.zIndex}};--left:{{item.mLeft}}">
<view class="swiper-item">
<image src="{{item.url}}" mode="aspectFill" wx:if="{{item.type=='image'}}"></image>
<view class="photo-item-layout">
<view class="photo-item-title">标题</view>
<view class="photo-item-label">标签 </view>
</view>
</view>
</view>
</view>
page { background-color: #fff; } .swiper-body { height: 420rpx; position: relative; max-width: 750rpx; overflow: hidden; box-sizing: border-box; margin-top: 90rpx; } .swiper-item-box { position: absolute; width: 300rpx; height: 380rpx; top: 0; bottom: 0; left: 50%; margin: auto; transition: all 0.2s ease-in 0s; opacity: 1; box-shadow: 0px 13rpx 12rpx rgba(0, 0, 0, .5); border-radius: 15rpx; overflow: hidden; transform: scale(calc(0.5 + var(--index) / 10)); margin-left: calc(var(--left) * 100rpx - 150rpx); z-index: var(--index); } .swiper-item-box.none { opacity: 0; } .swiper-item { overflow: hidden; position: relative; width: 100%; height: 100%; border-radius: 6rpx; } .swiper-item image{ width: 100%; display: block; height: 100%; margin: 0; pointer-events: none; } image { max-width: 100%; display: inline-block; position: relative; z-index: 0; } .photo-item-layout { position: absolute; width: 100%; left: 0; bottom: 0; color: #fff; border-bottom-right-radius: 18rpx; float: left; display: flex; flex-direction: column; background: linear-gradient(180deg, #0092fb00,#3691FB ); } .photo-item-title { color: white; font-size: 32rpx; font-weight: 800; margin-top: 20rpx; text-align: center; overflow: hidden; text-overflow: -o-ellipsis-lastline; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; } .photo-item-label { color: rgba(255, 255, 255, 0.829); font-size: 28rpx; text-align: center; padding: 3rpx 20rpx 10rpx 20rpx; border-top-right-radius: 20rpx; border-bottom-right-radius: 20rpx; overflow: hidden; text-overflow: -o-ellipsis-lastline; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; }
Page({ data: { swiperList: [ { type: 'image', url: '/img_fj.png' }, { type: 'image', url: '/img_banner_random.png', }, { type: 'image', url: '/img_activity.png' }, { type: 'image', url: '/img_activity.png' }, { type: 'image', url: '/img_stage.png' }, { type: 'image', url: '/img_activity.png' }, ], }, onLoad: function (options) { this.tauchSwiper('swiperList'); }, onShow: function () { }, // 初始化tauchSwiper tauchSwiper(name) { let list = this.data[name]; for (let i = 0; i < list.length; i++) { // Math.abs(x) 函数返回指定数字 “x“ 的绝对值 list[i].zIndex = parseInt(list.length / 2) + 1 - Math.abs(i - parseInt(list.length / 2)) list[i].mLeft = i - parseInt(list.length / 2) } this.setData({ swiperList: list }) }, // tauchSwiper触摸开始 tauchStart(e) { this.setData({ tauchStart: e.touches[0].pageX }) }, // tauchSwiper计算方向 tauchMove(e) { this.setData({ direction: e.touches[0].pageX - this.data.tauchStart > 0 ? 'right' : 'left' }) }, // tauchSwiper计算滚动 tauchEnd(e) { let direction = this.data.direction; let list = this.data.swiperList; if (direction == 'right') { let mLeft = list[0].mLeft; let zIndex = list[0].zIndex; for (let i = 1; i < list.length; i++) { list[i - 1].mLeft = list[i].mLeft list[i - 1].zIndex = list[i].zIndex } list[list.length - 1].mLeft = mLeft; list[list.length - 1].zIndex = zIndex; this.setData({ swiperList: list }) } else { let mLeft = list[list.length - 1].mLeft; let zIndex = list[list.length - 1].zIndex; for (let i = list.length - 1; i > 0; i--) { list[i].mLeft = list[i - 1].mLeft list[i].zIndex = list[i - 1].zIndex } list[0].mLeft = mLeft; list[0].zIndex = zIndex; this.setData({ swiperList: list }) } } })
<view class="pageLayout">
<swiper indicator-dots='true' autoplay='true' interval='5000' duration='1000' circular='true'>
<block wx:for="{{bnrUrl}}" wx:for-index="index">
<swiper-item id='{{index}}' bindtap='bannerClick' data-bannertitle='{{item.title}}' data-bannerid='{{item.id}}'>
<image class='bannerLayout' src='{{item.url}}' mode='scaleToFill'></image>
</swiper-item>
</block>
</swiper>
</view>
/* 页面样式 */ .pageLayout { background-size: 100%; padding: 0 30rpx 50rpx; } /* 轮播图 */ .bannerLayout { width: 100%; height: 310rpx; box-sizing: border-box; overflow: hidden; border-radius: 20rpx; margin-top: 30rpx; margin-bottom: 24rpx; box-shadow: 0 0 10rpx #7d7d7d; background: #fff; }
// pages/banner2/banner2.js const utils = require('../../utils/util.js'); Page({ /** * 页面的初始数据 */ data: { "bnrUrl": [{ "url": `weChatFile/icon_menu_yxt.png`, "title": `标题一` }, { "url": `weChatFile/icon_menu_yxt.png`, "title": `标题二 ` }] }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { let that = this that.getslideImg() }, bannerClick: function (e) { var bannerId = e.currentTarget.dataset.bannerid; wx.navigateTo({ //方法一 url: '../bannerDetail/bannerDetail?bannerId='+bannerId, //方法二 //url: `../bannerDetail/bannerDetail?bannerId=${bannerId}`, }) }, getslideImg: function () { let that = this // utils.getPostData('a/msmallapp/appWheel/list', function (res) { // let resData = res.data // console.log("===3==" + resData); // console.log(resData); // if (resData) { // if (resData.success) { // let resList = resData.body.list // that.setData({ // bnrUrl: resList // }) // } // } // }) }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })
<!--index.wxml--> <view class="container"> <!-- 轮播图 --> <view class="banner-swiper"> <swiper indicator-dots="{{indicator}}" autoplay="{{autoplay}}" current='{{swiperCurrent}}' indicator-color="{{beforeColor}}" indicator-active-color="{{afterColor}}" circular='{{circular}}' previous-margin="{{previousmargin}}" next-margin="{{nextmargin}}" bindchange="swiperChange"> <block wx:for="{{arr}}" wx:key="key"> <swiper-item> <image src="{{item.images}}" class="slide-image {{index == swiperCurrent ? ' active' : ''}}"></image> <view class='goods-info'>{{item.title}}</view> <view class='goods-more'> <view> <text class='prefix'>免费样品</text> <text class='nums'>({{item.num}}个)</text> </view> <view> <text class='prefix supply'>供应价:</text> <text class='price'>¥{{item.price}}</text> </view> </view> </swiper-item> </block> </swiper> <view class="dots"> <block wx:for="{{arr}}" wx:key="{{index}}"> <view class="{{index== cur?'active':''}} dot"></view> </block> </view> </view> </view>
/**index.wxss**/ /* 轮播图 */ .banner-swiper{ width: 100%; height: 540rpx; overflow: hidden; position: relative; background-color: #fff; } swiper { display: block; height: 540rpx; font-size: 0; } .slide-image{ width: 96%; display: block; margin: 0 auto; height: 410rpx; border-radius: 10rpx; font-weight: bold; } .goods-info{ font-size: 28rpx; color: #000; text-align: center; margin-top: 20rpx; margin-bottom: 20rpx; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .goods-more { display: flex; flex-direction: row; justify-content: center; } .supply { margin-left: 40rpx; } .prefix { font-size: 24rpx; color: #000; } .nums { font-size: 24rpx; color: #666; } .price { font-size: 24rpx; color: #fc515c; } .dots{ position: absolute; right: 0; bottom: 140rpx; left: 0; width: 300rpx; height: 18rpx; margin: 0 auto; text-align: center; display: flex; flex-direction: row; justify-content: center; } /*未选中时的小圆点样式 */ .dot{ width: 10rpx; height: 10rpx; margin-right: 8rpx; border-radius: 100rpx; background-color: #f2f2f2; } /*选中以后的小圆点样式 */ .active{ width: 36rpx; height: 10rpx; border-radius: 5rpx; background-color: #f2f2f2; }
//index.js //获取应用实例 const app = getApp() Page({ /** * 页面的初始数据 */ data: { arr: [{ images: '/weChatFile/img_fj.png', title: 'Lumea Prestige系列脱毛装置', num: '2', price: '99.00' }, { images: '/weChatFile/img_banner_random.png', title: 'Lumea Prestige系列脱毛装置', num: '2', price: '99.00' }, { images: '/weChatFile/img_activity.png', title: 'Lumea Prestige系列脱毛装置', num: '2', price: '99.00' }], beforeColor: "white",//指示点颜色 afterColor: "coral",//当前选中的指示点颜色 previousmargin: '24px',//前边距 nextmargin: '24px',//后边距 indicator: false, //是否显示指示点 interval: 5000, //自动切换时间间隔 duration: 400, //滑动动画时长 autoplay: true, //是否自动切换 circular: true, //是否采用衔接滑动 cur: 0, //当前所在滑块的index }, //轮播图的切换事件 swiperChange(e) { let cur = e.detail.current //获取当前轮播图片的下标, 可以给当前指示点加样式 this.setData({ cur: cur }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。