我尝试使用一个字幕效果与香草JS。效果的作品,但svg(和图像)是抖动的移动。
<div class="marquee">
<h1>Nepal <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Himalayas <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Mountains <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Everest</h1>
</div>
<style>
.marquee {
overflow: hidden;
border-top: 1px solid #000;
border-bottom: 1px solid #000;
display: flex;
}
.marquee h1{
font-size: 5em;
white-space: nowrap;
text-transform: uppercase
}
.marquee h1 svg {
width: auto;
height: 60px;
}
</style>
<script>
function Marquee(selector, speed) {
const parentSelector = document.querySelector(selector);
const clone = parentSelector.innerHTML;
const firstElement = parentSelector.children[0];
let i = 0;
console.log(firstElement);
parentSelector.insertAdjacentHTML('beforeend', clone);
parentSelector.insertAdjacentHTML('beforeend', clone);
setInterval(function () {
firstElement.style.marginLeft = `-${i}px`;
if (i > firstElement.clientWidth) {
i = 0;
}
i = i + speed;
}, 0);
}
//after window is completed load
//1 class selector for marquee
//2 marquee speed 0.2
window.addEventListener('load', Marquee('.marquee', 0.2))
</script>
示例:https://codepen.io/diegosomar/pen/dyKBGWg
有人知道是否有一种方法可以防止svg抖动?
2条答案
按热度按时间fcy6dtqo1#
将
setInterval()
替换为requestAnimationFrame()
正如@Jefferson的回答中指出的,您当前的
setInterval()
调用具有零毫秒延迟,导致动画/过渡抖动。此外,它会导致不一致的计时,例如在Firefox和Chromium中。
requestAnimationFrame()
确保,您的样式更改每帧应用一次-然而,setInterval()
可能会尝试在”帧之间“更改样式属性(如果以毫秒为单位的间隔与帧不匹配)。示例代码段
动画首选整数值-如果可行
按浮点数字递增样式属性可能会导致舍入错误-也会导致不希望的抖动过渡和性能问题。
这也适用于本文中描述的svgs。
ycggw6v22#
如果您将间隔设置为100 ms更新,如下所示:
你会清楚地看到发生了什么。不仅图像会抖动,单个字母也会抖动。这种抖动效果似乎是浏览器(至少是Chrome)渲染图像/字母的方式。
但是,我在查看CSS时注意到一些问题,当我将宽度更改为
width: 70px
时,“抖动”似乎停止了(我选择70 px是因为它更接近于最初的心脏图像大小)当我在Inspector上检查HeartSVG元素时,我发现当宽度设置为width: auto
时,与width: 70px
相比,宽度的变化过程有延迟,这使得它看起来抖动更大。使用固定的
width
像素大小是解决这个问题的一个很好的方法,但是有一个更好更简单的方法可以解决这个问题。不用每毫秒修改一次
margin-left
,你可以每秒修改一次,让CSS来处理平滑过渡,你可以在这里了解CSS transitions。通过在
.marquee h1
样式中添加transition
,您可以立即看到不同之处。注意,您可能希望在i = 0
之后处理transition
,以防止从-2000px(firstElement.clientWidth
大小)突然平滑跳变到0 px。