随着 str 长度的变化重新居中文本位置

Re-Center text position as str length changes

我是 javascript 的新手,随着字符串长度的变化,我在重新定位动画文本时遇到了问题。我有一个 SVG 元素和一个字符串,其中该字符串需要在该 SVG 中居中。使用 ' | ' 作为中心参考,居中看起来像:

   |      |      |
 g g g   g g     g

如果我以 len 3 的 str 开始动画,它将正确居中 Len 3 strs,但其他镜头将等效于:


  |     |
g g   g 

示例代码:

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 class="triangle-container">
                <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" class="triangle" />

            </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 class="heading1" id="heading"  x='190px' y='250px'
      fontSize="36">100 </text>

              </svg>


    </div>

</svg>

我已经尝试重新排列 div 以允许绝对和相对定位,但是这并没有根据需要正确地保持大小关系。

如果您在文本元素上使用 dominant-baseline="middle" text-anchor="middle" 并将其放置在 SVG (250,250) 的中间,它应该可以工作。

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" class="triangle" />
  <polygon points="0,260 0,220 40,240" />
  <polygon points="500,260 500,220 460,240" />
  <text class="heading1" id="heading"  x="250" y="250" font-size="60"
    dominant-baseline="middle" text-anchor="middle">100</text>
</svg>