微信小程序实现3D轮播图效果(非swiper组件)


Posted in Javascript onSeptember 21, 2019

本文实例为大家分享了微信小程序实现3D轮播图效果的具体代码,供大家参考,具体内容如下

首先上一下效果图:

微信小程序实现3D轮播图效果(非swiper组件)

 在做的时候首先想到的是用swiper组件但是发现swiper组件放进去图片的时候会没有3d的效果,原因是swiper组件自带的style属性限制了3d效果所需要的属性,所以单独写了一个组件。

index.html

<view class='page-con'>
  rotate.wxml
  <view class='stage'>
    <view class='wrapper' bindtouchstart='start' bindtouchend='end'>
      <block wx:for='{{swiperList}}'>
        <image class='imgBasic {{index === 0 ? "" : "fold"}} {{item.active ? item.swpClass : ""}}' src='{{item.imgsrc}}' data-index='{{index}}'></image>
      </block>
    </view>
    <view class='dots'>
      <block wx:for='{{swiperList}}' wx:key='unique'>
        <view data-i='{{index}}' bindtap='fn' class='dot {{index === currentImageIndex ? "active" : ""}}'></view>
      </block>
    </view>
  </view>
</view>

index.css:

.stage{
  perspective: 3000rpx;
  perspective-origin: 50% 50%;
  border: 2rpx solid rgba(0, 0, 0, 0.5);
  padding: 20rpx 28rpx;
  background: rgba(255, 255, 255,0.8);
  height: 520rpx;
}
.wrapper{
  height:480rpx;
  margin-top: 20rpx;
  transform-style: preserve-3d;
  position: relative;
}
.imgBasic{
  position: absolute;
  width:480rpx;
  height:480rpx;
  border-radius:10rpx;
  border: 7rpx solid #fff;
}
image:nth-child(1){
  -webkit-transform: rotateY(0deg);
  transform: rotateY(0deg);
}
image:nth-child(2){
  left: 260rpx;
}
image:nth-child(3){
  left: 320rpx;
}
image:nth-child(4){
  left: 380rpx;
}
.fold{
  transform: rotateY(-80deg) scale3d(1,0.85,1) translateZ(-10%);
  -webkit-transform: rotateY(-80deg) scale3d(1,0.85,1);
  background: rgba(255, 255, 255,0.8);
}
 
.swiper-con{
  height: 520rpx;
}
.scrollCon{
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: nowrap;
  background: red;
}
.itemParent{
  position: relative;
  width: 100%;
  height: 1000rpx;
}
.item{
  width: 100rpx;
  float: left;
  height: 100rpx;
}
.item-con{
  height:500rpx;
}
swiper-item{
  width:480rpx;
  height:480rpx;
}
 
.idx-content {
 perspective: 1500;
}
.idx-content .idx-swiper {
 position: relative;
 margin: 40rpx 0;
 padding-bottom: 100%;
 transform-style: preserve-3d;
}
.idx-content .idx-swiper .idx-cswp {
 width: 70%;
 height: 100%;
 position: absolute;
 transform-style: preserve-3d;
 top: 0;
 border-radius: 6px;
}
.idx-content .idx-swiper .idx-cswp image {
 width: 100%;
 max-height: 600rpx;
}
.idx-content .idx-swiper .idx-cswp .swp-title .swp-btime {
 text-align: center;
 font-size: 28rpx;
}
.idx-content .idx-swiper .idx-cswp .swp-title .swp-bname {
 text-align: center;
 font-size: 24rpx;
}
/*
  右边的图片展开动画效果
*/
@keyframes rotateImage{
  from{
    transform:rotateY(-80deg);
    -webkit-transform:rotateY(-80deg);
    left: 250rpx;
  }
  to{
    transform: rotateY(0deg) scale3d(1,1,1);
    -webkit-transform: rotateY(0deg) scale3d(1,1,1);
    left: 0rpx;
  }
}
@keyframes backRotateImage{
  from{
    transform: roateteY(0deg) scale3d(1,1,1);
    -webkit-animation: rotateY(0deg) scale3d(1,1,1);
    filter: contrast(100%) brightness(100%);
  }
  to{
    transform: rotateY(280deg) scale3d(1,0.85,1);
    -webkit-animation: rotateY(280deg) scale3d(1,0.85,1);
    left: 210rpx;
  }
}
@keyframes leftMoveAnimation{
  from{
    /* transform:translateX(-300rpx); */
    /* left: 260rpx; */
  }to{
    transform:translateX(-40%) scale3d(1,0.85,1) rotateY(-80deg);
    -webkit-transform:translateX(-40%) scale3d(1,0.85,1) rotateY(-80deg);
  }
}
@keyframes leftMove2Animation{
  from{
    
  }to{
    transform:translateX(-35%) scale3d(1,0.85,1) rotateY(-80deg);
    -webkit-transform:translateX(-35%) scale3d(1,0.85,1) rotateY(-80deg);
  }
}
/*
  功能介绍:向左边展开,放大,位移操作
*/
.swp-left {
 animation: rotateImage 1s normal;
 -webkit-animation: rotateImage 1s normal;
 animation-iteration-count:1;
 animation-fill-mode: forwards;
 transform-origin: right;
 backface-visibility: hidden;
}
/*
  功能介绍:单独从左侧位移到屏幕的最后侧位置并且播放折叠动画
*/
.swp-right {
  animation: backRotateImage 1s normal;
  -webkit-animation: backRotateImage 1s normal;
  animation-iteration-count:1;
  animation-fill-mode: forwards;
  transform-origin: right;
  backface-visibility: hidden;
}
/*
 右边的动画依次向左移动,放大,旋转操作
*/
.move-left1{
  transform:rotateY(-80deg) scale3d(1,0.85,1);
  animation: leftMoveAnimation 1s normal;
  -webkit-animation: leftMoveAnimation 1s normal;
  animation-iteration-count:1;
  animation-fill-mode: forwards;
  transform-origin: right;
  backface-visibility: hidden;
}
.move-left2{
  transform:rotateY(-80deg) scale3d(1,0.85,1);
  animation: leftMove2Animation 1s normal;
  -webkit-animation: leftMove2Animation 1s normal;
  animation-iteration-count:1;
  animation-fill-mode: forwards;
  transform-origin: right;
  backface-visibility: hidden;
}
.dots{
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: center;
  margin: 0 8rpx;
  position: absolute;
  left: 0rpx;
  right: 0rpx;
  bottom: 15rpx;
}
.dot{
  margin: 0 8rpx;
  height: 15rpx;
  width: 15rpx;
  background: #da91f5;
  border-radius: 15rpx;
}
.active{
  width: 40rpx;
  height: 15rpx;
  border-radius: 15rpx;
}

控制层index.js:

// pages/lck/testJing/perfact.js
let app = getApp();
Page({
 
  /**
   * 页面的初始数据
   */
  data: {
    host: app.host,
    dkheight: 300,
    dkcontent: `你好<br/>nihao,<br/><br/><br/><br/><br/><br/><br/>这个是测试<br/><br/>你同意了吗<br/><br/><br/>hehe<b class='nihao'>n你好啊,我加粗了kk</b >
   <p><img src='http://shop.ykplay.com/upload/1/App.ico'/><strong>asdfasdfasd</strong></p>`,
    typeValue: null,
    showRightToast: false,
    changeImg: false,
    show: true,
    swiperList: [
      {
        index: 0,
        aurl: "../start/start",
        swpClass: "swp-left",
        active: false,
        imgsrc: "../../resources/test.png",
      },
      {
        index: 1,
        aurl: "#",
        swpClass: "swp-right",
        active: false,
        imgsrc: "../../resources/800.jpg"
      },
      {
        index: 2,
        aurl: "#",
        swpClass: "swp-right",
        active: false,
        imgsrc: "../../resources/900.jpg"
      },
      {
        index: 3,
        aurl: "#",
        swpClass: "swp-right",
        active: false,
        imgsrc: "../../resources/1000.jpg"
      }],
    played: false,
    //滑动触点开始的时候
    startPoint: 0,
    currentImageIndex: 0
 
  },
 
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.data.typeValue = {};
    this.data.typeValue.size = 'M';
    this.data.typeValue.color = 'red';
    console.log("typeValue is ", this.data.typeValue);
    this.setData({
      typeValue: this.data.typeValue
    })
    let winPage = this;
    wx.getSystemInfo({
      success: function (res) {
        let winHeight = res.windowHeight;
        console.log(winHeight);
        winPage.setData({
          dkheight: winHeight - winHeight * 0.05 - 80
        })
      }
    })
 
    wxParse.wxParse('dkcontent', 'html', this.data.dkcontent, this, 5);
  },
 
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
 
  },
 
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    //  wx.hideLoading();
  },
 
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
 
  },
 
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
 
  },
 
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
 
  },
 
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
 
  },
 
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
 
  },
  previewImage: function (e) {
    var that = this,
      //获取当前图片的下表
      index = e.currentTarget.dataset.index,
      //数据源
      pictures = this.data.pictures;
    wx.previewImage({
      //当前显示下表
      current: pictures[index],
      //数据源
      urls: pictures
    })
  },
  onShareAppMessage: function (ops) {
    
  },
 
  show: function (event) {
    this.setData({
      show: true
    })
  },
  back: function () {
    this.setData({
      show: false
    })
  },
  //显示求换按钮
  swpBtn: function (event) {
    let swp = this.data.swiperList;
    let max = swp.length;
    let dataSet = event.currentTarget.dataset;
    let idx = dataSet.index;
    console.log("idx is ", idx);
    let prev = swp[idx - 1];
    let curView = swp[idx];
    let next = swp[idx + 1];
    console.log("prev is ", prev);
    console.log("curView is ", curView);
    for (let j = 0; j < max; j++) {
      swp[j].active = true;
    }
    if (idx == 1 && prev && next) {
      prev.swpClass = 'swp-right';
      curView.swpClass = 'swp-left';
      console.log("curView.index is ", curView.index);
      for (let i = 2; i < max; i++) {
        if (i === 2) {
          swp[i].swpClass = 'move-left1';
        } else if (i === 3) {
          swp[i].swpClass = 'move-left2';
        }
      }
      let self = this;
      this.setData({
        swiperList: swp
      }, () => {
        console.log("外层的setData被调用");
        //将数组中的第一个元素删除放到最后的位置
        let first = swp.shift();
        swp.push(first);
        console.log("swp is ", swp);
        self.data.swiperList = swp;
        self.setData({
          swiperList: swp
        }, () => {
          console.log("最内层的setData被调用");
        })
      })
    }
  },
  start: function (e) {
    console.log("e is ", e);
    this.data.startPoint = e.changedTouches[0].pageX;
    console.log("startPoint is ", this.data.startPoint);
  },
  end: function (e) {
    let isLeft = false;
    let isRight = false;
    console.log("e is ", e);
    console.log("endPoint is ", e.changedTouches[0].pageX);
    let endPoint = e.changedTouches[0].pageX;
    console.log("是否向左移动?", (endPoint - this.data.startPoint) < 0 ? (isLeft = true) : (isRight = true));
    console.log("isLeft is ", isLeft);
    console.log("isRight is ", isRight);
    //如果向左移动的话执行相应方法
    if (isLeft) {
      this.moveLeft(1);
    } else {
      // this.moveRight();
    }
  },
  moveLeft: function (idx) {
    if (idx === 1) {
      let swp = this.data.swiperList;
      let max = swp.length;
      let prev = swp[idx - 1];
      let curView = swp[1];
      let next = swp[idx + 1];
      console.log("prev is ", prev);
      console.log("curView is ", curView);
      for (let j = 0; j < max; j++) {
        swp[j].active = true;
      }
      if (prev && next) {
        prev.swpClass = 'swp-right';
        curView.swpClass = 'swp-left';
        console.log("curView.index is ", curView.index);
        // this.data.currentImageIndex = curView.index;
        this.setData({
          currentImageIndex: curView.index
        })
        for (let i = 2; i < max; i++) {
          if (i === 2) {
            swp[i].swpClass = 'move-left1';
          } else if (i === 3) {
            swp[i].swpClass = 'move-left2';
          }
        }
        let self = this;
        this.setData({
          swiperList: swp
        }, () => {
          console.log("外层的setData被调用");
          //将数组中的第一个元素删除放到最后的位置
          let first = swp.shift();
          swp.push(first);
          console.log("swp is ", swp);
          self.data.swiperList = swp;
          self.setData({
            swiperList: swp
          }, () => {
            console.log("最内层的setData被调用");
          })
        })
      }
    }
  },
  icon: function (e) {
    console.log("e is ", e);
  }
})

源码地址:rotate3d

现在的功能是左滑移动,感兴趣的朋友可以试试右滑移动。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Microsoft Ajax Minifier 压缩javascript的方法
Mar 05 Javascript
Javascript 类与静态类的实现(续)
Apr 02 Javascript
理解Javascript_09_Function与Object
Oct 16 Javascript
正则表达式中特殊符号及正则表达式的几种方法总结(replace,test,search)
Nov 26 Javascript
ECMAScript6的新特性箭头函数(Arrow Function)详细介绍
Jun 07 Javascript
JavaScript Promise启示录
Aug 12 Javascript
js实现图片缓慢放大缩小效果
Aug 02 Javascript
JavaScript高仿支付宝倒计时页面及代码实现
Oct 21 Javascript
JS实现的适合做faq或menu滑动效果示例
Nov 17 Javascript
js 取消页面可以选中文字的功能方法
Jan 02 Javascript
js时间戳转yyyy-MM-dd HH-mm-ss工具类详解
Apr 30 Javascript
vue键盘事件点击事件加native操作
Jul 27 Javascript
微信小程序自定义波浪组件使用方法详解
Sep 21 #Javascript
LayUi使用switch开关,动态的去控制它是否被启用的方法
Sep 21 #Javascript
LayUI switch 开关监听 获取属性值、更改状态的方法
Sep 21 #Javascript
Vue登录主页动态背景短视频制作
Sep 21 #Javascript
layui table 获取分页 limit的方法
Sep 20 #Javascript
微信小程序用户拒绝授权的处理方法详解
Sep 20 #Javascript
解决layui动态加载复选框无法选中的问题
Sep 20 #Javascript
You might like
php empty,isset,is_null判断比较(差异与异同)
2010/10/19 PHP
PHP 实现类似js中alert() 提示框
2015/03/18 PHP
Windows下php+mysql5.7配置教程
2017/05/16 PHP
[原创]PHP实现字节数Byte转换为KB、MB、GB、TB的方法
2017/08/31 PHP
Laravel 集成 Geetest验证码的方法
2018/05/14 PHP
php桥接模式应用案例分析
2019/10/23 PHP
php使用自带dom扩展进行元素匹配的原理解析
2020/05/29 PHP
javascript之bind使用介绍
2011/10/09 Javascript
Google (Local) Search API的简单使用介绍
2013/11/28 Javascript
收集json解析的四种方法分享
2014/01/17 Javascript
简易的投票系统以及js刷票思路和方法
2015/04/07 Javascript
关于Function中的bind()示例详解
2016/12/02 Javascript
Angular.JS中的指令引用template与指令当做属性详解
2017/03/30 Javascript
JS设计模式之状态模式概念与用法分析
2018/02/05 Javascript
浅谈一种让小程序支持JSX语法的新思路
2019/06/16 Javascript
Node 使用express-http-proxy 做api网关的实现
2020/10/15 Javascript
vue二选一tab栏切换新做法实现
2021/01/19 Vue.js
python 实现插入排序算法
2012/06/05 Python
Python中的exec、eval使用实例
2014/09/23 Python
python PIL模块与随机生成中文验证码
2016/02/27 Python
详解Python自建logging模块
2018/01/29 Python
flask入门之表单的实现
2018/07/18 Python
Python学习笔记之图片人脸检测识别实例教程
2019/03/06 Python
使用Python的Turtle绘制哆啦A梦实例
2019/11/21 Python
PyQt5 文本输入框自动补全QLineEdit的实现示例
2020/05/13 Python
python 指定源路径来解决import问题的操作
2021/03/04 Python
欧洲最大的球衣网上商店:Kitbag
2017/11/11 全球购物
俄罗斯的精英皮具:Wittchen
2018/01/29 全球购物
使用Vue.js和MJML创建响应式电子邮件
2021/03/23 Vue.js
《跨越百年的美丽》教学反思
2014/02/11 职场文书
婚纱摄影师求职信
2014/03/07 职场文书
合作经营协议书范本
2014/09/16 职场文书
学生上课说话检讨书
2014/10/25 职场文书
开学典礼校长致辞
2015/07/29 职场文书
python实现简单聊天功能
2021/07/07 Python
Elasticsearch Recovery 详细介绍
2022/04/19 Java/Android