今天给大家带来一个微信小程序的弹出是菜单效果,老规矩先上效果图。(录制的gif动画有点卡,实际真机或是模拟器上很顺畅)
先简单说下思路:
1、首先在屏幕的某个位置放几个悬浮按钮,放几个看你需要的功能
2、点击最上层(wxml中最后一个就是最上层)的的按钮后增加背景遮罩,这个遮罩在我前面自定义modal弹框时有用到
3、分别对按钮做旋转和移动动画和透明度,造成动画差异就是位移的动画距离不同
4、收起的时候回到原来位置并且让透明度变成0就ok了
思路说完了,下面开始上实现代码,这里同样也是封装成了组件,方便调用。
首先是wxml实现
<view bindtap="showOrHide" wx:if="{{isShow}}" catchtouchmove="myCatchTouch"></view> <view > <image src="" animation="{{animDelLots}}" bindtap="deleteLots"></image> <image src="" animation="{{animAdd}}" bindtap="add"></image> <image src="" animation="{{animMain}}" bindtap="showOrHide"></image> </view>
然后是wxss
//悬浮按钮 .buttom{ width: 100rpx; height: 100rpx; display: flex; flex-direction: row; position: fixed; bottom:60rpx; right: 60rpx; z-index: 1001; } .drawer_screen { width: 100%; height: 100%; position: fixed; top: 0; left: 0; right:0; bottom:0; z-index: 1000; background: #000; opacity: 0.5; overflow: hidden; } .drawer_box { overflow: hidden; position: fixed; z-index: 1001; }
json文件
{ "component": true, "usingComponents": {} }
最后是js逻辑实现
// components/Menu/menu.js var systemInfo = wx.getSystemInfoSync(); Component({ /** * 组件的属性列表 */ properties: { }, /** * 组件的初始数据 */ data: { isShow: false,//是否已经弹出 animMain: {},//旋转动画 animAdd: {},//item位移,透明度 animDelLots: {},//item位移,透明度 }, /** * 组件的方法列表 */ methods: { //点击弹出或者收起 showOrHide: function () { if (this.data.isShow) { //缩回动画 this.takeback(); this.setData({ isShow: false }) } else { //弹出动画 this.popp(); this.setData({ isShow: true }) } }, add: function () { this.triggerEvent("addEvent") this.showOrHide() }, deleteLots: function () { this.triggerEvent("deleteLotsEvent") this.showOrHide() }, //弹出动画 popp: function () { //main按钮顺时针旋转 var animationMain = wx.createAnimation({ duration: 500, timingFunction: 'ease-out' }) var animationDelLots = wx.createAnimation({ duration: 500, timingFunction: 'ease-out' }) var animationAdd = wx.createAnimation({ duration: 500, timingFunction: 'ease-out' }) animationMain.rotateZ(180).step(); animationDelLots.translate(0, -200 / 750 * systemInfo.windowWidth).rotateZ(180).opacity(1).step(); animationAdd.translate(0, -320 / 750 * systemInfo.windowWidth).rotateZ(180).opacity(1).step(); this.setData({ animMain: animationMain.export(), animDelLots: animationDelLots.export(), animAdd: animationAdd.export(), }) }, //收回动画 takeback: function () { //main按钮逆时针旋转 var animationMain = wx.createAnimation({ duration: 500, timingFunction: 'ease-out' }) var animationDelLots = wx.createAnimation({ duration: 500, timingFunction: 'ease-out' }) var animationAdd = wx.createAnimation({ duration: 500, timingFunction: 'ease-out' }) animationMain.rotateZ(0).step(); animationDelLots.translate(0, 0).rotateZ(0).opacity(0).step(); animationAdd.translate(0, 0).rotateZ(0).opacity(0).step(); this.setData({ animMain: animationMain.export(), animDelLots: animationDelLots.export(), animAdd: animationAdd.export(), }) } }, //解决滚动穿透问题 myCatchTouch: function () { return } })
在要调用的页面json文件引用menu组件(我这里引用了两个组件,还有一个是前面封装的dialog组件)
"usingComponents": { "dialog": "/components/Dialog/dialog", "menu": "/components/Menu/menu" },
然后在调用的wxml中使用
<!--_addEvent 和 _deleteLotsEvent分别是弹出菜单里面按钮对应的事件,需要在调用的js中实现 --> <menu hidden bind:addEvent="_addEvent" bind:deleteLotsEvent="_deleteLotsEvent" />
调用menu组件的js中实现菜单中item的点击事件
_addEvent: function(){ //do something }, _deleteLotsEvent: function(){ //do something }
整体代码实现就这么多,代码比较简单,如果有不清楚的童鞋,请留言,我将为你们解答。