Search code examples
animationsvgsvg-animate

How to animate the svg rectangle to grow like music wave?


I have a below code,

<div id="akbar">
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg"
     width="400" height="200" viewBox="0 0 400 200">
    <g transform="scale(1,-1) translate(0,-200)">
      <rect x="50" y="0" fill="#f00" width="100" height="100">
        <animate attributeName="height" 
                 from="0" 
                 to="100" 
                 dur="0.5s" 
                 fill="freeze" />
      </rect>
      <rect x="150" y="0" fill="#f70" width="100" height="200">
        <animate 
                 attributeName="height" 
                 from="0" 
                 to="200" 
                 dur="0.5s" 
                 fill="freeze" />
      </rect>
      <rect x="250" y="0" fill="#ec0" width="100" height="150">
        <animate 
                 attributeName="height" 
                 from="0" 
                 to="150" 
                 dur="0.5s" 
                 fill="freeze" />
      </rect>
    </g>
  </svg>
</div>

I would like to animate the svg rectangle to grow like music waves.

How can I achieve that?

I need this behavior


Solution

  • You can achieve it using

    • values,
    • keyTimes
    • and keySplines

    attributes of an <animate> tag.

    JSfiddle example.

    I stripped your example to single column only:

    <svg version="1.1" xmlns="http://www.w3.org/2000/svg"
     width="400" height="200" viewBox="0 0 400 200">
      <g transform="scale(1,-1) translate(0,-200)">
        <rect x="50" y="0" fill="#f00" width="100" height="100">
          <animate 
            attributeName="height" 
            from="0"
            to="100" 
            dur="1s" 
            fill="freeze"
            values="0; 200; 150; 160; 150; 160"
            keyTimes="0; 0.2; 0.4; 0.6; 0.8; 1"
            keySplines=".42 0 1 1;
                        0 0 .59 1;
                        .42 0 1 1;
                        0 0 .59 1;
                        .42 0 1 1;
                        0 0 .59 1;"
          />
        </rect>
      </g>
    </svg>
    

    As it is not perfect yet, you can play around with the attributes to adjust the timing better (keySplines especially) and make it more music waves like.

    As you can see on the provided example, single column steps of movements are:

    1. All the way from bottom to top
    2. Then, from top to ~83% of height
    3. Then, from ~83% to ~88%,
    4. Then, from ~88% to ~83%,
    5. Then, from ~83% to ~88%

    I guess that increasing the difference between those repeating percentage numbers (83 and 88) will give you slightly better effect than mine (which is based on 75% and 80%, easier to calculate on widht: 200px), but it is close.

    Also take a look at CSS tricks article on SVG animation, it is very thorough and covers all the details about mentioned attributes - and much more.