技术, 前端

声波动画教程

2019年03月24日,天气晴

最近项目中有一个声波动画的效果的需求,网上没找到合适的,于是手撸了一个。

效果

audiowave-demo-1

Demo

https://jsfiddle.net/HADB/x8vdkmqh/

示例代码

<div class="background">
      <div class="audiowave"></div>
</div>
/* 

Author: HADB
Date: 2019-03-24
My Blog: https://hadb.me
My GitHub: https://github.com/HADB

*/

var wavePillarCount = 100       // 柱子总数(用来调整密度)
var waveCount = 5               // 波形总数(用来调整波形数量)
var waveAnimationDuration = 3   // 单个动画秒数(与 animation-duration 一致)
var randomRate = 1              // 随机倍率,越大越随机

for (i = 0; i < wavePillarCount; i++) {
    var offset = ((i / wavePillarCount - 1) * waveCount * waveAnimationDuration) - Math.random() * randomRate;
    document.querySelector('.audiowave').innerHTML += '<div style="-webkit-animation-delay:' + offset + 's;"></div>';
}
body {
  padding: 0;
  margin: 0;
}

.background {
    width: 100vw;
    height: 100vh;
    background-color: #193082;
}

.audiowave {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 200px;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
}

.audiowave div {
    top: 0;
    background: rgba(44, 99, 255, 0.25);
    z-index: 9;
    width: 3px;
    height: 0;
    animation: audiowave 3s infinite linear;
}

@keyframes audiowave {
    0% {
        height: 28.75%;
    }

    5% {
        height: 37.5%;
    }

    10% {
        height: 56.25%;
    }

    15% {
        height: 48.75%;
    }

    20% {
        height: 68.75%;
    }

    25% {
        height: 82.5%;
    }

    30% {
        height: 71.25%;
    }

    35% {
        height: 78.125%;
    }

    40% {
        height: 68.75%;
    }

    45% {
        height: 80.875%;
    }

    50% {
        height: 90%;
    }

    55% {
        height: 91.875%;
    }

    60% {
        height: 87%;
    }

    65% {
        height: 70%;
    }

    70% {
        height: 60%;
    }

    75% {
        height: 55%;
    }

    80% {
        height: 45%;
    }

    85% {
        height: 40%;
    }

    90% {
        height: 35%;
    }

    95% {
        height: 30%;
    }

    100% {
        height: 28.75%;
    }
}

代码解析

核心还是通过 animation-delay 动画延迟来实现,audiowavekeyframes 是根据设计图中一个完整波形的大致高度来调整的,不需要太精确,因为我们会加一些随机数进去,这样可以使每个波形之间不完全一致,不然就太死板了。

wavePillarCount 是指整个声波中柱子的数量,可以根据总宽度和每个柱子的宽度按需调整。

waveCount 是波的数量,可以尝试把下面的 randomRate 设为 0 就可以清楚地看出来了。

randomRate 如上所述,是添加的随机延迟倍率,以便增加波形的杂音,不至于太死板。值越大杂音越大,值为 0 的时候没有杂音。下面是把 randomRate 设为 0 的效果。

audiowave-demo-2

另外,offset 计算的时候之所以要减去 1,是为了保证 offset 的值为负数,这样可以保证动画在一开始就是完整的,不然部分波形一开始将不完整,等到了那个 offset 时才会开始动。

基本上就是这样,通过通过 keyframes 来设置初始波形,通过微调 wavePillarCountwaveCountrandomRate 来获得更加的效果。

Author image

About Bean Deng