I have a text that is wrapping around an SVG circle which is scaling depending on window size – thanks to user enxaneta https://stackoverflow.com/a/56036245/10727821. I want to animate the text so that it would be revolving around the center like a marquee. For this, my code currently looks like this:
<div id="wrap">
<svg id="ellipse" version="1.1" viewBox="0 0 1000 1000" preserveAspectRatio="none">
<path id="thePath" fill="transparent" d="M100,500A400,400 0 0 0 900 500 A400,400 0 0 0 100 500" />
<text stroke="black" font-size="20">
<textPath xlink:href="#thePath" dy="5" id="tp">
Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon •
Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon •
Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon • Coming Soon •
</textPath>
</text>
</svg>
</div>
<script>
function Init(){
let wrap = document.getElementById('wrap');
let thePath = document.getElementById('thePath');
let ellipse = document.getElementById('ellipse');
let w = wrap.clientWidth;
let h = wrap.clientHeight;
ellipse.setAttributeNS(null,"viewBox",`0 0 ${w} ${h}`);
let d = `M${w/10},${h/2}A${4*w/10},${4*h/10} 0 0 0 ${9*w/10} ${5*h/10} A${4*w/10},${4*h/10} 0 0 0 ${w/10} ${5*h/10}`
thePath.setAttributeNS(null,"d", d)
}
window.setTimeout(function() {
Init();
window.addEventListener('resize', Init, false);
}, 15);
let so = 0
function Marquee(){
let tp = document.getElementById('tp');
requestAnimationFrame(Marquee)
tp.setAttributeNS(null,"startOffset",so+"%");
if(so >= 50){so = 0;}
so+= .05
}
Marquee()
</script>
This is working well, except the text gets "swallowed" at the end of the curve (see attached image). I'd like to have it make a full rotation without any interruption. I have tried changing the so
variable to a negative value, but this ends up in the text being too far offset so it would only slowly creep onto the page. I was thinking to prepend a text fragment after a certain time, but this wouldn't take into account the startOffset
movement and would probably not work…
Thankful for any hints, also those using JS libraries or plugins!
The main idea is that the path has to coil twice. And when the
startOffset
is at 50% you make it 0. Also because the length of the path is changing when you resize the window you need to recalculate the font-size. I hope it helps.UPDATE
The OP is commenting:
One easy fix would be setting the attribute
textLength
equal to the length of the path divided by 2 (since the path is coiling twice - is twice as long as it should be). Also you need tu uselengthAdjust="spacingAndGlyphs"
that is controlling how the text is stretched or compressed into that length.You may also need to add/remove some
Coming Soon •
if the text becomes too stretched / squished.UPDATE 2
Apparently the last solution do not work on Firefox. This is another solution to this problem.
Initially I'm setting the font size much bigger than needed. Next I check if the text length is bigger than half path length, and if so I'm reducing the font size. I'm doing this in a while loop: