马黑黑 发表于 2026-8-7 12:24

多图循环平滑移动之background实现方式

<style>
    .artBox { margin: 20px auto; font: normal 18px/26px sans-serif; }
    .artBox mark { padding: 2px 6px; background: #ccc; }
    .artBox p { margin: 10px 0; }
</style>

<div class="artBox">
    <h2>一、实现原理:</h2>
    <p><mark>background</mark> 是 <mark>background-image</mark>、<mark>background-repeat</mark>、<mark>background-position</mark>、<mark>background-size</mark>、<mark>background-color</mark> 等的简写属性,其中的 background-position 属性用于设置背景图片的位置。以背景图片自右向左移动为例:</p>
    <ol>
      <li>background-position 从 x 到 -x 的改变可以达成背景图片自右向左的移动效果;</li>
      <li>多张背景图片的 background-position 的水平方向可以依次按 0、x、2*x、...、n*x 往右平铺,形成图片横向并排的布局;</li>
      <li>最后一张背景图片和第一张相同,营造无缝循环的衔接效果。</li>
    </ol>
    <h2>二、完整代码(支持在线预览):</h2>
    <div class="hEdiv" data-prev="1"><pre class="hEpre">
&lt;style&gt;
    .pa {
      width: 1024px;
      height: 640px;
      background:
            url('https://638183.freep.cn/638183/t22/webp/jyiu.webp') no-repeat 0 0/cover,
            url('https://638183.freep.cn/638183/t22/webp/qqup.webp') no-repeat 1024px 0/cover,
            url('https://638183.freep.cn/638183/t22/webp/uwty.webp') no-repeat 2048px 0/cover,
            url('https://638183.freep.cn/638183/t24/7/dbxj.jpg') no-repeat 3072px 0/cover,
            url('https://638183.freep.cn/638183/t22/webp/jyiu.webp') no-repeat 4096px 0/cover;
      animation: bgmove 30s linear infinite var(--state);
      border: thick outset #333;
      margin: auto;
      --state: running;
    }
    .pa:hover { --state: paused; }
    .tMid { text-align: center; }
    @keyframes bgmove {
      to { background-position: -4096px 0, -3072px 0, -2048px 0, -1024px 0, 0 0; }
    }
&lt;/style&gt;

&lt;h1 class="tMid"&gt;多张背景图片循环平滑移动演示&lt;/h1&gt;
&lt;div class="pa"&gt;&lt;/div&gt;
    </pre></div>
    <h2>三、简要说明:</h2>
    <ol>
      <li>容器元素宽高比设置最好与图片的宽高比一致或接近,这样可以减少图片变形或被剪裁的风险;</li>
      <li>用 url() 函数加载每一张图片做背景,图片不重复(no-repeat)、各图片依次沿水平方向向右平铺(background-position)、尺寸(background-size)设置为 cover(覆盖整个容器)或 100% 100%;</li>
      <li>背景图片平铺涉及到水平方向的距离计算,第一张图片 background-position 的 x 为 0,第二张为 容器宽度*1px,第三张为 容器宽度*2px,其余以此类推。如果希望每张图片之间留出间隔缝隙,尺寸可以设置为大于容器宽度,位置跟着变更,方法是第一张图片水平方向位置 0 不变,其余按 (2-1)*x 计算水平方向位置;</li>
      <li>最后一张背景图片和第一张同,但 background-position 的 x 位置不一样,其作用是做循环衔接;</li>
      <li>关键帧动画的 background-position 属性 x 位置反向取值,要一一对应前面各图片的属性设置。</li>
    </ol>
    <p>【注意】平滑移动多个背景图片的有个重要前提:背景图片 background-size 应大于等于容器宽度。设置为 cover 或 100% 100% 时都满足这一前提。background-size 设置为 cover 时是图片覆盖整个容器,如果图片尺寸与容器宽高比不一致,图片会被剪裁;设为百分比或像素值时,图片得以完整呈现,但若图片尺寸和容器宽高比对不上,图片会扭曲、变形。</p>
</div>

<script type="module">
    import hl from 'https://638183.freep.cn/638183/web/js/hl.js';
    const divs = document.querySelectorAll('.hEdiv');
    const pres = document.querySelectorAll('.hEpre');
    divs.forEach((div,idx) => hl.hl(div, pres));
</script>

梦江南 发表于 2026-8-7 13:35

黑黑老师,多张图片平移,还是留点缝隙好看。个见。{:4_187:}

梦江南 发表于 2026-8-7 13:35

今天是立秋,祝黑黑老师立秋安康!{:4_204:}

马黑黑 发表于 2026-8-7 13:58

梦江南 发表于 2026-8-7 13:35
黑黑老师,多张图片平移,还是留点缝隙好看。个见。

设计好 background-position 的x位置就好,例如,第二张开始,x 比 容器宽度大 8px,然后后面的依次加倍递增,(宽度+8)* 2,这样就可以了

马黑黑 发表于 2026-8-7 13:58

梦江南 发表于 2026-8-7 13:35
今天是立秋,祝黑黑老师立秋安康!

立秋嚎

杨帆 发表于 2026-8-7 19:01

又一种背景图平滑移动实现方式。谢谢马老师精彩讲解与演示{:4_190:}

马黑黑 发表于 2026-8-7 19:35

杨帆 发表于 2026-8-7 19:01
又一种背景图平滑移动实现方式。谢谢马老师精彩讲解与演示

这个,相对于 img 标签,仅需重复第一张背景图,要简约一些

杨帆 发表于 2026-8-7 19:47

马黑黑 发表于 2026-8-7 19:35
这个,相对于 img 标签,仅需重复第一张背景图,要简约一些

是,总体上一样,同时也加上了多个位置设置

霜染枫丹 发表于 2026-8-7 20:17

马老师立秋快乐!

这个平移的代码太实用了,运行很平滑,漂亮!还是要抱走,感谢您的分享,晚上好!{:4_204:}{:4_190:}

红影 发表于 2026-8-7 20:45

这个平移是种新的方式,需要计算每张图图的布置位置和移动位置。学了这个,都忘了以前的是怎么平移的了{:4_173:}

马黑黑 发表于 2026-8-7 21:15

红影 发表于 2026-8-7 20:45
这个平移是种新的方式,需要计算每张图图的布置位置和移动位置。学了这个,都忘了以前的是怎么平移的了{:4_ ...

采摘玉米棒的猴子晚上嚎{:4_170:}

马黑黑 发表于 2026-8-7 21:15

霜染枫丹 发表于 2026-8-7 20:17
马老师立秋快乐!

这个平移的代码太实用了,运行很平滑,漂亮!还是要抱走,感谢您的分享,晚上好!{:4_ ...

多种实现方式

马黑黑 发表于 2026-8-7 21:16

杨帆 发表于 2026-8-7 19:47
是,总体上一样,同时也加上了多个位置设置

采用 background 简写形式(语法糖)代码量比较少,分开写属性,代码行数也很多

杨帆 发表于 2026-8-7 21:52

马黑黑 发表于 2026-8-7 21:16
采用 background 简写形式(语法糖)代码量比较少,分开写属性,代码行数也很多

是,采用语法糖化繁为简、压缩代码量很有实际意义

红影 发表于 2026-8-7 22:49

马黑黑 发表于 2026-8-7 21:15
采摘玉米棒的猴子晚上嚎

嗯嗯,摘一个丢一个,也挺快乐{:4_173:}

马黑黑 发表于 2026-8-8 08:55

红影 发表于 2026-8-7 22:49
嗯嗯,摘一个丢一个,也挺快乐

快乐第一

马黑黑 发表于 2026-8-8 09:14

杨帆 发表于 2026-8-7 21:52
是,采用语法糖化繁为简、压缩代码量很有实际意义

压缩了代码,省略属性名

杨帆 发表于 2026-8-8 11:10

本帖最后由 杨帆 于 2026-8-8 11:14 编辑

马黑黑 发表于 2026-8-8 09:14
压缩了代码,省略属性名
是,总量一样,同时增加了内置属性语义的记忆

请问老师:可否实现首尾镜像拼接?

马黑黑 发表于 2026-8-8 13:04

杨帆 发表于 2026-8-8 11:10
是,总量一样,同时增加了内置属性语义的记忆

请问老师:可否实现首尾镜像拼接?

可以参考用两个伪元素的那个类型

杨帆 发表于 2026-8-8 13:07

马黑黑 发表于 2026-8-8 13:04
可以参考用两个伪元素的那个类型

好的,谢谢老师答疑解惑{:4_180:}
页: [1] 2
查看完整版本: 多图循环平滑移动之background实现方式