繁体   English   中英

选框文字效果。 无论文本长度如何,滚动速度相同

[英]Marquee text effect. Same scrolling speed no matter the length of the text

我的网站上有一个类似于选取框的元素,它从屏幕的右侧滑到左侧。 html 看起来像这样:

<div class='text-scroller-container'>
    <p class='message'></p>
</div>

滚动条内可以有许多不同的消息。 有些范围从一个单词到一个完整的句子。

我处理滚动的方式是设置left: 100%并添加一个transition: left 5s 然后在js中将left设置为0。

我现在面临的问题是超短消息滚动非常慢,而非常长消息滚动快速,因为它们都绑定到5s transition duration

我确定有一种方法可以计算相对于元素offsetWidth的速度,以便无论消息的长度如何,它都以大致相同的速度滚动。

我最初的解决方案是使用setInterval/requestAnimationFrame并一次移动元素 1px 直到其宽度完全离开屏幕。 但是,我现在需要提高我的 web 应用程序的性能,所以我要切换回使用过渡。

这个事情谁有经验?

这听起来更像是 animation,而不是过渡。 当 state 发生变化时,转换只运行一次,而 animation 可以永远循环,从而产生选框效果。

您需要的是一个 animation 循环。 您可以使用CSS Keyframes来做到这一点。 使用它,您可以指定开始和结束 state,然后无限循环这些状态。

现在这里的问题是速度。 需要计算速度。 CSS 不能这样做,所以我们需要添加一些 JavaScript 来解决这个问题。

速度的计算是amount of pixels per second * (width of message + container width) 所以在一段时间内行进的距离乘以距离。 消息越大,持续时间越长。

下面的示例显示了三个选框,每个选框都有不同长度的不同消息。 JavaScript 循环遍历每条消息,进行计算,并为每条消息设置animationDuration持续时间(以毫秒为单位)。

 /** * The speed in time (in milliseconds) of a single pixel. * Changing this value will change the speed. * @type {number} */ const timePerPixel = 20; /** * Width of the container. * Hardcoded for simplicity' sake. * @type {number} */ const containerWidth = 200; /** * Select all the messages * @type {NodeList} */ const messages = document.querySelectorAll('.message'); /** * For each message, calculate the duration based on the lenght of the message. * Then set the animation-duration of the animation. */ messages.forEach(message => { const messageWidth = message.offsetWidth; const distance = messageWidth + containerWidth; const duration = timePerPixel * distance; message.style.animationDuration = `${duration}ms`; });
 .text-scroller-container { position: relative; width: 200px; height: 20px; border: 1px solid #d0d0d0; border-radius: 3px; background-color: #f0f0f0; overflow: hidden; margin-bottom: 10px; }.message { display: block; position: absolute; top: 0; right: 0; margin: 0; white-space: nowrap; /* Starting postition */ transform: translate3d(100%, 0, 0); /* Animation settings */ animation-name: marquee-animation; animation-iteration-count: infinite; animation-timing-function: linear; } @keyframes marquee-animation { from { /* Start right out of view */ transform: translate3d(100%, 0, 0); } to { /* Animate to the left of the container width */ transform: translate3d(-200px, 0, 0); } }
 <div class='text-scroller-container'> <p class='message'>This is a sentence. I'm a long sentence.</p> </div> <div class='text-scroller-container'> <p class='message'>This is a short sentence.</p> </div> <div class='text-scroller-container'> <p class='message'>This is a very long sentence. This sentence is going to be the longest one of them all.</p> </div>

如果您正在寻找高性能动画,请使用transform属性而不是left 虽然left更改将重新绘制整个页面,但transform只会重新渲染受转换影响的部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM