Home > database >  Loop SVG text animation around rectangle path
Loop SVG text animation around rectangle path

Time:05-03

I am using SVG to animate text around the path of a rounded rectangle. The idea is to have a stream of text that is constantly moving around the rectangle.

Here's an example of the rectangle animation in this tutorial video for After Effects

But when closing the SVG path for the text, the animation does not run at all and if I leave the path open the text disappears as it reaches the end as in this code snippet:

html, body {
  background: black;
  margin: 0 auto;
}

.container {
  widht: 100%;
  background: red;
}

.svgwave {
  margin-left: calc(50% - 150px);
  margin-top: 100px;
}
<div >
            <svg  xmlns="http://www.w3.org/2000/svg" width="301" height="301" viewBox="0 0 301 301" style="width:auto; height: auto; overflow: visible;">
                <path id="wavepath" d="M145.5 301.5H13C6.09645 301.5 0.5 295.904 0.5 289V13C0.5 6.09645 6.09644 0.5 13 0.5H289C295.904 0.5 301.5 6.09644 301.5 13V289C301.5 295.904 295.904 301.5 289 301.5H156.5" style="fill: transparent; stroke: transparent; stroke-width: 1px;"></path>

                <foreignObject x='6' y='6' width='300px' height='300px'>
                    <div
                    style="width: 282px; height: 282px;
                            border-radius: 8px;
                            background-size: contain;
                            border: 4px solid white;
                            display:inline-block; "
                    ></div>
                </foreignObject>
                <text text-anchor="middle" style="text-transform: uppercase; font-family: Arial; font-size: 20px; fill: white;">
                    <textPath style=" fill-opacity: 1" href="#wavepath" side="left" startOffset="0%">
                    <animate attributeName="startOffset" from="30%" to="42%" begin="0s" dur="4s" repeatCount="indefinite"></animate>
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    </textPath>
                </text>
            </svg>

        </div>

  • What would be the best way to achieve this animation using SVG?
  • Would there be any alternative way to achieve this with Javascript?

CodePudding user response:

If you extend the path and add textLength settings to make sure that the text wraps perfectly - and tweak a few other things you can get this to look better. Still has a tiny seam jitter, but it's not that noticeable.

html, body {
  background: black;
  margin: 0 auto;
}

.container {
  widht: 100%;
  background: red;
}

.svgwave {
  margin-left: calc(50% - 150px);
  margin-top: 100px;
}
            <svg  xmlns="http://www.w3.org/2000/svg" width="301" height="301" viewBox="0 0 301 301" style="width:auto; height: auto; overflow: visible;">
                <path id="wavepath" d="M145.5 301.5H13C6.09645 301.5 0.5 295.904 0.5 289V13C0.5 6.09645 6.09644 0.5 13 0.5H289C295.904 0.5 301.5 6.09644 301.5 13V289C301.5 295.904 295.904 301.5 289 301.5H156.5 H13C6.09645 301.5 0.5 295.904 0.5 289V13C0.5 6.09645 6.09644 0.5 13 0.5H289C295.904 0.5 301.5 6.09644 301.5 13V289C301.5 295.904 295.904 301.5 289 301.5H156.5 H13C6.09645 301.5 0.5 295.904 0.5 289V13C0.5 6.09645 6.09644 0.5 13 0.5H289C295.904 0.5 301.5 6.09644 301.5 13V289C301.5 295.904 295.904 301.5 289 301.5H156.5 H13C6.09645 301.5 0.5 295.904 0.5 289V13C0.5 6.09645 6.09644 0.5 13 0.5H289C295.904 0.5 301.5 6.09644 301.5 13V289C301.5 295.904 295.904 301.5 289 301.5H156.5" style="fill: transparent; stroke: transparent; stroke-width: 1px;" ></path>

                <foreignObject x='6' y='6' width='300px' height='300px'>
                    <div
                    style="width: 282px; height: 282px;
                            border-radius: 8px;
                            background-size: contain;
                            border: 4px solid white;
                            display:inline-block; "
                    ></div>
                </foreignObject>
                <text text-anchor="left" style="text-transform: uppercase; font-family: Arial; font-size: 20px; fill: white;">
                    <textPath style=" fill-opacity: 1" href="#wavepath" side="left" startOffset="0%" textLength="1175">
                    <animate attributeName="startOffset" from="20%" to="42%" begin="0s" dur="12s" repeatCount="indefinite"></animate>
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    First <tspan style="fill: #DED279;">Second</tspan> 
                    </textPath>
                </text>
            </svg>

  • Related