#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 пытаются совпасть.