htmlsvgsvg-animate

SVG animation height


I tried doing a height animation so the bars from my diagram go from 100% height to 30% and then back to 100%. I thought i could just do it with the attribute "height" but apparently not. Its not working at all and not doing anything so obviously i did do something wrong. I am not sure what to use instead.

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1276.9 806.1">
  <defs>
    <style>
      .cls-1 {
        fill: #bcbcbc;
      }
    </style>
  </defs>
  <!-- Generator: Adobe Illustrator 28.7.1, SVG Export Plug-In . SVG Version: 1.2.0 Build 142)  -->
  <g>
    <g id="Ebene_1">
      <g id="diagramm_balken">
        <path id="achsen" class="cls-1" d="M944.6,722H313.4c-10.3,0-18.9-8.6-18.9-18.9V71.9c0-10.3,8.6-18.9,18.9-18.9s18.9,8.6,18.9,18.9v612.3h612.3c10.3,0,18.9,8.6,18.9,18.9s-8.6,18.9-18.9,18.9Z"/>
        <path class="cls-1" d="M389.1,422.6h52.4c12.8,0,23.2,10.3,23.2,22.9v233.5c0,12.7-10.4,22.9-23.2,22.9h-52.4c-12.8,0-23.2-10.3-23.2-22.9v-233.5c0-12.7,10.4-22.9,23.2-22.9Z">
          <animate
      attributeName="height"
      attributeType="XML"
      dur="4s"
      values="30;100;30"
      repeatCount="indefinite"/>
        </path>
        <path class="cls-1" d="M531.7,305.1h52.4c12.8,0,23.2,10.4,23.2,23.3v351.1c0,12.9-10.4,23.3-23.2,23.3h-52.4c-12.8,0-23.2-10.4-23.2-23.3v-351.1c0-12.9,10.4-23.3,23.2-23.3Z">
           <animate
      attributeName="height"
      attributeType="XML"
      dur="4s"
      values="30;100;30"
      repeatCount="indefinite"/>
    </path>
        <path class="cls-1" d="M674.4,226h52.4c12.8,0,23.2,10.2,23.2,22.9v432.7c0,12.6-10.4,22.9-23.2,22.9h-52.4c-12.8,0-23.2-10.2-23.2-22.9V248.9c0-12.6,10.4-22.9,23.2-22.9Z">
           <animate
      attributeName="height"
      attributeType="XML"
      dur="4s"
      values="30;100;30"
      repeatCount="indefinite"/>
    </path>
        <path class="cls-1" d="M816.5,127.9h52.4c12.8,0,23.2,10.3,23.2,23v529.9c0,12.7-10.4,23-23.2,23h-52.4c-12.8,0-23.2-10.3-23.2-23V150.9c0-12.7,10.4-23,23.2-23Z">
           <animate
      attributeName="height"
      attributeType="XML"
      dur="4s"
      values="30;100;30"
      repeatCount="indefinite"/>
    </path>
      </g>
    </g>
  </g>
</svg>

I then tried it with scale but the rectangles move way down and look just wrong. I mean somehow its kinda working but its not from use when its going further down than where the diagram ends.

I appreciate any help :))

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1276.9 806.1">
  <defs>
    <style>
      .cls-1 {
        fill: #bcbcbc;
      }
    </style>
  </defs>
  <!-- Generator: Adobe Illustrator 28.7.1, SVG Export Plug-In . SVG Version: 1.2.0 Build 142)  -->
  <g>
    <g id="Ebene_1">
      <g id="diagramm_balken">
        <path id="achsen" class="cls-1" d="M944.6,722H313.4c-10.3,0-18.9-8.6-18.9-18.9V71.9c0-10.3,8.6-18.9,18.9-18.9s18.9,8.6,18.9,18.9v612.3h612.3c10.3,0,18.9,8.6,18.9,18.9s-8.6,18.9-18.9,18.9Z"/>
        <path class="cls-1" d="M389.1,422.6h52.4c12.8,0,23.2,10.3,23.2,22.9v233.5c0,12.7-10.4,22.9-23.2,22.9h-52.4c-12.8,0-23.2-10.3-23.2-22.9v-233.5c0-12.7,10.4-22.9,23.2-22.9Z">
          <animateTransform  
        attributeType="xml"
        attributeName="transform" 
        type="scale"
        values="1,1; 1,3; 1,1"
        begin="0.4s" 
        dur="4s" 
        repeatCount="indefinite" />
        </path>
        <path class="cls-1" d="M531.7,305.1h52.4c12.8,0,23.2,10.4,23.2,23.3v351.1c0,12.9-10.4,23.3-23.2,23.3h-52.4c-12.8,0-23.2-10.4-23.2-23.3v-351.1c0-12.9,10.4-23.3,23.2-23.3Z">
           <animateTransform  
        attributeType="xml"
        attributeName="transform" 
        type="scale"
        values="1,1; 1,3; 1,1"
        begin="0.4s" 
        dur="4s" 
        repeatCount="indefinite" />
    </path>
        <path class="cls-1" d="M674.4,226h52.4c12.8,0,23.2,10.2,23.2,22.9v432.7c0,12.6-10.4,22.9-23.2,22.9h-52.4c-12.8,0-23.2-10.2-23.2-22.9V248.9c0-12.6,10.4-22.9,23.2-22.9Z">
           <animateTransform  
        attributeType="xml"
        attributeName="transform" 
        type="scale"
        values="1,1; 1,3; 1,1"
        begin="0.4s" 
        dur="4s" 
        repeatCount="indefinite" />
    </path>
        <path class="cls-1" d="M816.5,127.9h52.4c12.8,0,23.2,10.3,23.2,23v529.9c0,12.7-10.4,23-23.2,23h-52.4c-12.8,0-23.2-10.3-23.2-23V150.9c0-12.7,10.4-23,23.2-23Z">
           <animateTransform  
        attributeType="xml"
        attributeName="transform" 
        type="scale"
        values="1,1; 1,3; 1,1"
        begin="4s" 
        dur="4s" 
        repeatCount="indefinite" />
      </path>
      </g>
    </g>
  </g>
</svg>


Solution

  • <path> elements don't have a height property/attribute.

    As commented by Michael Mullany you're better off rebuilding the graphs manually in SVG code. Just because graphic applications tend to export rather convoluted SVG markup that's hard to manipulate when coding something like animations.

    Find a suitable SVG element for animation

    As always, it depends on your requirements – check out the candidates:

    <svg viewBox="0 0 100 100">
    
      <style>
        .rect {
          fill: #ccc;
          /* flip graphs */
          transform: scale(1, -1);
          /* define axis origin as transforms-origin referance point */
          transform-origin: 0 80px;
          width: 10px;
          animation: 1s graphAni forwards alternate infinite ease-in-out;
        }
    
        .delay0 {
          animation-delay: 0.25s;
        }
    
        .delay1 {
          animation-delay: 0.5s;
        }
    
        .delay2 {
          animation-delay: 0.75s;
        }
    
        .delay3 {
          animation-delay: 1s;
        }
    
        @keyframes graphAni {
          to {
            height: 0px;
          }
        }
      </style>
      <!-- x/y axis -->
      <path d="M 17.5 20 v60 h65" stroke="#ccc" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
      <!-- graphs -->
      <rect class="rect delay0" x="25" y="80" rx="2.5" height="20" />
      <rect class="rect delay1" x="40" y="80" rx="2.5" height="30" />
      <rect class="rect delay2" x="55" y="80" rx="2.5" height="40" />
      <rect class="rect delay3" x="70" y="80" rx="2.5" height="50" />
    </svg>

    Basically, we just flip the graph rendering via transform: scale(1, -1) so we can increase/decrease the height value during animation. We also need to set a transform origin as a reference point – which would be the graph axis origin. Here's an example how it looks without transformations:

    svg {
      width: 50vmin;
      display: block;
      outline: 1px solid #ccc;
      overflow: visible;
    }
    <svg viewBox="0 0 100 100">
    
      <style>
        .rect {
          fill: red;
          /* define axis origin as transforms-origin referance point */
          transform-origin: 0 80px;
          width: 10px;
          animation: 1s graphAni forwards alternate infinite ease-in-out;
        }
    
        .delay0 {
          animation-delay: 0.25s;
        }
    
        .delay1 {
          animation-delay: 0.5s;
        }
    
        .delay2 {
          animation-delay: 0.75s;
        }
    
        .delay3 {
          animation-delay: 1s;
        }
    
        @keyframes graphAni {
          to {
            height: 0px;
          }
        }
      </style>
      <!-- x/y axis -->
      <path d="M 17.5 20 v60 h65" stroke="#ccc" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
      <!-- graphs -->
      <rect class="rect delay0" x="25" y="80" rx="2.5" height="20" />
      <rect class="rect delay1" x="40" y="80" rx="2.5" height="30" />
      <rect class="rect delay2" x="55" y="80" rx="2.5" height="40" />
      <rect class="rect delay3" x="70" y="80" rx="2.5" height="50" />
    </svg>

    Also, we may not need different initial height values but instead rely on animation delays to get a "stepped" graph rendering.