I am new to javascript and am having an issue repositioning animated text as the string length varies. I have an SVG element and a string within it, where that string needs to be centered within that SVG. Using ' | ' as a center reference, the centering would look like:
| | |
g g g g g g
If I start the animation with a str of len 3, it will be centered properly for Len 3 strs, but then other lens would be equivalent to:
| |
g g g
Example code:
function animateValue(obj, start, end, duration) {
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
const str = obj.innerHTML;
// console.log(`${str.length}` );
if (`${str.length}`==="1"){
obj.style.x = '200px';
}
obj.innerHTML = Math.floor(progress * (end - start) start);
if (progress < 1) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}
const obj = document.getElementById("heading");
animateValue(obj, 100, 0, 5000);
svg {
position: absolute ;
width: 40%;
border: 1px solid rgba(255,255,255,0.3);
margin-left: 30%;
border-radius: 50%;
}
#roseline, #majline {
stroke: #eee;
stroke-width: .5;
}
text {
font-family: Montserrat, sans-serif;
font-size: 10;
fill: #eee;
}
text.heading1{
font-size:4.5em;
fill: #0ee;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500" id="compassrose">
<defs>
<symbol>
<line x1="40" y1="250" x2="50" y2="250" id="roseline" />
<line x1="40" y1="250" x2="60" y2="250" id="majline" />
<path d="M10,250a240,240 0 1,0 480,0a240,240 0 1,0 -480,0" id="rosecircle" transform='rotate(90 250 250)' />
</symbol>
</defs>
<div >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500" id="compassrose">
<polygon points="250,40 280,0 220,000" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500" >
<polygon points="0,260 0,220 40,240" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500" >
<polygon points="500,260 500,220 460,240" />
<text id="heading" x='190px' y='250px'
fontSize="36">100 </text>
</svg>
</div>
</svg>
I have tried re-arranging the divs to allow for the absolute and relative positioning, however that was not properly maintaining size relationships as needed.
CodePudding user response:
If you use dominant-baseline="middle" text-anchor="middle"
on the text element and position it in the middle of the SVG (250,250) it should work.
function animateValue(obj, start, end, duration) {
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
obj.innerHTML = Math.floor(progress * (end - start) start);
if (progress < 1) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}
const obj = document.getElementById("heading");
animateValue(obj, 200, 0, 5000);
svg {
display: block;
position: absolute;
width: 40%;
border: 1px solid rgba(255, 255, 255, .3);
margin-left: 30%;
border-radius: 50%;
}
#roseline,
#majline {
stroke: #eee;
stroke-width: .5;
}
text {
font-family: Montserrat, sans-serif;
font-size: 10;
fill: #eee;
}
text.heading1 {
fill: #0ee;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500" id="compassrose">
<defs>
<symbol>
<line x1="40" y1="250" x2="50" y2="250" id="roseline" />
<line x1="40" y1="250" x2="60" y2="250" id="majline" />
<path d="M10,250a240,240 0 1,0 480,0a240,240 0 1,0 -480,0"
id="rosecircle" transform='rotate(90 250 250)' />
</symbol>
</defs>
<polygon points="250,40 280,0 220,000" />
<polygon points="0,260 0,220 40,240" />
<polygon points="500,260 500,220 460,240" />
<text id="heading" x="250" y="250" font-size="60"
dominant-baseline="middle" text-anchor="middle">100</text>
</svg>