纯css实现单张图片无限循环无缝滚动

本文介绍如何使用CSS3的animation属性实现单张竖图的无缝滚动及滚动到正中间停留的效果。通过定义关键帧动画,使图片能够平滑地向上滚动并达到无缝循环,同时加入暂停功能,提升视觉体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考链接:https://blog.youkuaiyun.com/qq_20777797/article/details/77916029

https://www.xiabingbao.com/css3/2017/07/03/css3-infinite-scroll.html

需求是一共有两个,
1、单张竖图持续向上无缝滚动,

2、单张竖图滚动到正中间之后,停留3s,继续滚动。

一、用js setInterval定时器实现

js实现要通过不断的改变定位、复制图片的方式来做,效果极其不稳定

二、用css3 animation动画实现

需求1动画:

 @-webkit-keyframes scrollUp {
            0% {
                -webkit-transform: translateY(0);
                transform: translateY(0);
            }
            100% {
                -webkit-transform: translateY(-400px);
                transform: translateY(-400px);
            }
        }

        @-moz-keyframes scrollUp {
            0% {
                -moz-transform: translateY(0);
                transform: translateY(0);
            }
            100% {
                -moz-transform: translateY(-400px);
                transform: translateY(-400px);
            }
        }

        @-o-keyframes scrollUp {
            0% {
                -o-transform: translateY(0);
                transform: translateY(0);
            }
            100% {
                -o-transform: translateY(-400px);
                transform: translateY(-400px);
            }
        }

        @keyframes scrollUp {
            0% {
                -webkit-transform: translateY(0);
                -moz-transform: translateY(0);
                -o-transform: translateY(0);
                transform: translateY(0);
            }
            100% {
                -webkit-transform: translateY(-400px);
                -moz-transform: translateY(-400px);
                -o-transform: translateY(-400px);
                transform: translateY(-400px);
            }
        }

需求2动画:

@-webkit-keyframes scrollUpAndPause {
            0% {
                -webkit-transform: translateY(0);
                transform: translateY(0);
            }
            25% {
                -webkit-transform: translateY(-350px);
                transform: translateY(-350px);
            }
            100% {
                -webkit-transform: translateY(-350px);
                transform: translateY(-350px);
            }
        }

        @-moz-keyframes scrollUpAndPause {
            0% {
                -moz-transform: translateY(0);
                transform: translateY(0);
            }
            25% {
                -moz-transform: translateY(-350px);
                transform: translateY(-350px);
            }
            100% {
                -moz-transform: translateY(-350px);
                transform: translateY(-350px);
            }
        }

        @-o-keyframes scrollUpAndPause {
            0% {
                -o-transform: translateY(0);
                transform: translateY(0);
            }
            25% {
                -o-transform: translateY(-350px);
                transform: translateY(-350px);
            }
            100% {
                -o-transform: translateY(-350px);
                transform: translateY(-350px);
            }
        }

        @keyframes scrollUpAndPause {
            0% {
                -webkit-transform: translateY(0);
                -moz-transform: translateY(0);
                -o-transform: translateY(0);
                transform: translateY(0);
            }
            25% {
                -webkit-transform: translateY(-350px);
                -moz-transform: translateY(-350px);
                -o-transform: translateY(-350px);
                transform: translateY(-350px);
            }
            100% {
                -webkit-transform: translateY(-350px);
                -moz-transform: translateY(-350px);
                -o-transform: translateY(-350px);
                transform: translateY(-350px);
            }
        }

html

<div class="box">
    <div class="image-item">
    </div>
    <div class="image-item">
    </div>
    <div class="image-item">
    </div>
</div>

style:

 .box {
            width: 500px;
            height: 500px;
            overflow: hidden;
        }

应用动画:

.image-item {
            width: 500px;
            height: 400px;
            background: url("./猫咪咪.jpg") repeat-y center center; /* 什么图片都可以*/
            /*animation-delay: 2s;!*延迟2s在进行滚动*!*/
            -webkit-animation: 3s scrollUp linear infinite normal;/* 3s持续滚动图片*/
            animation: 3s scrollUp linear infinite normal;
            /*-webkit-animation: 4s scrollUpAndPause linear infinite normal;*/ /* 每停3s滚动一次*/
            /*animation: 4s scrollUpAndPause linear infinite normal;*/
 }

另外自己做好css的兼容写法即可实现。

注意:

1、前提是把一张图片复制成3张,以实现无缝滚动,网上看了很多人此类无缝循环滚动的方法,实现出来之后,每次回到起点都会有跳动的感觉,这里经过摸索,给动画上移的距离设为图片的高度,就不会有跳动问题了,完美无限循环+无缝滚动;

2、图片每停3s滚动一次,且每次刚好停在正中间,上线留的衔接的图片距离相等,这里就要计算一下,每次动画上移距离= 图片实际显示高度-(所在区域的总高度-上间距高度)。

以下是图片滚动的js,如果要实现动态获取图片高度,则需要写下面的js:

function addKeyFrames(height,offsetHeight){
    let style = document.createElement('style');
    style.type = 'text/css';
    let keyFrames = '\
    @-webkit-keyframes scrollUpAndPause {\
        0% {\
            -webkit-transform: translateY(0);\
            transform: translateY(0);\
        }\
        40% {\
            -webkit-transform: translateY(0);\
            transform: translateY(A_DYNAMIC_VALUE);\
        }\
        100% {\
            -webkit-transform: translateY(0);\
            transform: translateY(A_DYNAMIC_VALUE);\
        }\
    }\
    @-moz-keyframes scrollUpAndPause {\
        0% {\
            -webkit-transform: translateY(0);\
            transform: translateY(0);\
        }\
        40% {\
            -webkit-transform: translateY(0);\
            transform: translateY(A_DYNAMIC_VALUE);\
        }\
        100% {\
            -webkit-transform: translateY(0);\
            transform: translateY(A_DYNAMIC_VALUE);\
        }\
    }\
    @-o-keyframes scrollUpAndPause {\
        0% {\
            -webkit-transform: translateY(0);\
            transform: translateY(0);\
        }\
        40% {\
            -webkit-transform: translateY(0);\
            transform: translateY(A_DYNAMIC_VALUE);\
        }\
        100% {\
            -webkit-transform: translateY(0);\
            transform: translateY(A_DYNAMIC_VALUE);\
        }\
    }\
    @keyframes scrollUpAndPause {\
        0% {\
            -webkit-transform: translateY(0);\
            transform: translateY(0);\
        }\
        40% {\
            -webkit-transform: translateY(0);\
            transform: translateY(A_DYNAMIC_VALUE);\
        }\
        100% {\
            -webkit-transform: translateY(0);\
            transform: translateY(A_DYNAMIC_VALUE);\
        }\
    }\
    @-webkit-keyframes scrollUp {\
        0% {\
             -webkit-transform: translateY(0);\
            transform: translateY(0);\
        }\
        100% {\
            -webkit-transform: translateY(0);\
            transform: translateY(B_DYNAMIC_VALUE);\
        }\
    }\
    @-moz-keyframes scrollUp {\
        0% {\
             -webkit-transform: translateY(0);\
            transform: translateY(0);\
        }\
        100% {\
            -webkit-transform: translateY(0);\
            transform: translateY(B_DYNAMIC_VALUE);\
        }\
    }\
    @-o-keyframes scrollUp {\
        0% {\
             -webkit-transform: translateY(0);\
            transform: translateY(0);\
        }\
        100% {\
            -webkit-transform: translateY(0);\
            transform: translateY(B_DYNAMIC_VALUE);\
        }\
    }\
    @keyframes scrollUp {\
        0% {\
             -webkit-transform: translateY(0);\
            transform: translateY(0);\
        }\
        100% {\
            -webkit-transform: translateY(0);\
            transform: translateY(B_DYNAMIC_VALUE);\
        }\
    }';
    keyFrames = keyFrames.replace(/A_DYNAMIC_VALUE/g, '-'+(height-(offsetHeight-height)/2)+'px');
    keyFrames = keyFrames.replace(/B_DYNAMIC_VALUE/g, '-'+height+'px');
    style.innerHTML = keyFrames;
    document.getElementsByTagName('head')[0].appendChild(style);
}
// 初始化图片滚动动画高度
function initAnimate() {
    const adLeftHeight = document.getElementById("adLeft").offsetHeight; // 左侧区域高度
    const adLeftWidth = document.getElementById("adLeft").offsetWidth; // 左侧区域宽度
    let leftImage = new Image();
    let leftImageWidth = "";
    let leftImageHeight = "";
    leftImage.src = window.campaign.image_url;
    leftImage.onload = function () {
        leftImageWidth = leftImage.width;
        leftImageHeight = leftImage.height;
        let imageRealHeight = adLeftWidth * (leftImageHeight / leftImageWidth);
        // const imageBoxScrollHeight = document.getElementById("imageBox").scrollHeight; // 三张图片的总高度
        // const imageHeight = imageBoxScrollHeight/3;// 单张图片高度
        addKeyFrames(imageRealHeight,adLeftHeight);
    }
}

以上js对应的html:

<div class="ad_left" id="adLeft">
        <div class="image-box" id="imageBox">
            <img class="image-item" src="xxx.jpg" alt="">
            <img class="image-item" src="xxx.jpg" alt="">
            <img class="image-item" src="xxx.jpg" alt="">
        </div>
</div>

以上html对应的css:

.ad_left{
        width:44vw;
        height: 100vh;
        overflow: hidden;
        .image-box{
          width:100%;
          height: auto;
          .image-item {
            width: 100%;
            height: auto;
            display: block;
            animation: 5s scrollUpAndPause linear infinite normal;
          }
        }
      }

 

### 使用 CSS3 实现 Vue 图片墙组件的无限循环无缝滚动 为了实现一个高效的无限循环无缝滚动效果,可以采用 CSS 解决方案来减少 JavaScript 的开销并提高性能。下面介绍一种通过 CSS 动画和伪类相结合的方式。 #### HTML 结构设计 创建一个容器用于容纳所有的图片项,并确保这些图片能够水平排列: ```html <div class="carousel-container"> <ul class="carousel-list"> <!-- 个列表项 --> <li v-for="(item, index) in items" :key="index" class="carousel-item"> <img :src="item.src"/> </li> <!-- 复制首尾两个元素以平滑过渡 --> <li class="carousel-item clone-first"><img src="{{items[0].src}}"/></li> <li class="carousel-item clone-last"><img src="{{items[items.length - 1].src}}"/></li> </ul> </div> ``` #### 关键样式定义 利用 `@keyframes` 定义动画路径以及设置初始状态与结束状态之间的变化;同时应用 `transform translateX()` 来控制位移距离。注意这里的宽度计算应该考虑实际内容加上额外复制的内容[^2]。 ```css .carousel-container { overflow: hidden; } .carousel-list { display: flex; animation-name: slideLoop; animation-duration: 8s; /* 可调整 */ animation-timing-function: linear; animation-iteration-count: infinite; } .carousel-item { min-width: 25%; /* 假设每张图占据四分之一空间 */ } /* 额外添加的关键帧规则 */ @keyframes slideLoop { from { transform: translateX(0); } to { transform: translateX(-{{ (imagesCount + 1) * itemWidth }}px); } } .clone-first, .clone-last{ position:absolute; } ``` 此方法的核心在于巧妙地处理了视觉上的连续性和物理位置上的重置,从而实现了真正的无间断滚动体验。对于 Vue.js 应用程序来说,只需要关注数据绑定部分即可轻松集成该功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值