微信小程序 3D轮播
程序员文章站
2024-02-11 17:14:46
...
非常简单的微信小程序3D轮播
(弄着玩,代码比较随意,两个页面的都揉一起了)
1.看看效果吧
2.页面wxml布局
<navigator class='btn' url="../3d/3d">前往 3d 页面</navigator>
<view class='carousel'>
<view class='figure' style="transform: rotateY({{rotateY}}deg)" bindtouchstart='touchStart' bindtouchmove='touchMove' bindtouchend="touchEnd">
<image wx:for="{{imgLists}}" wx:key="{{item}}" src="{{item.url}}" style="transform: rotateY({{item.rotateY}}deg) translateZ({{item.translateZ}}rpx) scaleX({{item.scaleX}}) scaleY({{item.scaleY}})" mode='aspectFill'></image>
</view>
</view>
<view class='scrollBar'>
<view class='scroll' style="left:{{left}}%;width:{{width}}%" bindtouchstart='touchStart' bindtouchmove='touchMove' bindtouchend="touchEnd"></view>
</view>
3.页面wxss样式
page{
background: #000;
}
.btn{
margin: 20rpx auto;
width: 500rpx;
text-align:center;
line-height: 60rpx;
background: #fff;
border-radius: 8rpx;
}
.carousel {
margin: 60px auto 50rpx;
padding: 60px;
box-sizing: border-box;
perspective: 500px;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
}
.carousel .figure {
margin: 0;
width: 40%;
height: 300rpx;
transform-style: preserve-3d;
transition: transform 0.5s;
}
.carousel .figure image {
width: 100%;
height: 100%;
padding: 0 0px;
box-sizing: border-box;
}
.carousel .figure image:not(:first-of-type) {
position: absolute;
left: 0;
top: 0;
}
.scrollBar{
position: relative;
margin: 20rpx auto;
width:80%;
height:20rpx;
background:#ffeeaf;
border-radius:10rpx;
}
.scrollBar .scroll{
position: absolute;
left:0;
height:20rpx;
background:#f9c200;
border-radius:10rpx;
transition: all 0.5s;
}
4.页面js代码
Page({
/**
* 页面的初始数据
*/
data: {
imgLists: [
{
url: '../../image/classify/abstract.jpg'
}, {
url: '../../image/classify/animal.jpg'
}, {
url: '../../image/classify/caricature.jpg'
}, {
url: '../../image/classify/manual.jpg'
}, {
url: '../../image/classify/cartoon.jpg'
}, {
url: '../../image/classify/other.jpg'
}, {
url: '../../image/classify/scenery.jpg'
}, {
url: '../../image/classify/character.jpg'
}],//图片列表
translateZ: 320,//偏移量
rotateY: 0,//视图旋转角度
endRotate: '',//视图最后旋转角度
currentImg: 0,//当前正对图片
deg: 0,//每个图片旋转角度
startX: '',//滑动X起点
startY: '',//滑动Y起点
endX: '',//滑动X终点
endY: '', //滑动Y终点
scaleX: 0.8,//初始视图X缩小
endScaleX: 1.2,//视图X放大
scaleY: 0.6,//初始视图Y缩小
endScaleY: 1.6,//视图Y放大
left: 0,//滑块左边距离
endLeft: '',//滑块最后位置
width: '',//滑块宽度
},
//触发图片动画
rotateCarousel() {
let len = this.data.imgLists.length;
let currentImg = this.data.currentImg;
let deg = this.data.deg;
let endX = this.data.endX;
let endY = this.data.endY;
let startX = this.data.startX;
let startY = this.data.startY;
let left = this.data.left;
let endLeft = this.data.endLeft;
if (this.getTouchData(endX,endY,startX,startY) == 'left') {
currentImg--;
} else if (this.getTouchData(endX, endY, startX, startY) == 'right'){
currentImg++
}
if (Math.abs(currentImg) % len == 0) {
left = 0;
} else {
left = currentImg > 0 ? Math.abs(currentImg) % len / len * 100 : (1 - Math.abs(currentImg) % len / len) * 100;
}
this.setData({
left: left,
endLeft: left,
currentImg: currentImg,
rotateY: deg * currentImg
})
this.getView(this.data.endScaleX, this.data.endScaleY);
},
//判断用户左右滑
getTouchData(endX, endY, startX, startY) {
let turn = "";
if (endX - startX > 50 && Math.abs(endY - startY) < 50) { //右滑
turn = "right";
} else if (endX - startX < -50 && Math.abs(endY - startY) < 50) { //左滑
turn = "left";
}
return turn;
},
//开始滑动
touchStart(e) {
this.setData({
startX: e.changedTouches[0].clientX,
startY: e.changedTouches[0].clientY
});
},
//滑动中 (有动画过渡效果时使用,不需要过渡效果时可以注释掉内部代码)
touchMove(e) {
let _this = this;
let len = _this.data.imgLists.length
let deg = _this.data.deg;
let maxLeft = (len - 1) / len * 100;
let maxRotate = (len - 1) / len * 360;
let startX = this.data.startX;
let endLeft = parseInt(this.data.endLeft);
let moveX = 0;
let rotate = 0;
let endRotate = parseInt(this.data.endRotate);
let barWidth = 0;
let currentImg = this.data.currentImg;
wx.createSelectorQuery().select('.scrollBar').boundingClientRect(function (rect) {
barWidth = rect.width;
moveX = endLeft + parseInt((e.touches[0].clientX - startX) / barWidth * 100);
rotate = endRotate + parseInt((e.touches[0].clientX - startX) / barWidth * 360);
if (moveX < 0 && rotate < 0) {
moveX = 0;
rotate = 0;
currentImg = 0;
} else if (moveX > maxLeft && rotate > maxRotate) {
moveX = maxLeft;
rotate = maxRotate;
currentImg = len - 1;
} else {
for (let i = 0; i < len; i++) {
if (i / len * 100 < moveX && (i + 1) / len * 100 > moveX) {
moveX = (i + 1) / len * 100;
if ((e.touches[0].clientX - startX) > 0) {
currentImg = i + 1;
} else {
currentImg = i;
}
}
if (i / len * 360 < rotate && (i + 1) / len * 360 > rotate) {
rotate = (i + 1) / len * 360;
if ((e.touches[0].clientX - startX) > 0) {
currentImg = i + 1;
} else {
currentImg = i;
}
}
}
}
_this.setData({
left: moveX,
rotateY: rotate,
currentImg: currentImg
});
let lists = _this.data.imgLists;
for (let i = 0; i < len; i++) {
if (i * deg == rotate) {
lists[i].scaleX = _this.data.scaleX;
lists[i].scaleY = _this.data.scaleY;
} else {
lists[i].scaleX = _this.data.scaleX;
lists[i].scaleY = _this.data.scaleY;
}
}
_this.setData({
imgLists: lists,
})
}).exec();
},
//滑动结束
touchEnd(e) {
this.setData({
endX: e.changedTouches[0].clientX,
endY: e.changedTouches[0].clientY,
endLeft: parseInt(this.data.left),
endRotate: parseInt(this.data.rotateY),
});
this.getView(this.data.endScaleX, this.data.endScaleY);//有动画过渡效果时使用(3d-animation)
// this.rotateCarousel();//无动画过渡效果时使用(3d)
},
//获取当前视图
getView() {
let lists = this.data.imgLists;
let len = this.data.imgLists.length;
let deg = this.data.deg;
let rotateY = 0;
if (this.data.rotateY > 0) {
rotateY = this.data.rotateY >= 360 ? this.data.rotateY % 360 : 360 - this.data.rotateY;
} else {
rotateY = Math.abs(this.data.rotateY) >= 360 ? Math.abs(this.data.rotateY) % 360 : Math.abs(this.data.rotateY);
}
for (let i = 0; i < len; i++) {
lists[i].rotateY = i * deg;
lists[i].translateZ = 320;
if (i * deg == rotateY) {
lists[i].scaleX = this.data.endScaleX;
lists[i].scaleY = this.data.endScaleY;
} else {
lists[i].scaleX = this.data.scaleX;
lists[i].scaleY = this.data.scaleY;
}
}
this.setData({
imgLists: lists,
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let len = this.data.imgLists.length;
let deg = Math.floor(360 / len);
let width = 1 / len * 100;
this.setData({
rotateY: 0,
endRotate: 0,
currentImg: 0,
deg: deg,
left: 0,
endLeft: 0,
width: width
})
this.getView(this.data.endScaleX, this.data.endScaleY);
}
})
5.暂且就这样了