找回密码
 立即注册
搜索

切换class样式实现动画播放,出现动画闪烁

1
回复
500
查看
[复制链接]

46

主题

47

帖子

465

积分

 楼主| 2021-7-30 17:43:41 显示全部楼层 |阅读模式

现象描述

通过切换class的样式来实现动画播放会导致动画闪烁,如录屏所示,点击“点我旋转”,“获取播放状态”的文字会左右旋转,但在旋转过程中出现闪烁。

问题代码如下:

<template>
<!-- template里只能有一个根节点 -->
<div class="wrapper">
<text @click="rotate">点我旋转</text>
<text
      class="title {{ isRotate ? 'title_play' : 'title_pause' }}"
      @click="getCurrentTIme"
    >
{{ title }}
</text>
<input
      class="btn"
      type="button"
      value="跳转到播放器"
      onclick="onDetailBtnClick"
    />
</div>
</template>

<script>
  import router from '@system.router'
  import prompt from '@system.prompt';
  export default {
    // 页面级组件的数据模型,影响传入数据的覆盖机制:private内定义的属性不允许被覆盖
    private: {
      title: '获取播放状态',
      player: null,
      duration: 269,
      player: null,
      isRotate: false
    },
    onInit() {
    },
    getCurrentTIme() {
      this.player = $Player.getInstance()
      if (this.player) {
        this.player.getStatus().then(res => {
          console.log(res)
          prompt.showToast({
            message: res,
            duration: 2000,
            gravity: 'center'
          })
        })
      }
    },
    onDetailBtnClick() {
      router.push({
        uri: '/pages/DemoDetail'
      })
    },
    rotate() {
      this.isRotate = !this.isRotate
    }
  }
</script>
<style lang="scss">
  @import './../../assets/styles/style.scss';
  .wrapper {
    @include flex-box-mixins(column, center, center);
    .title {
      font-size: 8 * $size-factor;
      text-align: center;
      color: $black;
    }
    .btn {
      width: 90 * $size-factor;
      height: 16 * $size-factor;
      border-radius: 8 * $size-factor;
      background-color: $brand;
      color: $white;
      font-size: 30px;
      margin-top: 16 * $size-factor;
    }
  }
  .slider-wrapper {
    margin: 30px 50px 0;
    width: 100%;
    flex-direction: column;
  }
  .title {
    margin-top: 50px;
    transform-origin: 0 0;
    animation-duration: 0.3s;
    animation-iteration-count: 1;
    animation-timing-function: ease-in-out;
    &_play {
      transform: rotate(24deg);
      animation-name: playAni;
    }
    &_pause {
      transform: rotate(0deg);
      animation-name: pauseAni;
    }
  }
  @keyframes playAni {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(24deg);
    }
  }
  @keyframes pauseAni {
    from {
      transform: rotate(24deg);
    }
    to {
      transform: rotate(0deg);
    }
  }
</style>


回复

使用道具 举报

23

主题

142

帖子

825

积分

2021-7-30 17:45:34 显示全部楼层

问题分析

问题出在如下样式切换代码中:

.title {
margin-top: 50px;
transform-origin: 0 0;
animation-duration: 0.3s;
animation-iteration-count: 1;
animation-timing-function: ease-in-out;
&_play {
transform: rotate(24deg);
animation-name: playAni;
}
&_pause {
transform: rotate(0deg);
animation-name: pauseAni;
}
}

transform和animation-name属性不能同时设置,否则会导致动画重复执行。

解决方法

需要删除上述代码中的transform字段,只保留animation-name,并添加“animation-fill-mode: forwards;”,解决代码如下:

<template>
<!-- template里只能有一个根节点 -->
<div class="wrapper">
<text @click="rotate">点我旋转</text>
<text
      class="title {{ isRotate ? 'title_play' : 'title_pause' }}"
      @click="getCurrentTIme"
    >
{{ title }}
</text>
<input
      class="btn"
      type="button"
      value="跳转到播放器"
      onclick="onDetailBtnClick"
    />
</div>
</template>

<script>
  import router from '@system.router'
  import prompt from '@system.prompt';
  export default {
    // 页面级组件的数据模型,影响传入数据的覆盖机制:private内定义的属性不允许被覆盖
    private: {
      title: '获取播放状态',
      player: null,
      duration: 269,
      player: null,
      isRotate: false
    },
    onInit() {
    },
    getCurrentTIme() {
      this.player = $Player.getInstance()
      if (this.player) {
        this.player.getStatus().then(res => {
          console.log(res)
          prompt.showToast({
            message: res,
            duration: 2000,
            gravity: 'center'
          })
        })
      }
    },
    onDetailBtnClick() {
      router.push({
        uri: '/pages/DemoDetail'
      })
    },
    rotate() {
      this.isRotate = !this.isRotate
    }
  }
</script>
<style lang="scss">
  @import './../../assets/styles/style.scss';
  .wrapper {
    @include flex-box-mixins(column, center, center);
    .title {
      font-size: 8 * $size-factor;
      text-align: center;
      color: $black;
    }
    .btn {
      width: 90 * $size-factor;
      height: 16 * $size-factor;
      border-radius: 8 * $size-factor;
      background-color: $brand;
      color: $white;
      font-size: 30px;
      margin-top: 16 * $size-factor;
    }
  }
  .slider-wrapper {
    margin: 30px 50px 0;
    width: 100%;
    flex-direction: column;
  }
  .title {
    margin-top: 50px;
    transform-origin: 0 0;
    animation-duration: 0.3s;
    animation-iteration-count: 1;
    animation-timing-function: ease-in-out;
    animation-fill-mode: forwards;//当动画完成后,保持最后一个属性值(在最后一个关键帧中定义)
    &_play {
      animation-name: playAni;
    }
    &_pause {
      animation-name: pauseAni;
    }
  }
  @keyframes playAni {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(24deg);
    }
  }
  @keyframes pauseAni {
    from {
      transform: rotate(24deg);
    }
    to {
      transform: rotate(0deg);
    }
  }
</style>


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册