CSS-使用Animation实现弹幕动画效果

6 篇文章 0 订阅

1.需求

在某个位置上展示一些弹幕,弹幕的样式需求如下:![在这里插入图片描述](https://img-blog.csdnimg.cn/20210312173916879.png在这里插入图片描述

2.实现过程

因为在很多位置都需要用到该样式的弹幕功能,所以我将弹幕封装成一个组件(BaberrageVertical),在父组件中传入数据源来进行弹幕数据的显示。

2.1 HTML

2.2.1 父组件

<BaberrageVertical :customers="barrageList" class="helper-top-barrage"/>

Tip:我们可以在此处对弹幕于父组件页面位置进行决定

2.2.2 子组件

<div class="baberradeVertical">
    <ul class="baberradeVertical-left">
      <li class="baberradeVertical-left-item" v-for="(item,index) in threeObj" :key="index">
        <span class="baberradeVertical-left-item-name">{{ item.name }} 是一条</span>
        <span class="baberradeVertical-left-item-coursesName">弹幕</span>
      </li>
    </ul>
  </div>

2.2 JS

<script>
export default {
  props: {
    customers: {	// 接收参数,主要为弹幕显示的内容
      type: Array,
    }
  },
  data() {
    return {
      baberrageTimer: null,	// 定时器,固定时间内将数据进行操作
      threeObj: [],		// 过多dom操作影响页面性能,所以用这个来固定几个dom,只修改数据即可
      showBaberrageAll: [],	// 弹幕池
    }
  },
  methods: {
  // 设置弹幕内容
    setOperateItem() {
      let i = 0;
      this.baberrageTimer = setInterval(() => {
      // 每一秒,向弹幕池中增加一条数据
        this.showBaberrageAll.push(this.customers[i]);
        // dom<5 向屏幕中增加数据即可
        this.threeObj = this.showBaberrageAll
        // 若dom数量过大,将列表中第一个li移除掉,增加一个新的li,这样不会因为循环对动画效果造成影响
        if (this.showBaberrageAll.length > 5) {
          // 移除第一个dom
          const baberrageParent = document.querySelector('.baberradeVertical-left')
          baberrageParent.removeChild(baberrageParent.childNodes[0])
          // 在列表结尾处新增一个li,用于存放新的元素
          let newLi = document.createElement('li')
          newLi.className = "baberradeVertical-left-item"
          newLi.innerHTML = `
          <span class="baberradeVertical-left-item-name">${this.threeObj[4].name} 报名了</span>
       <span class="baberradeVertical-left-item-coursesName">${this.threeObj[4].coursesName}</span>
          `
          baberrageParent.appendChild(newLi)
          // 超过五条后,令弹幕池中永远保持同样的数据即可,数量虽然未变,但是内容可以不断更新
          this.threeObj.shift();
        }
        i++;
        if (i > 9) {
          i = 0;
        }
      }, 1000)
    },
  },
  // 在页面销毁时清除定时器,否则会影响性能
  beforeDestroy() {
    clearInterval(this.baberrageTimer)
  },
  mounted() {
    this.setOperateItem();
  }
}
</script>

2.3 CSS

这个样式我单独封装成一个less文件,因为在js中有动态增加li及相关样式,若在组件中定义,会因为时机的问题加载不出来

.baberradeVertical-left-item {
  background: #666666;
  padding: 4px;
  display: block;
  border-radius: 4px;
  animation: slidein linear 5s infinite;

  &-name {
    color: #FFFFFF;
    font-size: 12px;
  }

  &-coursesName {
    color: cadetblue;
    font-size: 12px;
    line-height: 17px;
    margin-left: 4px;
  }
}

@keyframes slidein {
  0% {
    transform: translateX(0, 0);
    opacity: 0;
  }

  20% {
    transform: translate(16px, 0px);
    opacity: 1;
  }

  40% {
    transform: translate(16px, -20px);
    opacity: 1;
  }

  60% {
    transform: translate(16px, -40px);
    opacity: 1;
  }

  80% {
    transform: translate(16px, -60px);
    opacity: 1;
  }

  100% {
    transform: translate(16px, -80px);
    opacity: 0;
  }
}

3.遇到问题

在实现结果后会出现如下的问题,当我们在页面停留观看弹幕效果时,如果离开该窗口查看其它内容,计时器和动画效果同步,再次回来时会看到动画效果堆叠在一起,影响体验,解决方法如下:

3.1 方法一:清空所有弹幕内容,重新开始

在页面挂载时,增加一个visibilitychange事件监听器,监听是否在当前页面,如果离开该页面则清空定时器,回来时重新开始定时器,代码如下:

eg:
  async mounted() {
  // 进入页面时,调用定时器,动画动起来
    await this.setOperateItem();
    // 加入事件监听器,当离开/回到当前窗口时进行不同的操作
    window.addEventListener("visibilitychange", async () => {
      if (document.hidden === true) {
        // 页面被挂起
        clearInterval(this.baberrageTimer);
        this.threeObj = [];
        this.showBaberrageAll = [];
        document.querySelector('.baberradeVertical-left').innerHTML = '';
      } else {
        // 页面由挂起被激活,弹幕重新开始
        await this.setOperateItem();
      }
    });
  }

完全原创哦,转载商用请加水印~

一直在路上,一路不迷茫!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值