微信小程序实现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 相关文章推荐
JMenuTab简单使用说明
Mar 13 Javascript
JQuery学习笔记 nt-child的使用
Jan 17 Javascript
JS版的date函数(和PHP的date函数一样)
May 12 Javascript
js和jquery中循环的退出和继续下一个循环
Sep 03 Javascript
jQuery中click事件的定义和用法
Dec 20 Javascript
JS实现支持多选的遍历下拉列表代码
Aug 20 Javascript
javascript实现右侧弹出“分享到”窗口效果
Feb 01 Javascript
jQuery使用deferreds串行多个ajax请求
Aug 22 Javascript
Bootstrap模态框插入视频的实现代码
Jun 25 Javascript
JavaScript操作文件_动力节点Java学院整理
Jun 30 Javascript
解决vue项目axios每次请求session不一致的问题
Oct 24 Javascript
vue 使用 sortable 实现 el-table 拖拽排序功能
Dec 26 Vue.js
微信小程序自定义波浪组件使用方法详解
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
别人整理的服务器变量:$_SERVER
2006/10/20 PHP
奇怪的PHP引用效率问题分析
2012/03/23 PHP
php三维数组去重(示例代码)
2013/11/26 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
PHP实现获取url地址中顶级域名的方法示例
2019/06/05 PHP
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
JS中Iframe之间传值的方法
2013/03/11 Javascript
js onload处理html页面加载之后的事件
2013/10/30 Javascript
上传图片js判断图片尺寸和格式兼容IE
2014/09/01 Javascript
AngularJS入门教程之学习环境搭建
2014/12/06 Javascript
javascript背景时钟实现方法
2015/06/18 Javascript
angularJS与bootstrap结合实现动态加载弹出提示内容
2015/10/16 Javascript
逻辑表达式中与或非的用法详解
2016/06/06 Javascript
BootstrapTable+KnockoutJS自定义T4模板快速生成增删改查页面
2016/08/01 Javascript
hovertree插件实现二级树形菜单(简单实用)
2016/12/28 Javascript
Vue 过渡实现轮播图效果
2017/03/27 Javascript
nodeJS实现路由功能实例代码
2017/06/08 NodeJs
JavaScript封装单向链表的示例代码
2020/09/17 Javascript
[01:20]辉夜杯背景故事宣传片《辉夜传说》
2015/12/25 DOTA
Python编程之string相关操作实例详解
2017/07/22 Python
利用python获取当前日期前后N天或N月日期的方法示例
2017/07/30 Python
Win10下python 2.7.13 安装配置方法图文教程
2018/09/18 Python
Python提取PDF内容的方法(文本、图像、线条等)
2019/09/25 Python
Python函数生成器原理及使用详解
2020/03/12 Python
python 比较字典value的最大值的几种方法
2020/04/17 Python
有关pycharm登录github时有的时候会报错connection reset的问题
2020/09/15 Python
图解CSS3制作圆环形进度条的实例教程
2016/05/26 HTML / CSS
畜牧兽医本科生的自我评价
2014/03/03 职场文书
班级学习计划书
2014/04/27 职场文书
个人房屋转让协议书范本
2014/10/26 职场文书
行政助理岗位职责范本
2015/04/11 职场文书
2015年维修工作总结
2015/04/25 职场文书
嘉年华活动新闻稿
2015/07/17 职场文书
Go中的条件语句Switch示例详解
2021/08/23 Golang
无线电知识基础入门篇
2022/02/18 无线电
世界十大儿童漫画书排名,法国国宝漫画排第五,第二是轰动日本连环
2022/03/18 欧美动漫