微信小程序实现卡片切换动画效果

原创 2018年04月14日 23:43:19

先上效果图


  1. index.wxml

Markup
<view class="xin">
<view class="title">你有一封新的信件</view>
<view class="border"></view>
<view class="xin-list" bindtouchend="moveItem" bindtouchstart="moveStart">
<block wx:for="{{xinList}}" wx:key="key" wx:for-index="idx">
<view class="single" style="opacity:{{item.display}};transform: translateX({{item.slateX}}) scale({{item.scale}});z-index:{{item.zIndex}};transform-origin: 100% 50% 0;{{item.style}}">
<view class="xin-shou">
致 {{item.to}}
</view>
<view class="xin-body">
{{item.msg}}
</view>
<view class="shenglue">···</view>
<view class="xin-xie">By {{item.from}}</view>
</view>
</block>
</view>
</view>


2.index.wxss

CSS
.xin{
     padding:0 20px;
}
.xin .title{
     font-size: 14px;
     color: #444;
}
.xin .border{
     height: 0;
     border-top: 1px solid #ccc;
     margin-top: 20px;
     width:20%;
}
.xin-list{
     width: 100%;
     position: relative;
}
.xin-list .single:nth-of-type(1){
     z-index: 10;
}
/* .xin-list .single:nth-of-type(2){
     position: absolute;
     transform: translateX(20px) scale(0.8);
     
     transform-origin: 100% 50% 0; 
     top: 0;

     z-index: -1;
}
.xin-list .single:nth-of-type(3){
     position: absolute;
     transform: translateX(40px) scale(0.6);
     
     transform-origin: 100% 50% 0; 
     
     top: 0;
     z-index: -2;
} 

*/
.xin-list .single:nth-of-type(n+4){
     
     transform:translateX(40px) scale(0.6);
     transform-origin: 100% 50% 0; 
}
.xin-list .single{
     transition: all 1s;
     overflow: hidden;
     border-radius: 1px;
     margin-top:15px;
     width: calc(100% - 60px);
     height: calc(100vh - 150px - 11vh);
     background: #fff;
     position: absolute;
     box-shadow: 3px 3px 10px 0px #777;
}
.xin-shou{
     writing-mode: vertical-lr;
     font-size: 15px;
     float: left;
     padding:10px 2px 10px 2px;
     letter-spacing:4px;
     margin:0 15px;
     position: relative;
     top: 50%;
     max-height: 80%;
     overflow: hidden;
     transform: translateY(-50%);
     border: 1px solid #999;
}
.xin-body{
     text-indent: 2em;
     letter-spacing:0.2em;
     writing-mode:vertical-lr;
     max-width:40vw;
     line-height:8vw;
     overflow: hidden;
     float: left;
     height: 70%;
     vertical-align: middle;
     position: relative;
     top: 50%;
     transform: translateY(-50%);
     text-align:justify;
}
.shenglue{
     float: left;
     height: 70%;
     line-height:25px;
     width: 25px;
     text-align:justify;
     writing-mode:vertical-lr;
     margin-top: 23%;
     letter-spacing:10px;
}
.xin-xie{
     clear: both;
     font-size: 12px;
     position: absolute;
     right: 15px;
     bottom: 10px;
}


3.index.js

JavaScript
//index.js
var app = getApp();
//获取应用实例

Page({
     data: {
          userInfo: {},
          startX:0, //开始移动时距离左
          endX:0, //结束移动时距离左
          nowPage:0, //当前是第几个个页面
          xinList:[
               {
                    id:5,
                    from:'一路向南1',
                    to:'记得要微笑',
                    msg:'这么多年咨询信看下来s,让我逐渐明白一件事。 很多时候,咨询的人心里已经有了答案,来咨询只是想确认自己的决定是对的。 所以有些人读过回信后,会再次写信过来, 大概就是因为回答的内容和他的想法不一样。',
                    display:0,
                    scale:'',
                    slateX:'',
                    zIndex:0,
                    style:''
               },
               {
                    id: 5,
                    from: '一路向南2',
                    to: '记得要微笑',
                    msg: '这么多年咨询信看下来s,让我逐渐明白一件事。 很多时候,咨询的人心里已经有了答案,来咨询只是想确认自己的决定是对的。 所以有些人读过回信后,会再次写信过来, 大概就是因为回答的内容和他的想法不一样。',
                    display:0,
                    scale: '',
                    slateX: '',
                    zIndex: 0,
                    style: ''
               },
               {
                    id: 5,
                    from: '一路向南3',
                    to: '记得要微笑',
                    msg: '这么多年咨询信看下来,让我逐渐明白一件事。 很多时候,咨询的人心里已经有了答案,来咨询只是想确认自己的决定是对的。 所以有些人读过回信后,会再次写信过来, 大概就是因为回答的内容和他的想法不一样。',
                    display:0,
                    scale: '',
                    slateX: '',
                    zIndex: 0,
                    style: ''
               },
               {
                    id: 5,
                    from: '一路向南4',
                    to: '记得要微笑',
                    msg: '这么多年咨询信看下来,让我逐渐明白一件事。 很多时候,咨询的人心里已经有了答案,来咨询只是想确认自己的决定是对的。 所以有些人读过回信后,会再次写信过来, 大概就是因为回答的内容和他的想法不一样。',
                    display:0,
                    scale: '',
                    slateX: '',
                    zIndex: 0,
                    style: ''
               },
               {
                    id: 5,
                    from: '一路向南5',
                    to: '记得要微笑',
                    msg: '这么多年咨询信看下来,让我逐渐明白一件事。 很多时候,咨询的人心里已经有了答案,来咨询只是想确认自己的决定是对的。 所以有些人读过回信后,会再次写信过来, 大概就是因为回答的内容和他的想法不一样。',
                    display: 0,
                    scale: '',
                    slateX: '',
                    zIndex: 0,
                    style: ''
               },
               {
                    id: 5,
                    from: '一路向南6',
                    to: '记得要微笑',
                    msg: '这么多年咨询信看下来,让我逐渐明白一件事。 很多时候,咨询的人心里已经有了答案,来咨询只是想确认自己的决定是对的。 所以有些人读过回信后,会再次写信过来, 大概就是因为回答的内容和他的想法不一样。',
                    display: 0,
                    scale: '',
                    slateX: '',
                    zIndex: 0,
                    style: ''
               },
               {
                    id: 5,
                    from: '一路向南7',
                    to: '记得要微笑',
                    msg: '这么多年咨询信看下来,让我逐渐明白一件事。 很多时候,咨询的人心里已经有了答案,来咨询只是想确认自己的决定是对的。 所以有些人读过回信后,会再次写信过来, 大概就是因为回答的内容和他的想法不一样。',
                    display: 0,
                    scale: '',
                    slateX: '',
                    zIndex: 0,
                    style: ''
               },
          ]
     },
     //事件处理函数

     onLoad: function (e) {
     
          this.checkPage(this.data.nowPage);
     },
     onReady: function () {
        
     },
     onShareAppMessage: function () {
          return {
               title: '解忧小酒馆,专治不开心~'
          }
     },
     //手指触发开始移动
     moveStart:function(e) {
          var startX = e.changedTouches[0].pageX;
          this.setData({
               startX:startX
          });
     },
     //手指触摸后移动完成触发事件
     moveItem: function (e) {
          var that = this;
          var endX = e.changedTouches[0].pageX;
          this.setData({
               endX: endX
          });
     
          //计算手指触摸偏移剧距离
          var moveX = this.data.startX - this.data.endX;
          
          //向左移动
          if(moveX > 20 ){
     
               if(that.data.nowPage >= (that.data.xinList.length - 1)) {
                    wx.showToast({
                         title: '最后一封信了喔,明天再来吧',
                         icon: 'none'
                    })
                    return false;
               }
               that.setData({
                    nowPage:that.data.nowPage+1
               });
               this.checkPage(this.data.nowPage);
          }
          if(moveX < -20) {
               if (that.data.nowPage <= 0) {
                    wx.showToast({
                         title: '这是第一封信了喔',
                         icon: 'none'
                    })
                    return false;
               } 
               that.setData({
                    nowPage: that.data.nowPage - 1
               });
               this.checkPage(this.data.nowPage);
               
               // wx.showToast({
               //  title: '不可以回退噢',
               //  icon:'none'
               // })
          }
          
               
     },
     // 页面判断逻辑,传入参数为当前是第几页 
     checkPage:function(index) {
          //信列表数据
          var data = this.data.xinList;
          var that = this;
          var m = 1;
          for(var i = 0;i < data.length;i ++) {
               //先将所有的页面隐藏
               var disp = 'xinList[' + i + '].display';
               var sca = 'xinList[' + i + '].scale';
               var slateX = 'xinList[' + i + '].slateX';
               var zIndex = 'xinList[' + i + '].zIndex';
               var style = 'xinList[' + i + '].style';
               that.setData({
                    [disp]:0,
                    [style]: "display:block",
               });
               //向左移动上一个页面
               if(i == (index - 1) ){
                    that.setData({
                         [slateX]: '-120%',
                         [disp]: 1,
                         [zIndex]: 2,
                         
                    });
               }
               //向右移动的最右边要display:none的页面
               if (i == (index + 3)) {
                    that.setData({
                         [style]:'display:none',
                         [slateX]:'0',
                         [zIndex]: -10,
                    });
               }
               if(i == index || (i > index && (i < index + 3))) {
                    //显示最近的三封
                    that.setData({
                         [disp]:1
                    });
                    //第一封信
                    if(m == 1){
                         this.setData({
                              [sca]: 1,
                              [slateX]: 0,
                              [zIndex]: 1,
                         });
                    }
                    //第一封信
                    else if (m == 2) {
                         this.setData({
                              [sca]: 0.8,
                              [slateX]:'20px',
                              [zIndex]: -1,
                         });
                    }
                    //第三封信
                    else if (m == 3) {
                         this.setData({
                              [sca]: 0.6,
                              [slateX]: '40px',
                              [zIndex]: -2,
                         });
                    }
                    m ++;
               }
          
          }
     }
})


简析:小程序不支持dom操作,所以只能通过数据绑定的方式实现,参考分页原理实现

[微信小程序]点击切换卡片动画效果

欢迎加入微信小程序开发交流QQ群(173683895)'先上效果图, GIF: ...
  • qq_35713752
  • qq_35713752
  • 2017-11-28 12:00:36
  • 4838

实现卡片翻转的动画效果

欢迎Follow我的GitHub, 关注我的CSDN. 在Android设计中, 经常会使用卡片元素, 正面显示图片或主要信息, 背面显示详细内容, 如网易有道词典的单词翻转和海底捞的食谱展示. 实现...
  • u012515223
  • u012515223
  • 2016-02-27 20:12:59
  • 6364

微信小程序_选项卡切换事例美容商城

http://www.see-source.com/weixinwidget/detail.html?wid=75 实现服务展示,服务详情,预约,技师列表,技师详情等功能 ...
  • sinat_17775997
  • sinat_17775997
  • 2017-01-03 20:40:58
  • 993

微信小程序14---卡片类view的实现

1.首先上效果图2.index.js中//重点在于阴影的设计 .card { border: 2px solid #ffffff; border-radius: 5px; ba...
  • qq_34589749
  • qq_34589749
  • 2016-11-16 22:02:43
  • 751

微信小程序实现tab和swiper切换结合效果viewpage+tab效果

实现tab+swiper(viewpage+tab)效果的实现,tab可左右滑动,跟着页面的滑动而改变位置的实现。tab也可点击切换page...
  • u013125372
  • u013125372
  • 2017-12-04 17:05:19
  • 235

微信小程序特殊效果合集第一期

一期一期的整,假如以下内容中,有已经无法使用的部分,欢迎指出;假如你有你觉得可以加入特殊效果范围的文章或帖子,或是你有自己制作的特殊效果,欢迎回复分享; 文字跑马灯效果:http://www.wxa...
  • u012421719
  • u012421719
  • 2017-04-28 11:06:52
  • 17491

微信小程序实现tab切换

代码如下: wxml 图文详情 产品参数
  • qq_25252769
  • qq_25252769
  • 2017-07-25 10:17:44
  • 428

微信小程序动画效果集合

一期一期的整,假如以下内容中,有已经无法使用的部分,欢迎指出;假如你有你觉得可以加入特殊效果范围的文章或帖子,或是你有自己制作的特殊效果,欢迎回复分享;  文字跑马灯效果:http://www.wx...
  • qq_20100573
  • qq_20100573
  • 2018-01-09 10:40:28
  • 973

微信小程序_城市切换DEMO

  • 2017年07月31日 15:10
  • 10KB
  • 下载

微信小程序滚动Tab选项卡:左右可滑动切换

最终效果如上。问题: 1、tab标题总共8个,所以一屏无法全部显示。 2、tab内容区左右滑动切换时,tab标题随即做标记(active)。 3、当active的标题不在当前屏显示时...
  • Sophie_U
  • Sophie_U
  • 2017-05-12 16:10:40
  • 22980
收藏助手
不良信息举报
您举报文章:微信小程序实现卡片切换动画效果
举报原因:
原因补充:

(最多只允许输入30个字)