Victor Westerlund
Victor Westerlund

Reputation: 100

SVG transformation from path to another

So I have this SVG animation I'm trying to make work, I made a quick smaller version of the real image below to explain what I'm trying to do.

The biggest issue I faced was making the <line> elements "follow" the position of the <path> or even <circle> elements.

This is the first stage of the animation

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 82">
  <defs>
    <style>
      .cls-1 {
        fill: none;
        stroke: #000;
        stroke-miterlimit: 10;
        stroke-width: 2px;
      }
    </style>
  </defs>
  <title>Untitled-5</title>
  <path d="M107,94a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-95 -34)"/>
  <path d="M139,36a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-95 -34)"/>
  <path d="M207,69a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-95 -34)"/>
  <line class="cls-1" x1="38" y1="21" x2="17" y2="61"/>
  <line class="cls-1" x1="54" y1="16" x2="102" y2="40"/>
</svg>

Then after a few seconds I want it to smoothly animate to the positions of this next SVG. After that it should just smootly alternate between the two.

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 112 68">
  <defs>
    <style>
      .cls-1 {
        fill: none;
        stroke: #000;
        stroke-miterlimit: 10;
        stroke-width: 2px;
      }
    </style>
  </defs>
  <title>Untitled-5</title>
  <path d="M104,53A10,10,0,1,1,94,63a10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-92 -28)"/>
  <path d="M151,74a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-92 -28)"/>
  <path d="M192,30a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-92 -28)"/>
  <line class="cls-1" x1="49" y1="52" x2="22" y2="39"/>
  <line class="cls-1" x1="66" y1="48" x2="92" y2="20"/>
</svg>

Thanks in advance for help!

Upvotes: 1

Views: 934

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101800

Trying to animate lines that connect the edges of the circles is going to be quite hard with SMIL animation. The endpoints will take non-linear paths across the screen.

However if you change the lines so that they connect the centre of the circles, things get a lot simpler. To hide the parts of the lines that are inside the circles, you can just move them behind the circles, and then give the circles a solid fill. Or you could use a circle mask to hide the extended lines, if you really need transparent circles.

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 82">
  <defs>
    <style>
      .cls-1 {
        fill: none;
        stroke: #000;
        stroke-miterlimit: 10;
        stroke-width: 2px;
      }
    </style>
  </defs>
  <title>Untitled-5</title>
  <line class="cls-1" x1="12" y1="70" x2="44" y2="12">
    <animate attributeName="y1" from="70" to="35" dur="2s" fill="freeze"/>
    <animate attributeName="x2" from="44" to="59" dur="2s" fill="freeze"/>
    <animate attributeName="y2" from="12" to="56" dur="2s" fill="freeze"/>
  </line>
  <line class="cls-1" x1="44" y1="12" x2="112" y2="45">
    <animate attributeName="x1" from="44" to="59" dur="2s" fill="freeze"/>
    <animate attributeName="y1" from="12" to="56" dur="2s" fill="freeze"/>
    <animate attributeName="x2" from="112" to="100" dur="2s" fill="freeze"/>
    <animate attributeName="y2" from="45" to="12" dur="2s" fill="freeze"/>
  </line>
  <circle cx="12" cy="70" r="11" fill="white" stroke="black" stroke-width="2">
    <animate attributeName="cy" from="70" to="35" dur="2s" fill="freeze"/>
  </circle>
  <circle cx="44" cy="12" r="11" fill="white" stroke="black" stroke-width="2">
    <animate attributeName="cx" from="44" to="59" dur="2s" fill="freeze"/>
    <animate attributeName="cy" from="12" to="56" dur="2s" fill="freeze"/>
  </circle>
  <circle cx="112" cy="45" r="11" fill="white" stroke="black" stroke-width="2">
    <animate attributeName="cx" from="112" to="100" dur="2s" fill="freeze"/>
    <animate attributeName="cy" from="45" to="12" dur="2s" fill="freeze"/>
  </circle>
</svg>

Upvotes: 2

Related Questions