欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

微信小程序 3D轮播

程序员文章站 2024-02-11 17:14:46
...

非常简单的微信小程序3D轮播
(弄着玩,代码比较随意,两个页面的都揉一起了)
1.看看效果吧
微信小程序 3D轮播
微信小程序 3D轮播
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.暂且就这样了