devaent
devaent

Reputation: 449

How do I get SVG textPath to work with animated path?

Please view the demo here: https://codepen.io/bsoutendijk/pen/gOvLMaq

Expected behavior: After clicking "update path" button, the path will change, and the text will appear along the path by the end of the animation.

Actual behavior: The text appears correctly on the path upon load, but when clicking update path, the text does not appear in the correct place.

code:

const path = document.getElementById('myPath');
const button = document.getElementById('myButton');

button.addEventListener('click', () => {
  console.log('clicked!');
  path.setAttribute('d', getRandomCurve()); 
})

function getRandomCurve() {
  const curveSize = Math.round(Math.random() * 300);
  
  return `M 100 350 q ${curveSize} -300 300 0`
}
#myPath {
  transition: all ease-out 2s;
}
<div>
  <button id="myButton">Update Path</button>
  <svg height="400" width="450">
    <path id="myPath" d="M 100 350 q 150 -300 300 0" stroke="blue" stroke-width="5" fill="none" />
    <text style="font-size: 2em;">
      <textPath startOffset="30%" text-anchor="middle" href="#myPath">
        Hello World
      </textPath>
    </text>
  </svg>
</div>

How do I use textPath in a way that it can work with animated paths?

Upvotes: 0

Views: 160

Answers (1)

Pete Pearl
Pete Pearl

Reputation: 341

const path = document.getElementById("myPath2");

function getRandomCurve() {
    const curveSize = Math.round(Math.random() * 300);

    return `M 100 350 q ${curveSize} -300 300 0`;
}

setInterval(() => {
    const pathDef = getRandomCurve();
    path.setAttribute("d", pathDef);
}, 1000)
.anim {
            transition: 1s;
        }
<div>
    <svg height="400" width="450">
    <path id="myPath2" class="anim" d="M 100 350 q 150 -300 300 0" stroke="blue" stroke-width="5" fill="none" />
    <text x="0" y="0" style="font-size: 2em;">
        <textPath startOffset="30%" href="#myPath2" class="anim">
            Hello World
            <animateTransform attributeName="transform"  dur="2s" repeatCount="indefinite"/>
        </textPath>
    </text>
</svg>
</div>

Oh, i can do it :)

"animateTransform" can fix your problem. "repeatCount" - important attribute, try to remove it and your animation will stop after "dur"

Upvotes: 2

Related Questions