欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

小程序自定义组件对话框动画过渡记录

程序员文章站 2022-07-12 08:11:53
...

效果图

小程序自定义组件对话框动画过渡记录
小程序自定义组件对话框动画过渡记录

自定义组件wxml

<view class="{{translateY?'modal-shadow':'modal-shadow flex'}}" bindtap="onCancel"  hidden="{{!isShow}}">
    <view class="{{translateY?'modal-dialog translateY':'modal-dialog '}}" animation="{{animation}}"
    >
        <view class="modal-title" wx:if="{{isHeader}}">{{title}}</view>
        <view class="modal-content">
            <slot name="content"></slot>
        </view>
        <view class="modal-footer" wx:if="{{isFooter}}">
            <view class="btn-cancel" bindtap="onCancel" wx:if="{{isCancel}}">{{cancelTxt}}</view>
            <view class="btn-confirm" bindtap="onConfirm" wx:if="{{isConfirm}}">{{confirmTxt}}</view>
            <slot name="auth" ></slot>
        </view>
    </view>
</view>

自定义组件css

.modal-shadow {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    background:rgba(0,0,0,0.5);
    z-index: 1000;
}
.flex{
    display: flex;
    align-items:center;
    justify-content: center;
}
.modal-dialog {
    width: 80%;
    overflow: hidden;
    z-index: 1001;
    background: #fff;
    border-radius: 10rpx;
    padding: 30rpx;
    box-sizing: border-box;
}
.translateY{
    width:100%;
    position:absolute;
    bottom:0;
    left: 0;
    transform:translateY(100%);
    padding:0
}
.modal-title {
    font-size: 34rpx;
    text-align: center;
    font-weight:600;
    color:rgba(0,0,0,1);
    line-height:100rpx;
    border-bottom: 1px solid #dedede;
    overflow: hidden ;
    text-overflow: ellipsis;
    -webkit-line-clamp: 1;
    white-space:nowrap;
}
.modal-content {
    padding: 30rpx;
}
.modal-footer {
    display: flex;
    height: 86rpx;
    border-top: 1px solid #dedede;
    font-size: 34rpx;
    line-height: 86rpx;

}
.btn-cancel,.btn-confirm{
    width: 100%;
    text-align: center;
}
.btn-cancel {
    color: #666;
    border-right: 1px solid #dedede;
}

.btn-confirm {
    color: #0bb20c;
    background-color: #fff;
}

自定义组件js

const app = getApp()
Component({
  options:{
    multipleSlots: true //插槽
  },
  properties: {
    animation:{
      type: Object,
      value: {}
    },
    translateY:{
      type: Boolean,
      value: false
    },
    isShow: {
      type: Boolean,
      value: false
    },
    isFooter: {
      type: Boolean,
      value: true
    },
    isHeader: {
      type: Boolean,
      value: true
    },
    isCancel: {
      type: Boolean,
      value: true
    },
    isConfirm: {
      type: Boolean,
      value: true
    },
    cancelTxt: {
      type: String,
      value:"取消"
    },
    confirmTxt: {
      type: String,
      value: "确认"
    },
    title: {
      type: String,
      value: ""
    },
  },

  data: {

  },
  lifetimes: {
    attached: function () {

    },
  },
  methods: {
    onConfirm(){
        this.triggerEvent('onConfirm')
    },
    onCancel(){
      this.triggerEvent('onCancel')
    },
  }
})

效果图1调用

//json
{
  "usingComponents": {
    "anima-modal": "/pages/component/anima-modal/anima-modal"
  }
}

//wxml
<button bind:tap="onShow">显示</button>
<anima-modal isShow="{{authModal.isShow}}"  title="{{authModal.title}}"  animation="{{authModal.animation}}"
             cancelTxt="再看看" confirmTxt="确认授权" bind:onCancel="onCancel"  bind:onConfirm="onConfirm" >
  <view slot="content" >
    <view class="m-title">授权后,您将解锁更多功能</view>
    <view class="m-list flex-center">
      <view class="submit-bg cir"></view>
      <image src="https://static-1256912642.cos.ap-chengdu.myqcloud.com/pm2.0/register/jiangpin.png" mode="widthFix"></image>
      文件收藏
    </view>
    <view class="m-list flex-center">
      <view class="submit-bg cir"></view>
      <image src="https://static-1256912642.cos.ap-chengdu.myqcloud.com/pm2.0/register/wenjian%202.png" mode="widthFix"></image>
      奖品兑换
    </view>
  </view>
  <!--
     <view bind:tap="onConfirm" style="width:100%"  slot="auth">
        <button
                wx:if="{{canIUse}}"
                open-type="getUserInfo"
                bindgetuserinfo="bindGetUserInfo"
                class="btn-confirm"
        >
            确认授权
        </button>
    </view>
    -->
</anima-modal>
//js
const anima = require('../../utils/animation')
Page({
  data: {
    authModal: {
      isShow: false,
      isWxShow: false,
      isConfirm: false,
      title: '微信昵称头像授权',
      animation: 'animationData'
    },
    // canIUse: wx.canIUse('button.open-type.getUserInfo'),
  },
  onShow: function() {
    anima.showModal(this, 'authModal.isShow', 'authModal.animation', 1000, 1, 200, 'opacity')
  },
  onConfirm() {
    this.onCancel()
  },
  onCancel() {
    anima.hideModal(this, 'authModal.isShow', 'authModal.animation', 1000, 0, 500, 'opacity')
  },
  bindGetUserInfo(){

  }
})

效果图2调用

//wxml
<button bind:tap="onShow">显示</button>
<anima-modal isShow="{{isShow}}"  isHeader="{{false}}"  isFooter="{{false}}"
                bind:onCancel="onCancel" animation="{{animationData}}" translateY="{{true}}">
    <view slot="content" >
    </view>
  </anima-modal>
//js
const anima = require('../../utils/animation')
Page({
  data: {
      isShow: false,
  },
  onShow: function() {
     anima.showModal(this,'isShow','animationData',600,0,200,'translateY')
  },
  onCancel() {
         anima.hideModal(this,'isShow','animationData',600,500,700,'translateY')
  },
})

animation.js

module.exports={
    showModal: function (that,name,animationData,duration,style,timeout,way) {
        let animation = wx.createAnimation({
            duration: duration,//动画的持续时间 
            timingFunction: 'ease',//动画的效果 
        })
        let showName = '{"' + name + '":""}'
        showName = JSON.parse(showName);
        showName[name] = true
        that.setData(showName)
        setTimeout(function(){
            if(way==="translateY")//style值为距离
                animation.translateY(style).step()
            else if(way==='opacity')//style值为1-0
                animation.opacity(style).step({duration:0}) //重置动画,再次触发动画
            //将param转换为key
            let json = '{"' + animationData + '":""}'
            json = JSON.parse(json);
            json[animationData] = animation.export()
            that.setData(json)
        },timeout)//延迟执行
    },
    // 隐藏遮罩层
    hideModal: function (that,name,animationData,duration,style,timeout,way) {
        let animation = wx.createAnimation({
            duration: duration,
            timingFunction: 'ease',
        })
        if(way==="translateY")
            animation.translateY(style).step()
        else if(way==='opacity')
            animation.opacity(style).step({})
         let json = '{"' + animationData + '":""}'
        json = JSON.parse(json);
        json[animationData] = animation.export()
        that.setData(json)
        setTimeout(function(){
             let showName = '{"' + name + '":""}'
            showName = JSON.parse(showName);
            showName[name] = false
            //设置动画
            that.setData(showName)
        },timeout)//先执行动画,再隐藏模块

    },
}