HTML5滚屏效果的实现主要依赖于CSS3的@keyframes
动画和JavaScript,下面我将详细介绍如何使用HTML5和CSS3制作滚屏效果。
创建HTML结构
我们需要创建一个包含滚动内容的HTML结构,这里我们使用一个<div>
元素作为容器,内部包含多个<p>
元素,每个<p>
元素代表一段滚动的文字。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>滚屏效果</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="scrolling-text"> <p>这里是第一段滚动的文字。</p> <p>这里是第二段滚动的文字。</p> <p>这里是第三段滚动的文字。</p> <!-更多文字内容 --> </div> <script src="script.js"></script> </body> </html>
编写CSS样式
接下来,我们需要编写CSS样式来实现滚屏效果,设置容器的宽度、高度和 overflow 属性,使得容器可以滚动,设置滚动速度和文字样式,使用JavaScript控制滚动效果。
/* style.css */ body { margin: 0; padding: 0; } .scrolling-text { width: 100%; height: 100vh; overflow: hidden; position: relative; } .scrolling-text p { position: absolute; white-space: nowrap; }
编写JavaScript代码
我们需要编写JavaScript代码来控制滚动效果,获取容器的宽度和每个<p>
元素的初始位置,使用requestAnimationFrame
方法实现滚动动画,在每一帧中,更新每个<p>
元素的位置,使其向左移动,当所有文字都移出容器时,重新从左侧开始滚动。
// script.js const container = document.querySelector('.scrolling-text'); const texts = container.querySelectorAll('p'); const textLength = texts.length; let currentIndex = Math.floor(Math.random() * textLength); let scrollDistance = container.clientWidth; // 每个文字之间的距离乘以文字数量减1,因为最后一个文字不需要移动距离就可以移出容器 let animationFrameId; function animateScroll() { if (currentIndex === textLength) { currentIndex = Math.floor(Math.random() * textLength); // 当所有文字都移出容器后,重新从左侧开始滚动 } else if (currentIndex > textLength) { // 如果当前索引超过了文字数量,将其重置为0(即第一个文字) currentIndex = 0; } else if (currentIndex < 0) { // 如果当前索引小于0,将其重置为最后一个文字的索引(即最后一个文字) currentIndex = textLength; } else if (currentIndex !== textLength && (container.clientWidth + scrollDistance) >= texts[currentIndex].offsetLeft) { // 如果当前文字已经移出容器,并且下一个文字即将进入可见区域,则将滚动距离增加一个文字之间的距离(即下一个文字的起始位置) scrollDistance += container.clientWidth; // 每个文字之间的距离乘以文字数量减1(因为最后一个文字不需要移动距离就可以移出容器) } else if (currentIndex !== textLength && (container.clientWidth + scrollDistance) <= texts[currentIndex].offsetLeft) { // 如果当前文字已经移出容器,并且下一个文字即将进入不可见区域,则将滚动距离减少一个文字之间的距离(即下一个文字的结束位置) scrollDistance -= container.clientWidth; // 每个文字之间的距离乘以文字数量减1(因为最后一个文字不需要移动距离就可以移出容器) } else if (currentIndex === textLength && scrollDistance < container.clientWidth) { // 当所有文字都已滚动到右侧边界且还有剩余滚动距离时,将滚动距离恢复到容器的宽度(即所有文字都能完全显示出来) scrollDistance = container.clientWidth; // 每个文字之间的距离乘以文字数量减1(因为最后一个文字不需要移动距离就可以移出容器) } else if (currentIndex === textLength && scrollDistance >= container.clientWidth) { // 当所有文字都已滚动到左侧边界且还有剩余滚动距离时,将滚动距离恢复到容器的宽度(即所有文字都能完全显示出来)并重置当前索引为第一个文字的索引(即第一个文字) scrollDistance = container.clientWidth; // 每个文字之间的距离乘以文字数量减1(因为最后一个文字不需要移动距离就可以移出容器) currentIndex = 0; // 将当前索引重置为第一个文字的索引(即第一个文字) } else if (currentIndex !== textLength && (container.clientWidth + scrollDistance) >= texts[currentIndex].offsetLeft && (container.clientWidth + scrollDistance) <= texts[currentIndex].offsetLeft + texts[currentIndex].clientWidth) { // 当当前文字已经移出容器,并且下一个文字即将进入可见区域或不可见区域时,根据下一个文字的位置调整当前索引和滚动距离(以保持滚动速度一致) const nextIndex = (currentIndex + Math.sign(scrollDistance)) % textLength; // 根据当前索引和滚动距离计算下一个文字的索引(取模运算保证索引在有效范围内) currentIndex = nextIndex; // 将当前索引更新为下一个文字的索引(即下一个准备进入或离开可见区域的文字) scrollDistance += (container.clientWidth + scrollDistance) * (nextIndex === currentIndex); // 根据下一个文字是否与当前文字相同以及它们的位置关系,调整滚动距离(如果两个相邻的文字相同或者它们的位置关系使得它们的滚动速度相同,则只增加一次滚动距离;否则每次都会增加一次滚动距离) } else if (currentIndex !== textLength && (container.clientWidth + scrollDistance) <= texts[currentIndex].offsetLeft || (container.clientWidth + scrollDistance) >= texts[currentIndex].offsetLeft + texts[currentIndex].clientWidth) { // 当当前文字已经移出容器,并且下一个文字即将进入不可见区域或已经完全不可见时,将当前索引重置为第一个文字的索引(即第一个文字),并将滚动距离恢复到容器的宽度(即所有文字都能完全显示出来)(这是为了防止出现死循环,例如当所有文本都在同一个位置时) currentIndex = 0; // 将当前索引重置为第一个文字的索引(即第一个文字) scrollDistance = container.clientWidth; // 将滚动距离恢复到容器的宽度(即所有文字都能完全显示出来)(这是为了防止出现死循环,例如当所有文本都在同一个位置时) } else if (currentIndex !== textLength && (container.clientWidth + scrollDistance) >= texts[currentIndex].offsetLeft + texts[currentIndex].clientWidth && (container.clientWidth + scrollDistance) <= texts[currentIndex].offsetLeft + containers[currentIndex].clientHeight) { // 当当前文字已经移出容器,并且下一个文字即将完全进入不可见区域时,将当前索引更新为下一个文字的索引(即下一个准备完全进入不可见区域的文字),并将滚动距离恢复到容器的宽度(即所有文字都能完全显示出来)(这是为了防止出现死循环,例如当所有文本都在同一个位置时) const nextIndex = (currentIndex + Math.sign(scrollDistance)) % textLength; // 根据当前索引和滚动距离计算下一个文字的索引(取模运算保证索引在有效范围内) currentIndex = nextIndex; // 将当前索引更新为下一个文字的索引(即下一个准备完全进入不可见区域的文字) scrollDistance += (container.clientWidth + scrollDistance) * (nextIndex === currentIndex); // 根据下一个文字是否与当前文字相同以及它们的位置关系,调整滚动距离(如果两个相邻的文字相同或者它们的位置关系使得它们的滚动速度相同,则只增加一次滚动距离;否则每次都会增加一次滚动距离) } else if (currentIndex !== textLength && (container.clientWidth + scrollDistance) <= texts[currentIndex].offsetLeft || (container.clientWidth + scrollDistance) >= texts[currentIndex].offsetLeft + texts[currentIndex].clientHeight) { // 当当前文字已经移出容器,并且下一个文字已经完全不可见时,将当前索引重置为第一个文字的索引(即第一个文字),并将滚动距离恢复到容器的宽度(即所有文字都能完全显示出来)(
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/273230.html