проблема с покачиванием(встряхиванием) текста svg во время анимации преобразования

#html #css #svg

Вопрос:

Во время анимации преобразования текст начинает дрожать, после исследования я понял, что это зависит от окна просмотра контейнера. Если окно просмотра маленькое, то мы видим, что текст дрожит, если окно просмотра большое, текст не начинает дрожать, и анимация проходит гладко.

Пример небольшого окна просмотра:

 const groupList = document.querySelectorAll("svg g");
const container = document.querySelector("#container");

const containerViewport = [20,20];
// const containerViewport = [100,100];

container.style.width = `${containerViewport[0]}%`;
container.style.height = `${containerViewport[1]}%`;

// cannot change this
const increaseRatio = 0.1;

const values = [
    30, 70, 110
]

for (const [key, node] of groupList.entries()) {
    node.setAttribute("transform", `translate(29, ${values[key]})`)
}

setInterval(()=>{
    for (const [key, node] of groupList.entries()) {
        values[key] = values[key]   increaseRatio;
        node.setAttribute("transform", `translate(29, ${values[key]})`)
    }
},20) 
  .tick {
    color: #fff;
}
.line {
    stroke: #fff;
} 
 <div style="background: gray;" id="container">
    <svg width="100%" height="100%" viewBox="0 0 411 252" xmlns="http://www.w3.org/2000/svg">
        <g>
            <text x="0" y="-10" style="" class="tick">15</text>
            <line x1="0" y1="0" x2="381" y2="0" class="line"></line>
        </g>
        <g>
            <text x="0" y="-10" style="" class="tick">10</text>
            <line x1="0" y1="0" x2="381" class="line" y2="0"></line>
        </g>
        <g>
            <text x="0" y="-10" style="" class="tick">5</text>
            <line x1="0" y1="0" x2="381" class="line" y2="0"></line>
        </g>
    </svg>
</div> 

Пример большого окна просмотра:

 const groupList = document.querySelectorAll("svg g");
const container = document.querySelector("#container");

// const containerViewport = [20,20];
const containerViewport = [100,100];

container.style.width = `${containerViewport[0]}%`;
container.style.height = `${containerViewport[1]}%`;

// cannot change this
const increaseRatio = 0.1;

const values = [
    30, 70, 110
]

for (const [key, node] of groupList.entries()) {
    node.setAttribute("transform", `translate(29, ${values[key]})`)
}

setInterval(()=>{
    for (const [key, node] of groupList.entries()) {
        values[key] = values[key]   increaseRatio;
        node.setAttribute("transform", `translate(29, ${values[key]})`)
    }
},20) 
  .tick {
    color: #fff;
}
.line {
    stroke: #fff;
} 
 <div style="background: gray;" id="container">
    <svg width="100%" height="100%" viewBox="0 0 411 252" xmlns="http://www.w3.org/2000/svg">
        <g>
            <text x="0" y="-10" style="" class="tick">15</text>
            <line x1="0" y1="0" x2="381" y2="0" class="line"></line>
        </g>
        <g>
            <text x="0" y="-10" style="" class="tick">10</text>
            <line x1="0" y1="0" x2="381" class="line" y2="0"></line>
        </g>
        <g>
            <text x="0" y="-10" style="" class="tick">5</text>
            <line x1="0" y1="0" x2="381" class="line" y2="0"></line>
        </g>
    </svg>
</div> 

Я попытался увеличить окно просмотра svg, но это не имеет значения, текст все еще дрожит.

Видео-демонстрация: https://youtu.be/d_aIIDfCHB0

Комментарии:

1. 0.1 помечено как не изменяемое — но оно очень мало, и интервал в 20 мс тоже довольно мал (если подумать о том, сколько кадров может быть нарисовано за секунду). Есть ли у вас CSS-анимации, которые могут добавить больше на графический процессор, и есть ли причина, по которой 0.1 не разрешается изменять. Возможно, вы получаете ошибки округления, когда пиксели устройства и пиксели CSS пытаются совпасть.