Search code examples
animationsvgmathematical-morphology

How to morph a path data to another path data in SVG?


I'm trying to figure out why it wont morph this path data to another path data, I need to make it look like an real animation.

This is my SMIL code:

    <animate xlink:href="#Barra3"  
    repeatCount="indefinite" 
    attributeName="d" 
    dur="5s"
    values="M52,346L56,346C61.523,346 66,350.477 66,356L42,356C42,350.477 46.477,346 52,346Z;
    M54,225C60.627,225 66,230.373 66,237L66,356L42,356L42,237C42,230.373 47.373,225 54,225Z;"/>

Here is my codepen:

https://codepen.io/joannesalfa/pen/mdPBJxq and go line 181. I'm using SMIL.


Solution

  • The most important when trying to morph a path in svg is thast the d attribute hes to have the same number of commands and the same commands. I've rewritten the short path so that the lines drawing the sides of the shape have a length = 0.

    M54,346
    C60.627,346,66,351.373,66,358
    L66,358L42,358L42,358
    C42,351.373,47.373,346,54,346Z

    Please take a look:

    svg{border:solid}
    <svg viewBox="5 200 100 200" width="100">
    
    
      <path d="M54,346
              C60.627,346,66,351.373,66,358
              L66,358L42,358L42,358
              C42,351.373,47.373,346,54,346Z"  stroke="red" fill="gold" >
    
      <animate  dur='5s'
        attributeType="XML"
        attributeName='d'      
        repeatCount='indefinite'
               values="M54,225
               C60.627,225 66,230.373 66,236
               L66,356L42,356L42,236
               C42,230.373 47.373,225 54,225Z;
                                                                         
               M54,346
               C60.627,346,66,351.373,66,356
               L66,356L42,356L42,356
               C42,351.373,47.373,346,54,346Z;
                                                                                      M54,225
               C60.627,225 66,230.373 66,236
               L66,356L42,356L42,236
               C42,230.373 47.373,225 54,225Z" />
        
        </path>
    </svg>

    Update

    The OP is commenting:

    Would you mind how to rewrite the short path step by step? I find it's very confusing to me

    I'm taking both those paths and I'm breaking them in 5 paths of different colors, one for every command. Please note that I had to add a move to command (M) at the beginning of each path. The value for the move to is the last point of the previous path. The lines, are the blue paths.

    For the short path you can see those blue paths in the code but not in the svg because their length is 0. I needed those 0 length lines because you have lines in the long path.

    svg{width:200px;border:solid;overflow:visible; fill:none}
    <svg viewBox="40 220 28 140" >
      <desc>The short path</desc>
      <path d="M54,346 C60.627,346,66,351.373,66,356" stroke="red" /> 
      <path d="M66,356 L66,356" stroke="blue" />           
      <path d="M66,356 L42,356" stroke="green" />    
      <path d="M42,356 L42,356" stroke="blue" /> 
      <path d="M42,356 C42,351.373,47.373,346,54,346" stroke="gold"/>
    
    </svg>
    
    <svg viewBox="40 220 28 140" >
      <desc>The long path</desc>
          <path d="M54,225 C60.627,225 66,230.373 66,237" stroke="red"/> 
          <path d="M66,237 L66,356" stroke="blue" />
          <path d="M66,356 L42,356" stroke="green" />  
          <path d="M42,356 L42,237" stroke="blue"/>
          <path d="M42,237 C42,230.373 47.373,225 54,225;" stroke="gold"/>
    
    </svg>