Search code examples
svgsvg-animate

How can I make a SVG element to move on the path?


I want to move a rect along a path. Therefore I translated the rect so that it's position is the begin of the path. But when I start the animation the rect the translation is interpreted relative to the path. Thus the rect moves with the translation offset along the path.

Here is an example:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600px"
    height="400px">
    <defs />
    <path id="path" d="M 100 100 L 100 15 L 500 15 L 500 150" fill="none" stroke="#000000" stroke-width="3"
      stroke-miterlimit="10" pointer-events="none" />
    <g transform="translate(50,75)">
      <rect height="50" width="100" fill="#FDD34D" rx="10" stroke-width="1px" stroke="#000000">
      </rect>
      <text x="15" y="28">Click me !</text>
      <animateMotion id="move" dur="4.6s" begin="click">
        <mpath xlink:href="#path" />
      </animateMotion>
    </g>
  </svg>

How can I make the rect to move on the path?

EDIT

I'm looking for a solution that works with multiple different paths. E.g.

  <svg viewBox="-100 -130 700 400">
    <defs />
    <path id="path" d="M 0 0 L 0 -90 L 500 -90 L 500 150" fill="none" stroke="#ff0000" stroke-width="3"
      stroke-miterlimit="10" pointer-events="none" />

    <path id="path2" d="M 150 0 L 150 90 L -50 90 L -50 150" fill="none" stroke="#ff0000" stroke-width="3"
      stroke-miterlimit="10" pointer-events="none" />
    <g>
      <rect height="50" width="100" x="-50" y="-25" fill="#FDD34D" rx="10" stroke-width="1px" stroke="#000000" />
      <text text-anchor="middle" dominant-baseline="middle">Click me !</text>
      <animateMotion id="move" dur="4.6s" begin="click">
        <mpath xlink:href="#path" />
      </animateMotion>
    </g>

    <g>
      <rect height="50" width="100" x="100" y="-25" fill="#FDD34D" rx="10" stroke-width="1px" stroke="#000000" />
      <text text-anchor="middle" x="150" dominant-baseline="middle">Click me !</text>
      <animateMotion id="move" dur="4.6s" begin="click">
        <mpath xlink:href="#path2" />
      </animateMotion>
    </g>
  </svg>


Solution

  • The main idea is to have the text and the rectangle centered around the point x=0, y=0

    <svg  viewBox="-100 -130 700 400">
        <defs />
        <path id="path" d="M 0 0 L 0 -90 L 500 -90 L 500 150" fill="none" stroke="#ff0000" stroke-width="3"
          stroke-miterlimit="10" pointer-events="none" />
       <g>
          <rect height="50" width="100" x="-50" y="-25" fill="#FDD34D" rx="10" stroke-width="1px" stroke="#000000"/>    
          <text text-anchor="middle" dominant-baseline="middle">Click me !</text>
          <animateMotion id="move" dur="4.6s" begin="click">
            <mpath xlink:href="#path" />
          </animateMotion>
        </g>
      </svg>