美文网首页APP & program
微信小程序实现单选跳跃选择动画

微信小程序实现单选跳跃选择动画

作者: 苏苏哇哈哈 | 来源:发表于2022-03-20 20:03 被阅读0次

    1.实现效果

    radioChange.gif

    2.实现原理

    wx.createAnimation(Object object):创建一个动画实例 animation。调用实例的方法来描述动画。最后通过动画实例的 export 方法导出动画数据传递给组件的 animation 属性

    Animation.translateY(number translation):在 Y 轴平移的距离,单位为 px

    wx.createSelectorQuery():获取相应id的高度

    • 拿到当前列表数据的高度+当前选中小圆点的高度,计算出translateY的值
    let dd = this.data.boxHeight / this.data.items.length;
    let ee = this.data.boxCircle / 2;
    animation.translateY(index * dd + ee).step();
    
    • 设置animation ,动画持续时间,500 ms
    var animation = wx.createAnimation({
       duration: 500,
        timingFunction: "linear",
        delay: 0
      })
    

    3.实现代码

    <view class="mb20 title">radio自定义样式</view>
    <radio-group bindchange="radioChange">
      <view class="box">
        <label class="flex-row" wx:for="{{items}}" wx:key="items">
          <view class="cust_label">
            <radio value="{{item.value}}" checked="true" />
            <view class="radio_checked" wx:if="{{curr==item.value}}"></view>
          </view>
          <view class="name {{curr==item.value&&'name_checked' }}">{{item.name}}</view>
        </label>
      </view>
    </radio-group>
    <view class="mb20 title">单选跳跃选择动画</view>
    <view class="flex-row">
      <view class="box" id="box">
        <view wx:for="{{items}}" wx:key="items" class="cust_label" catchtap="choseItem" data-index="{{index}}"></view>
        <view id="box-circle" class="checked" animation="{{animationData}}"></view>
      </view>
      <view>
        <view wx:for="{{items}}" wx:key="items" class="name {{item.checked&&'name_checked' }}" catchtap="choseItem" data-index="{{index}}">{{item.name}}</view>
      </view>
    </view>
    
    page {
      background-color: #f3bc90;
      padding: 20px;
    }
    
    .box {
      position: relative;
      overflow: hidden;
      flex-shrink: 0;
    }
    
    radio {
      display: none;
      opacity: 0;
    }
    
    .cust_label {
      border-radius: 50%;
      border: 16rpx solid #e06c35;
      height: 60rpx;
      width: 60rpx;
      margin-bottom: 20rpx;
      margin-right: 20rpx;
      transition: border-color 800ms;
      flex-shrink: 0;
      position: relative;
      box-sizing: border-box;
    }
    
    
    .name {
      font-family: 'susu';
      font-size: 35rpx;
      color: #fff;
      line-height: 60rpx;
      margin-bottom: 20rpx;
    }
    
    
    .radio_checked {
      position: absolute;
      background: #fff;
      border-radius: 50%;
      height: 30rpx;
      width: 30rpx;
      top: 50%;
      left: 50%;
      margin-top: -15rpx;
      margin-left: -15rpx;
    }
    
    .name_checked {
      color: #e06c35;
    }
    
    .title {
      color: #fff;
      font-size: 26rpx;
    }
    
    .checked {
      position: absolute;
      background: #fff;
      border-radius: 50%;
      height: 30rpx;
      width: 30rpx;
      left: 50%;
      margin-left: -25rpx;
      top: 0;
      transform: translateY(-80rpx);
    }
    
    Page({
    
      data: {
        items: [
          {
            name: '选项一二三',
            value: 1,
          },
          {
            name: '选项嘻嘻',
            value: 2,
          },
          {
            name: 'susu3', value: 3,
          },
          {
            name: 'susu4', value: 4,
          },
          {
            name: 'susu5', value: 5,
          },
          {
            name: '喜欢的哈哈哈哈哈哈', value: 6,
          }
        ],
        curr: '',
        animationData: {},
        boxHeight: 0,
        boxCircle: 0
      },
      onReady() {
        let query = wx.createSelectorQuery();
        query.select('#box').boundingClientRect(rect => {
          let height = rect.height;
          this.setData({
            boxHeight: height
          })
        }).exec();
        query.select('#box-circle').boundingClientRect(rect => {
          let height = rect.height;
          this.setData({
            boxCircle: height
          })
        }).exec();
      },
    
      radioChange(e) {
        console.log('radio发生change事件,携带value值为:', e.detail.value)
        const items = this.data.items
        let index = '';
        items.forEach((item, i) => {
          if (item.value == e.detail.value) {
            index = i;
          }
        })
        this.setData({
          curr: e.detail.value,
        })
      },
      choseItem(e) {
        let { index } = e.currentTarget.dataset, { items } = this.data;
        items.forEach((e, i) => {
          if (index == i) {
            e.checked = true
          } else {
            e.checked = false
          }
        })
        var animation = wx.createAnimation({
          duration: 500,
          timingFunction: "linear",
          delay: 0
        })
        let dd = this.data.boxHeight / this.data.items.length;
        let ee = this.data.boxCircle / 2;
        animation.translateY(index * dd + ee).step();
        this.setData({
          animationData: animation.export(),
          items,
        })
      }
    })
    

    4.完整代码,关注公众号 苏苏的bug,更多小程序demo,尽在苏苏的码云如果对你有帮助,欢迎你的star+订阅!

    相关文章

      网友评论

        本文标题:微信小程序实现单选跳跃选择动画

        本文链接:https://www.haomeiwen.com/subject/kzeadrtx.html