实现一个仿 Safari 语音识别的 CSS 动画

643 阅读1分钟

在 Safari 浏览器中,我们使用语音输入功能时,会出现一个非常”酷炫“的动画效果,仿佛你正在和浏览器进行互动。那么,这个动画效果可以用 CSS 来实现吗?当然可以!

本文将为大家介绍如何使用原生 JavaScript 和 CSS 来实现一个仿 Safari 语音识别的动画效果。以下是最终的效果演示:

实现思路

1. 创建一些竖线,表示每个音频线

我们可以利用 hr 元素的特性,将多条 hr 元素以一定的方式组合在一起,然后用 CSS 控制元素的长度和粗细。

  hr {
    background-color: #fff;
    width: 2px;
    height: 5px;
    margin: 0 3px;
    display: inline-block;
    border: none;
  }

2. 给每个竖线增加动画效果

通过下面代码能够发现,所有的变化效果都由 scaleY 控制

有两个点需要关注下

  • 180ms 是控制动画的变换的频率
  • scaleY(var(--scale)) 我们通过设置不同的 scale 来控制每个线条高度
  .animate {
    animation: note 180ms ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: alternate;
  }

  @keyframes note {
    0% {
      transform: scaleY(1);
    }

    100% {
      transform: scaleY(var(--scale));
    }
  }

3. 通过 JS 创建元素并设置 scale

  const box = document.querySelector(".box");
  const count = 40;  // 线条的个数
  const mid = count / 2;
  for (let i = 0; i < count; i++) {
    const hr = document.createElement("hr");
    hr.classList.add("animate");

    let scale = Math.random();
    
    // 下面的代码是为了让随机有规律(中间的高度大于两侧的高度)
    const distanceFromMiddle = Math.abs(i - mid);
    if (distanceFromMiddle < mid / 2) {
      // 让中间的线条不要太小
      scale = scale < 0.3 ? scale + 0.3 : scale;
    }
    scale *= (1 - distanceFromMiddle / mid) * 20;

    hr.style.setProperty("--scale", scale);
    // 使每个线条动画看起来有差异
    hr.style.animationDelay = Math.random() > 0.5 ? "180ms" : "100ms";
    box.appendChild(hr);
  }

最后

如果有帮到你,或者觉得这篇文章写的不错,可以给我一个赞和关注,让我更有动力写出更多优质的技术文章。