Search code examples
svgsvg-animate

SVG animation of text values


Is there an SVG animation tag that will allow me to change the content of a text tag?

I have an animation that moves an item alongside a text label and I need the text to update in sync with the animation. I have other features that use the SVG timing system to skip forward and backward, so I explicitly don't want to do this in JavaScript.

Here is some example code that doesn't work because I can't figure out how to express set tags that change text content:

<svg version='1.1' xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='-10 -10 600 400'>
  <g>
     <circle r='80' fill='cyan' cx='90' cy='120'/>
     <text x='98' y='120' fill='black' >
       I am moving
       <set attributeName='content' begin='3s' fill='freeze' to='I am stationary'/>
       <set attributeName='content' begin='5s' fill='freeze' to='I am moving'/>
     </text>
     <animateMotion path='M 0 0 L 100 100' begin='0s' dur='3s' fill='freeze' />
     <animateMotion path='M 100 100 L 0 0' begin='5s' dur='3s' fill='freeze' />
  </g>

When you view this in a browser I'd like to see a moving blue circle with the text "I am moving". When the blue circle pauses it should have the text "I am stationary" for a moment before moving on again. Instead the text change doesn't happen.

I've been reading the SMIL animation documentation; while it's really easy to make my text rotate or change colors, I don't see any way to actually change what a text tag says.


Solution

  • SVG's SMIL is used to animate attributes, not content. Thus, you can not use SMIL to change the <text> element's content. As Robert Longson mentioned in the comments, a possible work around is to use two <text> elements: one for the stationary text and one for the moving text. You could then use SMIL to animate the visibility attribute (or the display attribute) of the two <text> elements so that only one <text> element is visible at a time. For example...

    <svg version='1.1' xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='-10 -10 600 400'>
        <g>
            <circle r='80' fill='cyan' cx='90' cy='120'/>
            <text x='98' y='120' fill='black' visibility="visible">
                I am stationary
                <set attributeName='visibility' begin='0s' dur='3s' to='hidden'/>
                <set attributeName='visibility' begin='5s' dur='3s' to='hidden'/>
            </text>
            <text x='98' y='120' fill='black' visibility="hidden">
                I am moving
                <set attributeName='visibility' begin='0s' dur='3s' to='visible'/>
                <set attributeName='visibility' begin='5s' dur='3s' to='visible'/>
            </text>
            <animateMotion path='M 0 0 L 100 100' begin='0s' dur='3s' fill='freeze' />
            <animateMotion path='M 100 100 L 0 0' begin='5s' dur='3s' fill='freeze' />
        </g>
    </svg>
    

    Note that IE does not support SVG SMIL animations.

    Note that Chrome has deprecated support for SVG SMIL animations and could remove support in the future. When using SVG SMIL animations in Chrome, you will see a warning message in the developer's console.