提到跑马灯,你会想到怎么实现?

<marquee></marquee>标签实现?

上百度搜marquee,第一条答案就告诉你——已废弃

JS实现一套?

这大概是目前最普遍的实现方式。

思路有很多,比如用js计算偏移量,用循环定时任务去移动偏移量。

可以是:

  • 定时任务+transform
  • 定时任务+scroll

不管是哪种方式,代码量少说也有100行左右,还需处理各种状态判断。

由于没有找到合适的方案(在我看来,不能直接拿来用的代码就不是好代码);

所以只能自己造轮子,今天刚出炉的,给你介绍一下。

css实现

本例方案:用纯CSS动画实现跑马灯。

思路:采用animation循环动画,搭配CSS属性做到循环滚动,再根据文案长短动态设置动画时长。

代码实现

标签:

      <div className="marquee-root">
        <div className="marquee-content">
          跑马灯滚动起来…… 
        </div>
      </div>

css:

@keyframes marqueeAnim {
  0% {
    transform: translateX(100vw);
  }
  100% {
    transform: translateX(-100%);
  }
}

.marquee-content {
  white-space: nowrap;
  display: inline-block;
  color: chocolate;
  animation: marqueeAnim 5s linear 0s infinite;
}

.marquee-root {
  width: 100%;
  height: 30px;
  text-align: left;
  line-height: 30px;
  overflow: hidden;
  background-color: burlywood;
}

over

以上就是跑马灯的简单实现了。上面的跑马灯可以做到不管是多少文案,都能够展示完毕再进行下一次循环滚动。

但是在变换莫测的产线环境,文案可短可长,这种固定动画时长的方案可能会导致下面这种问题:


没错,有的快有的慢,文案很多的时候就快得离谱。

动态控制动画时间

根据文案的多少来决定动画时长。很简单,只要一行代码。

style={{ animationDuration: marqueeStrs.length * 0.2 + 5 + "s" }}

在你的动画div上面添加这个stylemarqueeStrs是你的跑马灯文案,0.2是时间系数,可以根据实际情况修改,+ 5是添加时间基数,不然文案少的时候就飞起来了。

全代码:

  //todo test data
  const marqueeStrs = "跑马灯滚动起来…… 跑马灯滚动起来…… 跑马灯滚动起来…… ";
  return (
    <div className="App">
      <div className="marquee-root">
        <div
          className="marquee-content"
          style={{ animationDuration: marqueeStrs.length * 0.2 + 5 + "s" }}
        >
          {marqueeStrs}
        </div>
      </div>
    </div>
  );

前面的css不需要修改。

效果图对比:


可以看到两张图的速度基本相等。

小结

这个方案看起来很简单,但是有一些点是需要注意的。

  1. white-space: nowrap; 可以让你的文案强制不换行。
  2. display: inline-block; 可以让你的跑马灯布局根据内容自适应。
  3. overflow: hidden; 父布局设置这个属性可以让跑马灯内容超出部分被隐藏。
  4. 0%transform: translateX(100vw); 是为了让跑马灯从屏幕外开始移动。
  5. 100%transform: translateX(-100%); 是为了让跑马灯布局滚动整个布局宽度(不是屏幕宽度),最后滚到屏幕外。

以上几个CSS样式是本次跑马灯实现的核心支撑。当然,还有最后的动态计算动画时间也是核心步骤。

那么,你应该会了。

如果你有更好的方案,欢迎评论区留言,Show出你的代码!