wxs微信小程序轮播图——高度自适应并动态过渡变化
程序员文章站
2022-06-25 11:57:30
之前实现了基于原生js的高度自适应且动态平滑过渡的轮播图:由于项目需要 将这一交互动效同步进了微信小程序...
之前实现了基于原生js的高度自适应且动态平滑过渡的轮播图:
原生js实现一个高度自适应且动态平滑变高的轮播图
由于项目需要 将这一交互动效在微信小程序里做了实现 结合了微信小程序wxs的脚本语言 下面是效果图:
使用脚本语言wxs的原因
实现动态的高度渲染需要监听微信小程序swiper组件bindtransition属性的参数dx(即轮播块在x轴方向上的位移值)并动态地反映到y轴方向上的高度上。 这在基本的js逻辑文件中做实现时 需要频繁调用setData方法把计算得到的高度值渲染为轮播区域的高度 而
这样的方式会带来严重的性能问题 所以需要使用在视图层表现优秀的wxs脚本来实现
关于wxs脚本语言的介绍 详见 微信官网文档——wxs
这里只结合项目和交互实现叙述用到的wxs相关处理方式
代码实现
下面是动效实现的代码 注释部分有实现思路的叙述和对wxs的一些基本使用方式
.wxml:(项目需求提出在轮播区域加入视频的展示 所以出现了video类型的轮播块)
<!-- wxs脚本的引入 相对路径 -->
<wxs src="./swiperHT.wxs" module="swiperHT"/>
<!-- 变高轮播 视频加入 -->
<view style="position:relative;">
<!-- ******绑定了三个属性 bindchange监听轮播块的变化以记录当前轮播快序号 并把"轮播块发生改变"这一状态记录为变量indexChange的值为true
bindanimationfinish监听轮播动画结束 还原indexChange的值为false以便区分是否触发了轮播块的改变--改变时需要过渡渲染到新高度 否则过渡回旧高度
bindtransition即对 "接触轮播区域后手势划动" 的整个过程的监听是一个复杂的过程 放进wxs中
-->
<!-- swiper组件的bindtransition方法可以调用声明过的wxs模块swiperHT中的方法bt 通过data-的形式向方法中传值
ic:是否发生轮播块的改变 cw:屏幕宽度 list:数据数组 index:当前轮播块序号-->
<swiper id="swiperOut" style="height:{{nowH}}px" duration="{{duration}}"
data-ic="{{indexChange}}" data-cw="{{clientW}}" data-list="{{imgSwiperList}}" data-index="{{durationIndex}}"
bindtransition="{{swiperHT.bt}}" bindchange="change" bindanimationfinish="changeEnd">
<!-- 需要的数据格式为(url 宽 高三项必填):[{url:"",height:100;width:100;type:pic},{...},{...},...] -->
<swiper-item wx:for="{{imgSwiperList}}" wx:key="index" >
<!-- 视频轮播块 -->
<view class="swiperInVP" wx:if="{{item.type==='video'}}">
<video
wx:if="{{item.type==='video'&&durationIndex===index}}"
style="width:100%;height:100%;"
src="{{item.url}}"
controls
autoplay="{{true}}"
></video>
</view>
<!-- 图片轮播块 -->
<view class="swiperInVP" wx:if="{{item.type==='pic'}}"
style="background-image: url({{item.url+'?imageslim'}});"></view>
</swiper-item>
</swiper>
<!-- 右下角数字提示 -->
<view class="swiperNum">{{durationIndex+1}}/{{imgSwiperList.length}}</view>
</view>
.wxss:
/* 顶部轮播 */
.swiperInVP{
width:100%;height:100%;background-size:cover;background-position:center;
}
.swiperNum{
position:absolute;
right:16px;
bottom:36px;
background:rgba(0,0,0,0.3);
border-radius:12px;
color:white;
padding:5px 8px;
font-size:11px;
line-height:11px;
}
.js:
imgSwiperList: [],//顶部轮播图片列表(url 宽 高三项必填): [{url:"",height:100;width:100;type:pic},{...},{...},...]
duration: 180,//轮播区域过渡动画时长
durationIndex: 0,//轮播区域轮播块index
nowH:0,//初始轮播区域高度(第一个轮播块在当前屏宽下的高度)
indexChange: false,//是否发生了轮播块的变动
clientW:0,//当前页面宽度
//swiper组件发生轮播块变动时触发的事件
change: function (e) {
console.log("index变动结束", e.detail.current);//触发于轮播块发生变动的时候
this.setData({
durationIndex: e.detail.current,//记录新的轮播块序号
indexChange: true//发生了轮播块改变 需要过渡渲染新的高度
})
},
//划动结束事件
changeEnd: function (e) {
console.log("一块轮播动画结束", e.detail.current);
//触发于滑动动画结束的时候 有可能停留在当前块
this.setData({
indexChange: false//未发生轮播块改变 过渡回旧的高度
})
},
.wxs:
var swiperOut;
var swiperInVP;
var dataset;
var index;
var list;
var cw;
var ic;
//滑动过程中
var bt=function(e,ins){
//******直接打印参数输出的是两个对象 需要转换成字符串后打印查看
// 观察可知第一个参数中能够取到wxs模块引用处的传值 第二个参数中暴露有方法可以进行dom的截取和操作
// console.log(JSON.stringify(e),"e")
// console.log(JSON.stringify(ins),"ins")
swiperOut=ins.selectComponent("#swiperOut")
swiperInVP=ins.selectComponent(".swiperInVP")
dataset = e.instance.getDataset();
index = dataset.index;
list = dataset.list;
cw = dataset.cw;
ic = dataset.ic;
if(e.detail.dx>0){
// console.log("左划")
if (index < list.length) {
if (ic === false) {//未发生轮播块改变 过渡回旧的高度
var nowH = (list[index].height) / (list[index].width) * cw; //当前轮播块高度
if (index === list.length-1){
var nextH = (list[index].height) / (list[index].width) * cw; //下一个轮播块高度
}else{
var nextH = (list[index + 1].height) / (list[index + 1].width) * cw; //下一个轮播块高度
}
var cs = (nextH - nowH) / cw * e.detail.dx
// console.log("落定前", "当前轮播快高度", nowH, "下个轮播块高度", nextH, "cs变动值", cs, "临界基准", ic)
// console.log(nowH + cs)
swiperOut.setStyle({//******通过样式设置的方式动态渲染高度 呈现高度变化的过渡过程 避免对setData()的频繁调用
"height": nowH + cs + 'px'
})
swiperInVP.setStyle({
"height": nowH + cs + 'px'
})
} else if (ic === true) {//发生了轮播块改变 需要过渡渲染新的高度
var nowH = (list[index - 1].height) / (list[index - 1].width) * cw; //当前轮播块高度
var nextH = (list[index].height) / (list[index].width) * cw; //下一个轮播块高度
var cs = (nextH - nowH) / cw * e.detail.dx
// console.log("落定后", "当前轮播快高度", nowH, "下个轮播块高度", nextH, "cs变动值", cs, "临界基准", ic)
// console.log(nowH + cs)
swiperOut.setStyle({
"height": nowH + cs + 'px'
})
swiperInVP.setStyle({
"height": nowH + cs + 'px'
})
}
}
}else if(e.detail.dx<0){
// console.log("右划")
if (index >= 0) {
if (ic === false) {//未发生轮播块改变 过渡回旧的高度
var nowH = (list[index].height) / (list[index].width) * cw; //当前轮播块高度
if (index === 0){
var nextH = (list[index].height) / (list[index].width) * cw; //下一个轮播块高度
}else{
var nextH = (list[index - 1].height) / (list[index - 1].width) * cw; //下一个轮播块高度
}
var cs = (nextH - nowH) / cw * e.detail.dx
// console.log("右划落定前", "当前轮播快高度", nowH, "下个轮播块高度", nextH, "cs变动值", cs, "临界基准", ic)
// console.log(nowH - cs)
swiperOut.setStyle({//******通过样式设置的方式动态渲染高度 呈现高度变化的过渡过程 避免对setData()的频繁调用
"height": nowH - cs + 'px'
})
swiperInVP.setStyle({
"height": nowH - cs + 'px'
})
} else if (ic === true) {//发生了轮播块改变 需要过渡渲染新的高度
var nowH = (list[index + 1].height) / (list[index + 1].width) * cw; //当前轮播块高度
var nextH = (list[index].height) / (list[index].width) * cw; //下一个轮播块高度
var cs = (nextH - nowH) / cw * e.detail.dx
// console.log("右话落定后", "当前轮播快高度", nowH, "下个轮播块高度", nextH, "cs变动值", cs, "临界基准", ic)
// console.log(nowH - cs)
swiperOut.setStyle({
"height": nowH - cs + 'px'
})
swiperInVP.setStyle({
"height": nowH - cs + 'px'
})
}
}
}
}
module.exports = {
bt:bt
};
本文地址:https://blog.csdn.net/mrl268/article/details/107870192
下一篇: html概述(续2)