微信小程序创建动画

2020-05-08  本文已影响0人  东扯葫芦西扯瓜

微信小程序创建动画

本文说下微信小程序的动画创建
先看效果图

[video(video-ahQoAtNe-1588948921831)(type-tencent)(url-https://v.qq.com/txp/iframe/player.html?vid=w0963oyuxdl)(image-http://puui.qpic.cn/vpic/0/w0963oyuxdl.png/0)(title-微信小程序动画演示)]

关键代码

由于项目使用云开发,所以天然支持asnyc await

index.js

首先说下基本思路:
动画效果是点击中间的切换按钮,两边的文字向对方移动最终互换,移动过程中还有透明度变化,由于两边文字长度不同,要能够精确掌握各自移动的距离,获取节点信息必不可少,所以先封装了两个获取节点信息的函数,为了减少代码嵌套,使用promise封装。
getQuerysFields_Sync 能获取元素宽高,定位值(即top,left,bottom,right)、边距等信息
getQuerySync 可以获取元素宽高,定位置信息
具体用法请查阅小程序获取dom节点api

注意我这里因为使用云开发,所天然支持async /await,如果你的项目没有使用云开发,是不能尺寸async /await的,除非引入相关插件

第二将文字移动透明动画提出去,方便调用,函数为switchTextAnimationFun,中间按钮翻转动画单独写

  // 中文苗文切换动画
  async wantChangeL(){
    let { input_cOrH}=this.data
    let config={
      computedStyle:['width','margin']
    }
    let switchImgDomInfo = await getQuerysFields_Sync('.arrew', config)
    let textDomInfo = await getQuerySync('.switchText')
    let switchImgMarginHalfX = parseInt(switchImgDomInfo.margin.split(' ')[1])
    let switchImgWidth=parseInt(switchImgDomInfo.width)
    let textWidth = textDomInfo.width
    let switchTargetMoveX = switchImgMarginHalfX * 2 + switchImgWidth + textWidth
    this.switchTextAnimationFun(1000, switchTargetMoveX)
    //中间按钮翻转动画
    let arrewAnimation = wx.createAnimation({
      duration:1000,
      timingFunction: 'ease'
    })
    let arrewImgRotateDeg = input_cOrH ? 180 : 0
    arrewAnimation.rotateX(arrewImgRotateDeg).step(1000)
    this.setData({
      checkResultTexts: [],
      arrewAnimation: arrewAnimation.export()
    })
    setTimeout(()=>{
      this.switchTextAnimationFun(0, 0)
      this.setData({
        input_cOrH: !input_cOrH,
      })
    },1000)
    
  },
    // 切换文字动画
  switchTextAnimationFun(duration, switchTargetMoveX){
    let leftTextAnimation = wx.createAnimation({
      duration,
      timingFunction: 'ease'
    })
    let rightTextAnimation = wx.createAnimation({
      duration,
      timingFunction: 'ease'
    })
    let opacityAnimation=wx.createAnimation({
      duration:2*duration/3,
      timingFunction:'ease'
    })
    leftTextAnimation.translateX(switchTargetMoveX).step(duration)
    rightTextAnimation.translateX(-switchTargetMoveX).step(duration)
    opacityAnimation.opacity(0).step(2*duration/3)
    this.setData({
      leftTextAnimation: leftTextAnimation.export(),
      rightTextAnimation: rightTextAnimation.export(),
      opacityAnimation: opacityAnimation.export()
    })
    setTimeout(()=>{
      opacityAnimation.opacity(1).step(duration / 3)
      this.setData({
        opacityAnimation: opacityAnimation.export()
      })
    },duration/2)
  },

util.js

/*同步获取节点*/
export const getQuerySync = (dom, that) => {
  return new Promise((resolve, reject) => {
    if (that) {
      that.createSelectorQuery().select(dom).boundingClientRect(res => {
        // //console.log(res)
        resolve(res)
      }).exec()
    } else {
      wx.createSelectorQuery().select(dom).boundingClientRect(res => {
        // //console.log(res)
        resolve(res)
      }).exec()
    }

  })
}

/*同步获取节点信息fields*/
export const getQuerysFields_Sync = (dom, config, that) => {
  // let {id,dataset,size,scrollOffset,properties,computedStyle,context,rect}=config
  // //console.log(wx)
  return new Promise((resolve, reject) => {
    if (that) {
      that.createSelectorQuery().select(dom).fields(config, res => {
        resolve(res)
      }).exec()
    } else {
      wx.createSelectorQuery().select(dom).fields(config, res => {
        resolve(res)
      }).exec()
    }

  })

}

其他文件

index.wxml页面

创建项目后,到index.wxml页面

<view class="indexPage">
  <view class="indexPageTop">
    <view class="logoBox rowCenter">
      <image src="../images/logo.jpg" class="logo"></image>
    </view>
    <!-- 查询操作 -->
    <view class="checkBox">
      <!-- 选择语系 -->
      <view class="switchHmongbBox rowCenter">
      <Radios radioData="{{switchHmongbData}}" size="18" bindradioChange="IwantThisHmongb" value="{{switchHmongb}}"/>
      </view>
      <!-- 中苗文切换 -->
      <view class="switchCheck rowCenter">
        <view class="rowCenter" animation="{{leftTextAnimation}}">
          <view class="rowCenter" animation="{{opacityAnimation}}">
            <text class="switchText rowCenter">{{input_cOrH ? chinese : hmongb}}</text>
          </view>
        </view>
        <view class="rowCenter" animation="{{arrewAnimation}}">
          <image src="../images/arrew.png" class="arrew {{input_cOrH ?'arrewRotate0' : 'arrewRotate180'}}" bindtap="wantChangeL"></image>
        </view>
        <view class="rowCenter" animation="{{rightTextAnimation}}">
          <view class="rowCenter" animation="{{opacityAnimation}}">
            <text class="switchText rowCenter">{{input_cOrH ? hmongb : chinese}}</text>
          </view>
        </view>
      </view>
      <!-- 模糊查询精准查询 -->
      <view class="wantMoreOrLessBox rowStart">
      <Radios radioData="{{wantMoreOrLessData}}" size="18" bindradioChange="tellMeWantMoreOrLess" value="{{wantMoreOrLess}}"/>
      </view>
      <!-- 查询框 -->
      <view class="inputCheckBox rowCenter">
        <view class="wordInputBox rowCenter">
          <input placeholder="请输入中文" class="wordInput" value="{{inputText}}" bindinput="getInputText"></input>
        </view>
        <view class="checkBtn rowCenter" bindtap="checkNow">查 询</view>
      </view>

    </view>
  </view>

  <!-- 查询结果 -->
  <view class="checkResultBox">
    <scroll-view scroll-y="true" class="checkResultText-scrollview" style="height:{{resultScrollHeight}}px;">
      <view>
        <block wx:for="{{checkResultTexts}}" wx:key="index">
          <view class="checkResultTextBox rowStart">
            <view class="copyBox" bindtap="copyTextFun" data-index="{{index}}">
              <text></text>
              <text></text>
            </view>
            <text class="resultText" bindtap="copyTextFun" data-index="{{index}}">{{input_cOrH ? item.hmongb : item.chinese}}</text>
            <text class="checkText">{{input_cOrH ? item.chinese :item.hmongb }}</text>
          </view>
        </block>
      </view>
    </scroll-view>
  </view>
  <!-- 复制结果 -->
  <view class="checkOptionBtnBox rowCenter">
    <view class="checkOptionBtn clearResult rowCenter" bindtap="clearResult">清空查询</view>
    <view class="checkOptionBtn copyResult rowCenter" bindtap="copyAllResult">复制结果</view>
  </view>
</view>

index.wxss

@import "../../utils/style/style.wxss";
view,text{
  font-size: 30rpx;
}
.logoBox{
  width:260rpx;
  height:260rpx;
  border-radius: 50%;
  overflow: hidden;
  margin:30rpx auto 50rpx auto;
}
.logo{
   width:260rpx;
  height:260rpx;
}
.checkBox{

}
.switchHmongbBox{
  margin-bottom: 20rpx;
}
.oneSwitchHmongbBox{
  margin-right: 20rpx;
}
.radioText{
  font-size: 24rpx;
  color:#999999;
}
.switchCheck{
  margin-bottom: 40rpx;
}
.switchText{
  font-size: 40rpx;
  width:200rpx;
  font-weight: bold;
}
.arrew{
  width:50rpx;
  height:36rpx;
  margin:0 50rpx;
}
.arrewRotate0{
 /* transform:rotateY(0deg);  */
/* transform-style:preserve-3d; */
 /* transform-origin:100% 18px  */
}
.arrewRotate180{
  /* transform:rotateY(180deg); */
  /* transform-style:preserve-3d; */
  /* transform-origin:100% 18px  */
}
.wantMoreOrLessBox{
  width:580rpx;
  margin:0 auto 20rpx auto;
}
.inputCheckBox{
}
.wordInputBox{
border:solid 2rpx #dddddd;
height:60rpx;
}
.wordInput{  
  height:60rpx;
  padding:0 10rpx;
  width:460rpx;
  background: #ffffff;
}
.checkBtn{
  width:120rpx;
  height:60rpx;
  background: #633319;
  color:#ffffff;
  font-size: 36rpx;
  font-weight: bold;
  border:solid 2rpx #633319;
}


/* 查询结果 */
.checkResultText-scrollview{
  /* background: #fcfcfc; */
}
.checkResultTextBox{
  flex-wrap: wrap;
  margin-bottom: 20rpx;
}
.resultText{
  margin: 0 20rpx 0 10rpx;
}
.copyBox{
  position: relative;
  width:30rpx;
  height:30rpx;
}
.copyBox text{
  width:20rpx;
  height:20rpx;
  position: absolute;
  border:solid 2rpx #F29438;
  background: #ffffff;
}
.copyBox text:first-of-type{
  left:0;
  top:0;  
}
.copyBox text:last-of-type{
  right:0;
  bottom:0;  
}

.checkResultBox{
  margin:30rpx auto 50rpx auto;
  width:600rpx;
  height:250rpx;
  align-items: flex-start;
}
.checkOptionBtnBox{
  position: fixed;
  bottom:0;
  left:0;
  width:100%;
}
.checkOptionBtn{
   height:80rpx;
  color:#ffffff;
  font-size: 36rpx;
  font-weight: bold;
  width:50%;
}
.clearResult{
background: #666666;
}
.copyResult{

  background: #F29438;
}

style.wxss

.left{
  float:left;
}
.clear{
  clear:both;
  overflow:hidden;
}
.clear::after{
    display: table;
    content:'';
    font-size:0;
  }
  .green{
    color: #5AC994 !important;
  }
  .gray{
    color:#999999 !important;
  }
  .graySmallText666{
    color:#666666 !important;
    font-size: 24rpx;
  }
   .graySmallText999{
    color:#999999 !important;
    font-size: 24rpx;
  }
  .wrap {
  width: 100%;
  height: 100%;
}
view,text{
  color:#333333;
  font-size: 28rpx;
}
/*按钮移动范围*/
.contact-area{
  width:100%;
  min-height:100vh;
}

/* flex布局 */
.rowStart{
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}
.rowAround{
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
}
.rowBtween{
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}
.rowCenter{
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
.rowEnd{
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  align-items: center;
}
.columnStart{
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
}
.columnAround{
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
}
.columnBtween{
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}
.columnCenter{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.columnEnd{
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
}
/* 返回按钮 */
.back-area {
   position: fixed;
   top:0;
   left:0;
  width:100%;
  height:100%;  
  z-index: 999;
}
.back-view {
  width: 80rpx;
  height: 80rpx;
}
.backBtn{
  border:solid 2rpx #ffffff;
  background: rgba(0,0,0,0.5);
  border-radius: 50%;
  color: #ffffff;
  font-weight: bold;
   width: 80rpx;
  height:80rpx;
  font-size:24rpx;
}
/* 页面标题 */
.pageTitleBox{
 width: 100%;
 position: relative;
 z-index: 999;
}
.pageSecondTitleBox{
  background: #5ac994;
  position: fixed;
  z-index: 999;
  left:0;
  top:0;
  width:100%;
}
.pageTitle {
  width: 100%;
  text-align: center;
  color: #fff;
  font-size: 36rpx;
  position: fixed;
  left:0;
  top:0;
  z-index: 999;
  font-weight: bold;
}
/*规格*/
.detailSpec{  
  background: #f5f5f5;
  color:#333333;
}
.detailSpecActive{
 background: #e6f2ed !important;
  color:#5AC994 !important;
}
/*选好了大按钮*/
.chooseOkBtn{
  background: #5AC994;
  width:100%;
  height:80rpx;
  color:#ffffff;
}
/* 关闭按钮x */
.closeBox{
  position: absolute;
  top:20rpx;
  right:20rpx;
  width:40rpx;
  height:40rpx;
}
.closeBox text{  
  background: #999999;
  position: absolute;
  left:50%;
  top:50%;
  transform: translate(-50%,-50%) rotate(-45deg);
}
.closeBox text:first-of-type{
  width:28rpx;
  height:2rpx;
}
.closeBox text:last-of-type{
  width:2rpx;
  height:28rpx;
}
/*弹窗黑是背景*/
.blackBk{
  width:100%;
  height:100vh;
  background: rgba(0,0,0,0.7);
  position: fixed;
  left:0;
  top:0;
  z-index: 99999;
}
/*在底部的弹窗白底*/
.bottomWhiteBox{
  background: #ffffff;
  position: absolute;
  bottom:0;
  left:0;
  width:100%;
  padding:20rpx 20rpx 0rpx 20rpx;
  box-sizing: border-box;
}
/*二维码canvas*/
.canvas-box{
  position: fixed;
  right:-100%;
  top:-100%;
}
/*请稍后*/
.loadingBox{
  position: fixed;
  top:0;
  left:0;
  width:100%;
  height:100vh;
  z-index: 99999;
}
.loadingText{
  color:#ffffff;
  padding:5rpx 10rpx;
  border-radius: 5rpx;
  background: rgba(0,0,0,0.8);
}
/*动画箭头*/
.openSwitch{
  transform: rotate(180deg);
}
.closeSwitch{
  transform: rotate(0);
}
/*点击获取地理位置*/
.getLocationBox{
  position: fixed;
  left:0;
  top:0;
  width:100%;
  height:100vh;
  z-index: 99999;
}
.getLocationText{
  background: #5ac994;
  color:#ffffff;
}
/* 透明按钮 */
.transparentBtn{
   background: transparent;
}
.transparentBtn::after{
  outline: none;
  border: none;
}
.getUserInfoBtn{
position: absolute;
  left:0;
  top:0;
  width:100%;
  height:100%;
  z-index: 999;
}
/* /////////////////////////////////////////////////新 */
.jiantou-right{
  width:23rpx;
  height:41rpx;
}
.red{
  color:red;
}
.yellow{
  color:#F29438;
}
.deepYellow{
  color:#633319;
}
上一篇下一篇

猜你喜欢

热点阅读