热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

微信小程序特效菜单抽屉效果实例代码

这篇文章主要介绍了微信小程序特效菜单抽屉效果实例代码的相关资料,抽屉效果的菜单在APP应用中经常使用,这里用微信小程序来实现这一效果,需要的朋友可以参考下

实现效果图:

抽屉菜单是app上常见的菜单设计方式,典型的抽屉菜单如下图所示

下面展示如何基于微信小程序实现抽屉菜单,最终效果如下图所示: 

页面包含一个主页和抽屉菜单页,为了实现滑动效果,页面采用absolute布局,代码如下 

index.wxml


 
  
  {{userInfo.nickName}}
 


 
  
  {{userInfo.nickName2}}
 

index.wxss

.main-page {
 width:100%;
 height:2000rpx;
 position: absolute;
 top: 0;
 left: 0;
 padding: 200rpx 0;
}

.drawer-menu {
 width: 800rpx;
 height:2000rpx;
 position: absolute;
 top: 0;
 left: -800rpx;
 padding: 200rpx 0;
 background: rgba(22, 22, 22, 1);
 z-index: 800;
}

程序绑定了主页的touch事件和tap事件,并且使用catchtouchmove阻止了move事件的传递,因为在真机环境下页面会自动响应滑动事件,注意不要catch startend事件,这会导致无法触发tap事件。

首先定义一些数据来记录滑动过程和状态

 drawerMenuMoveData: {
  check: false,  //是否触发滑动操作
  state:0,  //0:初始状态 1:菜单弹出中状态 2:菜单弹入状态中 3:菜单弹出状态
  firstTouchX:0, //首次触摸X坐标值
  touchCheckX:60, //触发滑动的触摸X
  moveX:0,  // 滑动操作横向的移动距离
  maxMoveX: (app.globalData.deviceInfo.windowWidth - 60), //抽屉菜单最大移动距离
  lastTranlateX: 0 //上次动画效果的平移距离,用于校准left值
 },

之后就是滑动事件的响应处理 

touchstart事件,首先判断当前状态,然后根据触摸位置判断是否激活滑动状态

 onMainPageTouchstart: function(e) {
  var data = this.drawerMenuMoveData;
  var clientX = e.touches[0].clientX;
  //初识状态
  if (data.state === 0) {
   if (clientX <= data.touchCheckX && clientX > 20) {
    data.check = true;
    data.state = 1;
    data.firstTouchX = clientX;
   }
  }
  //菜单弹出状态
  else if (data.state === 3) {
   if (clientX >= data.maxMoveX) {
    data.check = true;
    data.state = 2;
    data.firstTouchX = clientX;
   }
  } 
 },

touchmove 事件,首先判断是否处于滑动状态,之后根据当前模式来计算主页和菜单页的left值来产生滑动效果

 onMainPageTouchmove: function(e) {
  var data = this.drawerMenuMoveData;
  var pixelRatio = app.globalData.deviceInfo.pixelRatio;
  if (data.check) {
   var mainPageLeft = 0, drawerMenuLeft = 0;
   var moveX = e.touches[0].clientX - data.firstTouchX;
   if (data.state === 1)
   {
    //处理边界状态
    if (moveX <0) {
     moveX = 0;
    }
    if (moveX > data.maxMoveX) {
     moveX = data.maxMoveX;
    }
    if (moveX >= 0 && moveX <= data.maxMoveX) {
     data.moveX = moveX;
     moveX = moveX - data.lastTranlateX;
     //px转为rpx
     moveX = moveX * pixelRatio;
     mainPageLeft = moveX;
     drawerMenuLeft = -800 + moveX;
    }
   }
   else if (data.state === 2) {
    //处理边界状态
    if (moveX > 0) {
     moveX = 0;
    }
    if (moveX <-data.maxMoveX) {
     moveX = -data.maxMoveX; 
    }
    if (moveX <= 0 && moveX >= -data.maxMoveX) {
     data.moveX = moveX;
     moveX = moveX - data.lastTranlateX;
     //px转为rpx
     moveX = moveX * pixelRatio;
     var maxMoveX = data.maxMoveX * pixelRatio;
     mainPageLeft = maxMoveX + moveX;
     drawerMenuLeft = maxMoveX -800 + moveX;
    }
   }

   this.setData({mainPageLeft: mainPageLeft, 
          drawerMenuLeft: drawerMenuLeft});
  }
 },

touchend事件 根据滑动的距离来判断菜单是否弹出,并创建滑动动画

 onMainPageTouchend: function(e) {
  var data = this.drawerMenuMoveData;
  if (!data.check) {
   return;
  }
  data.check = false;
  data.firstTouchX = 0;
  var moveX = data.moveX;
  data.moveX = 0;
  var animation = wx.createAnimation({duration: 100});
  var translateX = 0;
  var mainPageLeft = 0;
  var windowWidth = app.globalData.deviceInfo.windowWidth;
  if (data.state === 1)
  {
   if (moveX === 0 || moveX === data.maxMoveX) {
    data.state = (moveX === 0) &#63; 0 : 3;
    return;
   }
   mainPageLeft = moveX;
   //滑动距离是否超过窗口宽度一半
   if (mainPageLeft > (windowWidth / 2)) {
    translateX = data.maxMoveX - moveX;
    data.state = 3;
   }
   else {
    translateX = -moveX;
    data.state = 0;
   }
  } 
  else if (data.state === 2) {
   if (moveX === 0 || moveX === -data.maxMoveX) {
    data.state = (moveX === 0) &#63; 3 : 0;
    return;
   }
   //滑动距离是否超过窗口宽度一半
   mainPageLeft = data.maxMoveX + moveX
   if (mainPageLeft > (windowWidth / 2)) {
    translateX = -moveX;
    data.state = 3;
   }
   else {
    translateX = -mainPageLeft;
    data.state = 0;
   }
  }
  translateX += data.lastTranlateX;
  data.lastTranlateX = translateX;
  animation.translateX(translateX).step();
  this.setData({
   animationData:animation.export()
  });
 },

tap事件, 如果当前是弹出状态,则将菜单弹回

 onMainPageTap: function(e) {
  var data = this.drawerMenuMoveData;
  if (data.state !== 3) {
   return;
  }
  data.state = 0;
  var translateX = -data.maxMoveX;
  translateX += data.lastTranlateX;
  data.lastTranlateX = translateX;
  var animation = wx.createAnimation({duration: 100});
  animation.translateX(translateX).step();
  this.setData({
   animationData:animation.export()
  });
 }

总体逻辑并不复杂,主要是做好状态判断和坐标运算,但有些问题需要注意

1: 微信小程序提供了rpx单位用于适配设备,但是各种滑动事件和动画的单位通常是px,因此需要进行转换,转换方法为 rpx = px * pixelRatio,其中pixelRatio可以通过 wx.getSystemInfoSync()获取

2: 当对组件使用通过wx.createAnimation 创建的动画时,小程序框架会给组件添加transform属性,其中translateX值会和left属性相互作用,因此计算left值时需要处理translateX的值。

3: 由于在真机环境下,页面左滑(初始触摸点在左侧边界时)默认行为是返回上一页或退出小程序(取决与是否是第一级页面), 抽屉菜单会和该行为发生冲突。

另外目前还不支持swiper操作,后续有机会再补上吧。

源码下载:http://xiazai.jb51.net/201701/yuanma/wx-drawermenu-master(jb51.net).rar


推荐阅读
  • 微信小程序实现类似微博的无限回复功能,内置云开发数据库支持
    本文详细介绍了如何利用微信小程序实现类似于微博的无限回复功能,并充分利用了微信云开发的数据库支持。文中不仅提供了关键代码片段,还包含了完整的页面代码,方便开发者按需使用。此外,HTML页面中包含了一些示例图片,开发者可以根据个人喜好进行替换。文章还将展示详细的数据库结构设计,帮助读者更好地理解和实现这一功能。 ... [详细]
  • 微信小程序图片上传功能详解:wx.chooseImage与wx.uploadFile的使用方法与注意事项
    在微信小程序中,图片上传功能是开发者常用的功能之一。本文详细介绍了 `wx.chooseImage` 和 `wx.uploadFile` 的使用方法及注意事项。通过 `wx.chooseImage`,用户可以选择本地图片或拍摄新照片,而 `wx.uploadFile` 则用于将选中的图片上传到服务器。文章还提供了代码示例,帮助开发者更好地理解和应用这两个 API。此外,文中还讨论了常见的错误处理和性能优化技巧,确保图片上传过程的稳定性和高效性。 ... [详细]
  • 深入解析微信小程序开发中的全局配置文件设置与优化技巧
    本文深入探讨了微信小程序开发中全局配置文件的设置与优化技巧,详细解析了 `app.js`、`app.json`、`app.wxss` 和 `project.config.json` 的功能与最佳实践。通过合理配置这些文件,开发者可以显著提升小程序的性能和用户体验。文章还介绍了如何利用这些配置文件进行模块化开发和调试,帮助开发者更好地管理和维护小程序项目。 ... [详细]
  • wxParse 0.3:微信小程序中的高级 HTML 和 Markdown 富文本解析器,全面支持多级嵌套与 Emoji 表情
    wxParse 0.3 是一款专为微信小程序设计的高级富文本解析器,支持 HTML 和 Markdown 转换为 WXML 可视化格式。该组件不仅能够处理复杂的多级嵌套结构,还全面支持 Emoji 表情,极大地提升了内容展示的多样性和用户体验。 ... [详细]
  • 在微信小程序中实现外部链接跳转,可以通过微信官方提供的组件来完成。具体而言,有以下两种方法:1. 首先,可以通过创建一个新的 `` 组件来加载外部网页。这个组件允许在小程序内部嵌入一个网页视图,从而实现外部链接的展示和交互。2. 另一种方法是使用 `wx.navigateToMiniProgram` API,通过调用该接口可以跳转到其他已安装的小程序,实现更丰富的跨应用交互功能。这两种方法各有优缺点,开发者可以根据实际需求选择合适的方式。 ... [详细]
  • 微信小程序详解:概念、功能与优势
    微信公众平台近期向200位开发者发送了小程序的内测邀请。许多人对微信小程序的概念还不是很清楚。本文将详细介绍微信小程序的定义、功能及其独特优势。 ... [详细]
  • 对于众多创业公司而言,选择小程序或小视频的发展方向至关重要。本文将深入分析小程序和小视频的特点、优势及局限,帮助创业者做出更明智的选择。 ... [详细]
  • 据《经济参考报》报道,微信即将推出新版小程序,预计将在近期正式上线。此次更新将新增支付功能,进一步提升用户体验。此外,新版小程序还将提供“附近门店”接口,用户可通过定位功能轻松查找周边门店,享受更加便捷的服务。这一系列改进旨在为用户提供更加丰富和高效的使用体验。 ... [详细]
  • 经过短暂的休整,我们再次推出新的小程序功能,进一步提升用户体验。现在,小程序页面不仅支持放置转发按钮,还新增了长按快速转发的功能,让用户能够更加便捷地分享页面内容。这一更新将为开发者提供更多创意空间,同时也大幅提升了用户的互动性和使用便利性。 ... [详细]
  • Java 点餐系统源代码附带管理后台(免费提供)
    本项目提供了一套基于 Java 的点餐系统,包括前端小程序和后端管理平台。采用 Spring Boot 和 SSM 框架,结合 MySQL 和 Redis 数据库技术,适用于学习和二次开发。有需要源代码的开发者可以通过私信联系,免费获取下载链接。 ... [详细]
  • 基于Java的微信小程序:Spring Boot驱动的中小学家校互动与电子作业管理平台
    基于Java的微信小程序,采用Spring Boot作为后端框架,构建了一个高效的中小学家校互动与电子作业管理平台。前端使用了uni-app框架,确保跨平台兼容性。该平台集成了家校沟通、作业发布与管理、学生成绩查询等功能,旨在提升教育管理效率和家长参与度。后端开发环境配置完善,采用Spring Boot、MyBatis等技术栈,确保系统的稳定性和扩展性。 ... [详细]
  • 如何撰写PHP电商项目的实战经验? ... [详细]
  • 经过半年的精心整理,我们汇总了当前市场上最全面的Android面试题解析,为移动开发人员的晋升和加薪提供了宝贵的参考资料。本书详细涵盖了从基础到高级的各类面试题,帮助读者全面提升技术实力和面试表现。章节目录包括:- 第一章:Android基础面试题- 第二章:... ... [详细]
  • 如何在微信文章中插入附件文档:详细教程与技巧分享
    对于众多企业和教育机构的微信公众号而言,在发布信息时常常需要在文章中嵌入各类文档附件,例如应聘申请表、健康声明书、数据记录表、疫情防控登记表、项目申报评分表及各类公告通知等。本文将详细介绍如何在微信文章中高效地插入不同类型的文档附件,并分享一些实用技巧,帮助用户提升内容发布的专业性和便捷性。 ... [详细]
  • 微信小程序 Scroll View 组件的上拉加载与下拉刷新功能优化指南 ... [详细]
author-avatar
小庄2502921871
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有