如题。
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>不定宽无限滚动</title>
<style>
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
background: darkcyan;
margin: 0;
}
.no-wrap {
white-space: nowrap !important;
}
.container {
/* max-width: 992px; */
width: 100vw;
margin: 0 auto;
overflow: hidden;
}
.grid {
display: block;
font-size: 0;
}
.cell {
display: inline-block;
font-size: 2rem;
font-weight: 700;
position: relative;
width: 100%;
height: 30vh;
padding: 1rem .5rem;
text-align: center;
cursor: pointer;
}
.cell .content {
display: block;
position: absolute;
top: .5rem;
bottom: .5rem;
left: .5rem;
right: .5rem;
padding: 1rem;
color: #555;
background: #fff;
box-shadow: 0 2px 10px -10px #ccc;
}
.cell.w16 {
width: 16%;
width: calc(100% / 6)
}
.cell.w25 {
width: 25%
}
.cell.w33 {
width: 33%;
width: calc(100% / 3)
}
.cell.w50 {
width: 50%
}
.cell.w66 {
width: 66%;
width: calc(100% / (3 / 2))
}
.cell.w75 {
width: 75%
}
.cell.w83 {
width: 83%;
width: calc(100% / (6 / 5))
}
.cell.w100 {
width: 100%
}
h1,
h2 {
text-align: center;
color: #fff;
}
h1 {
font-size: 3rem;
margin-bottom: .15rem;
}
h2 {
font-size: 1.3rem;
margin-top: .15rem;
margin-bottom: 15vh;
}
</style>
</head>
<body>
<h1>无限滚动横幅</h1>
<h2>( hover播放/暂停 )</h2>
<div class="container">
<div class="grid infinite-banner">
<div class="cell w66">
<div class="content">
开始
</div>
</div>
<div class="cell w33">
<div class="content">
1
</div>
</div>
<div class="cell w25">
<div class="content">
2
</div>
</div>
<div class="cell w25">
<div class="content">
3
</div>
</div>
<div class="cell w50">
<div class="content">
4
</div>
</div>
<div class="cell w100">
<div class="content">
5
</div>
</div>
<div class="cell w16">
<div class="content">
6
</div>
</div>
<div class="cell w83">
<div class="content">
7
</div>
</div>
<div class="cell w25">
<div class="content">
8
</div>
</div>
<div class="cell w75">
<div class="content">
9
</div>
</div>
<div class="cell w66">
<div class="content">
10
</div>
</div>
<div class="cell w33">
<div class="content">
结束
</div>
</div>
</div>
</div>
<script>
// 动画对象
let bannerAnimation
// 获取滚动显示元素和其子元素
const bannerEl = document.querySelector('.grid.infinite-banner')
const cells = bannerEl.querySelectorAll('.cell')
/**
* 创建无限滚动动画
* 检查元素是否具有animate方法,如果没有则不执行动画
* 计算所有子元素的总宽度,并基于这个宽度创建一个无限循环的线性动画
*/
const createBannerAnimation = () => {
// 检查bannerEl元素是否存在animate方法
if ('animate' in bannerEl && typeof bannerEl.animate === 'function') {
// 如果已有动画,取消之前的动画
if (bannerAnimation) bannerAnimation.cancel()
// 避免文本自动换行影响动画效果
bannerEl.style.whiteSpace = 'nowrap'
// 初始化位移变量,用于计算动画的最终位移量
let displacement = 0
// 遍历所有子元素,累加宽度以计算总位移量
for (const cell of cells) displacement += cell.clientWidth
// 调整位移量
displacement = (displacement - bannerEl.clientWidth) << 0
// 创建并启动动画,使轮播图从右向左滚动
bannerAnimation = bannerEl.animate(
[
{ transform: 'matrix(1, 0, 0, 1, 0, 0)', offset: 0 },
{
transform: `matrix(1, 0, 0, 1, ${-displacement}, 0)`,
offset: 1
}
],
{
duration: cells.length * 3000, // 动画总时长
easing: 'linear', // 匀速动画效果
delay: 0, // 无延迟启动
iterations: Infinity, // 无限循环
direction: 'normal', // 'reverse'
fill: 'forwards' // 动画结束后保持最终状态
}
)
}
}
/**
* 播放滚动动画
*/
const playBannerAnimation = () => {
if (bannerAnimation && bannerAnimation.playState === 'paused')
bannerAnimation.play()
}
/**
* 暂停滚动动画
*/
const pauseBannerAnimation = () => {
if (bannerAnimation && bannerAnimation.playState === 'running')
bannerAnimation.pause()
}
/**
* 防抖
*/
const debounce = (func) => {
let scheduled, context, args;
return () => {
context = this; args = Array.from(arguments);
if (scheduled) window.cancelAnimationFrame(scheduled);
scheduled = window.requestAnimationFrame(() => {
func.apply(context, args);
scheduled = null;
});
};
};
// 创建动画,添加鼠标事件
if ('animate' in bannerEl && typeof bannerEl.animate === 'function') {
createBannerAnimation()
bannerEl.addEventListener('mouseenter', pauseBannerAnimation, false)
bannerEl.addEventListener('mouseleave', playBannerAnimation, false)
window.addEventListener(
'resize',
debounce(createBannerAnimation),
false
)
} else {
// 浏览器不支持 Web Animation API
}
</script>
</body>
</html>