javascript - 如何在Web端实现动画切换效果一致的无限循环图片轮播?

 輕風斬情絲 发布于 2022-11-21 20:37

具体问题是这样的,我想要一个能无限循环播放图片的轮播,重点是播放完一轮后,跳回第一张时,切换效果应该和之前一样。即如果动画是从左到右切换的,那么最后一张切换到第一张时,也应该是这个效果。

在网上找了很多 jQuery 的轮播插件,但都不能满足我所想要的效果。Bootstrap 的 Carousel 倒是能用,但源码看不懂。

HTML 代码大致如下:

CSS 关键代码:

.carousel {
    height: 120px;
    overflow: hidden;
}

.slide {
    height: 120px;
    transition: all .4s ease-in;
}

jQuery关键代码:

$('.slide').each(function(){
        $(this).css('transform', 'translateY(' + (i)*-100 + '%)');          
})

我所写的这个,最后一张是transform: translateY(-300%);,然后就变成了transform: translateY(0%);,所以动画的方向变反了。

这样的写法似乎无法解决这个问题,是否有其他的轮播图写法?

15 个回答
  • superslide 完美兼容pc
    swiper 完美手机端
    满足题主一切需求

    2022-11-21 21:47 回答
  • 2022-11-21 21:47 回答
  • 2022-11-21 21:47 回答
  • 2022-11-21 21:47 回答
  • 搜一下PgwSlider插件,可以实现各种各样的图片轮播方式。本人前几天利用此插件完成了一个图片轮播,实现上方显示一张大图,下面陈列全部缩略图的功能。点击左右箭头实现轮播,点击缩略图也能实现大图切换。符合你所要求的点击最后一张图片后以相同方式回到第一张图片。源代码也比较容易读懂。如果需要源码,请回复。

    2022-11-21 21:47 回答
  • 实现无缝切换可以多加两张图,在第一张前面加上最后一张图,在最后一张图后面加上第一张图。刚好之前写过一个,JS原生,具体代码如下:
    html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>轮播图</title>
        <style>
        .wrap{
            width: 900px;
            height: 500px;
            overflow: hidden;
            margin: 0 auto;
            margin-top: 50px;
            position: relative;
        }
        .list{
            position: absolute;
            width: 5400px;      
        }
        img{
            width: 900px;
            height: 500px;
            float: left;
        }
        a{
            text-decoration: none;
            position: absolute;
            top:200px;
            display: inline-block;
            width: 85px;
            line-height: 70px;
            background: rgba(3,3,3,.3);
            color: #fff;
            font-weight: 700;
            font-size: 50px;
            text-align: center;
            display: none;
        }
        .buttons{
            position: absolute;
            bottom: 20px;
            width: 100%;
            text-align: center;
        }
        span{
            width: 15px;
            height: 15px;
            border-radius: 50%;
            display: inline-block;
            cursor: pointer;
            border: 1px solid #fff;
        }
        span~span{
            margin-left: 20px;
        }
        .light{
            background-color: #fff;
        }
        </style>
    </head>
    <body>
        <p class="wrap" id="wrap">
            <p class="list" id="list" style="left: -900px;">
                <img src="img/p4.jpg">
                <img src="img/p1.jpg">
                <img src="img/p2.jpg">
                <img src="img/p3.jpg">
                <img src="img/p4.jpg">
                <img src="img/p1.jpg">
            </p>
            <a href="#" id="prev"> < </a>
            <a href="#" id="next" style="right:0"> > </a>
            <p class="buttons" id="buttons">
                <span index="1" class="light"></span>
                <span index="2"></span>
                <span index="3"></span>
                <span index="4"></span>
            </p>
        </p>
        <script src="main.js?1.2.1"></script>
    </body>
    </html>
    

    js


    window.onload = function () { var index = 1; var switching = false; var prev = document.getElementById('prev'); var next = document.getElementById('next'); var list = document.getElementById('list'); var wrap = document.getElementById('wrap'); var dots = document.getElementsByTagName('span'); var buttons = document.getElementById('buttons'); wrap.onmouseover = function () { prev.style.display = 'block'; next.style.display = 'block'; stop(); }; wrap.onmouseout = function () { prev.style.display = 'none'; next.style.display = 'none'; play(); } function lastImg() { if (switching) { return; } switchPic(900); index--; if (index < 1) { index = 4; } else if(index > 4) { index = 1; } lightDot(); } function nextImg() { if (switching) { return; } switchPic(-900); index++; if (index < 1) { index = 4; } else if(index > 4) { index = 1; } lightDot(); } function btn(e) { if (switching) { return; } e = window.e || e; var target = e.target ? e.target: e.srcElement; if (target.nodeName.toLowerCase() == 'span') { var index1 = target.getAttribute('index'); var offset = (index - index1) * 900; switchPic(offset); index = index1; lightDot(); } }; // 切换图片的函数 function switchPic(offset) { switching = true; var time = 300; var inter = 10; // 隔10ms切换一次 var speed = Math.ceil(offset/(time/inter)); var left = parseInt(list.style.left) + offset; var go = function () { var curLeft = parseInt(list.style.left); if ((speed > 0 && curLeft < left) || (speed < 0 && curLeft > left)) { list.style.left = curLeft + speed + 'px'; setTimeout(go, inter); } else { list.style.left = left + 'px'; if (left < -3600) { list.style.left = -900 + 'px'; } else if (left > -900) { list.style.left = -3600 + 'px'; } switching = false; } }; go(); } // 点亮小点 function lightDot() { for (var i = 0, len = dots.length; i < len; i++) { if (dots[i].className == 'light') { dots[i].className = ''; break; } } dots[index-1].className = 'light'; } // 自动轮播 var timer; var order; var interval; var play = function () { var interval1 = interval || 2000; if (order == 'prev') { timer = setInterval(lastImg, interval1); } else { timer = setInterval(nextImg, interval1); } }; var stop = function () { clearInterval(timer); }; // 事件绑定DOM2 function addEvent(element, event, listener) { if (element.addEventListener) { element.addEventListener(event, listener, false); } else { element.attachEvent('on'+event, listener); } } // 点击左右键切图 addEvent(prev, 'click', lastImg); addEvent(next, 'click', nextImg); // 点击小点切图 addEvent(buttons, 'click', btn); // 指定切换顺序和间隔时间 order = 'next'; interval = 2000; play(); };

    可以建个img文件夹,放几张图片试一下效果,这个是4张图片

    2022-11-21 21:47 回答
  • 我想你要的是:当最后一张图片时就轮播到第一张是吗? 无限轮播是吧?..

    这个容易只要一个公式就搞定了.

    var prevImg = (currentImg+1)%totalImg; //currentImg是当前的轮播图片,toutalImg是一共多少图片.

    这样就能无限了

    2022-11-21 21:47 回答
  • 如果要实现这种无缝滚动,需要你补齐你的p.slider。实现这样效果的插件很多,比如楼上说的superslider,还有cxScroll等,如果楼主想看具体的细节,花点时间去研究下这些插件的源码即可,原理很简单。

    2022-11-21 21:47 回答
  • 考虑一下使用Canvas自己画~~?
    我觉得用Canvas画反而比较简单方便。而且性能还能好点……

    2022-11-21 21:47 回答
  • 我觉得 没必要闭门造车。可以看看这个 superslide 一个我用了很多年的插件
    源码也比较简单,可以看得懂 。

    2022-11-21 21:47 回答
  • 给个思路,第一个内容position: relative。然后轮播到最后一个内容的时候,第一个内容添加left值,大小为滚滚容器的宽度减一块内容的宽度。然后接着轮播,就看到了我们相对定位的第一个内容后。把第一个内容的position: static。然后滚动的容器left: 0就做到无缝了。

    思路大概是这样了!

    有个视频可以做参考:华为轮播图

    2022-11-21 21:47 回答
  • 这个思路说白了其实很简单,比如你要轮播三张图,你可以写四个标签,第一张图和第四张图是一样的,当播完第四张的时候将标签改为第一张的标签。。。手机码字不方便,大概就这个意思,达到欺骗用户眼睛的目的,大部分轮播插件也是这么实现的

    2022-11-21 21:47 回答
  • 原始html:

    <ul>
        <li class="slide1">1</p>
        <li class="slide2">2</p>
        <li class="slide3">3</p>
    <ul>
    

    先clone slide1 和 slide3,然后变成这样:

    <p class="carousel">
        <ul>
            <li class="slide3">3</p>
            <li class="slide1">1</p>
            <li class="slide2">2</p>
            <li class="slide3">3</p>
            <li class="slide1">1</p>
        <ul>
    </p>
    

    当动ul翻到最后clone出的slide1后,直接让ul定位到原始的slide1(这个动作不要加动画效果,直接定位),反方向也是如此。

    移动端就不是这么做了。每个slide都加absoulte,transition属性,然后监听手势去控制当前触摸的slide和其前后slide的transform。

    2022-11-21 21:47 回答
  • 三个class,都加absoulte,transition
    左:transformX(-100%)
    中:transformX(0)
    右:tranformX(100%)
    每次把当前显示的加为中间的class 小于当前的加左边class,大于的放右边,当最后一个激活的时候,把第一个放右边。只要每次改当前索引值就可以了,动画交给tansition去

    2022-11-21 21:47 回答
  • 这个思路是:

    1. 设置轮播的每个item为absolute,然后再通过z-index覆盖即可。active状态的z-index:2,normal状态为1。
    2. 每次轮播left走一个图片的距离。

    这样就可以让轮播始终都是一个图片的距离,无论你点击哪个序号(1,2,3,4,5),比如,从当前是第一张轮播,你直接跳到第五张图片,普通轮播会产生4个图片的距离,但是这样始终是一个图片的距离。

    其他在尾部克隆插入的方法没法解决以上产生的距离问题。

    参考我写的组件:https://github.com/xiaomingming/easySwitch
    demo是easySwitch.html.

    2022-11-21 21:47 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有