轮播图的制作原理?

图片描述

如上图设计原型,网上找不到类似的轮播插件。
尝试自己制作,没有较好的js思路。
毕竟它跟大多数的轮播图有点差距:
1、首屏显示了三张图片。
2、左右图片仅显示一部份,如左图隐藏了左边部分,右图隐藏了右边部份。
3、每张图片之间均有一定的间距。
4、中间的大图比两边的图片显示尺寸变大。(所有图片都是16:9)

阅读 12.4k
11 个回答

唉~ 写了半天~ 累啊

<!DOCTYPE html><html>
<head>
  <meta http-equiv="Cache-Control" content="no-transform " /> 
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  <meta http-equiv="X-UA-Compatible" content="chrome=1" />
  <meta name="renderer" content="webkit" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>轮播图 | 杰凯寇赞</title>
  <style>
  html,body {height: 100%}
  html {background: #222;color:#fff;} body {margin: 0;font-family: Roboto,Helvetica,Arial,Microsoft JhengHei,sans-serif}

  .viewport {width: 944px;height:283px;position: relative;overflow: hidden;}
  .father {width:3000%;height:100%;padding: 20px 0;box-sizing: border-box;transition: transform 0.6s ease-in-out;transform: translate3d(0,0,0);background: #ff5252;}
  .father.moving {transition-duration: 0s;}
  .father > div {width: 432px;height: 243px;margin: 0 20px;opacity:0.6;transition: all 0.6s ease-in-out;background: #2dbe60;float: left;}
  .father.moving > div {transition-duration: 0s;}
  .father > div.showing {opacity: 1;transform: scale3d(1.1, 1.1, 1);}

  .left, .right {width: 30px;height: 100%;line-height: 283px;user-select:none;text-align: center;cursor: pointer;background: rgba(0,0,0,0.15);position: absolute;top: 0;}
  .left {left: 0;} .right {right: 0;}
  </style>
</head>
<body>
  <div class="viewport">
    <div class="father" id="father">
      <div>A</div><!-- 1 -->
      <div>B</div>
      <div>C</div><!-- 3 -->
      <div>D</div>
      <div>E</div><!-- 5 -->
      <div>F</div>
      <div>G</div><!-- 7 -->
<!-- ^…^ -->
      <div>A</div><!-- 1 -->
      <div>B</div>
      <div>C</div><!-- 3 -->
      <div>D</div>
      <div>E</div><!-- 5 -->
      <div>F</div>
      <div>G</div><!-- 7 -->
<!-- Counting is too hard. -->
      <div>A</div><!-- 1 -->
      <div>B</div>
      <div>C</div><!-- 3 -->
      <div>D</div>
      <div>E</div><!-- 5 -->
      <div>F</div>
      <div>G</div><!-- 7 -->
    </div>
    <div class="left" id="left">:-o</div>
    <div class="right" id="right">:-)</div>
  </div>
<script type="text/javascript">
var father=document.getElementById("father"),
  sons=father.children,
  sonsLength=sons.length/3,
  showWidth=432+20*2, //432: width; 20*2: margin*2
  showingId=parseInt(sonsLength/2)+sonsLength-1,
  transform=-showingId*showWidth+showWidth/2,
  checkTime=new Date()

father.style.transform=`translate3d(${transform}px, 0, 0)`
sons[showingId].className="showing"

function go(nowShowingId, direction) {
  // Direction: "-1" stands for left, "1" stands for right.
  //+ Avoid continuous sliding
  if(new Date()-checkTime<700)return
  checkTime=new Date()
  //+ Standard show change
  sons[nowShowingId].className=""
  //- Change here
  nowShowingId=nowShowingId+direction
  showingId=nowShowingId;
  transform=nowShowingId*showWidth-showWidth/2
  father.style.transform=`translate3d(-${transform}px, 0, 0)`
  sons[nowShowingId].className="showing"
  //+ Special show change
  if(nowShowingId==1){
    showingId=sonsLength*2+1 // How does it works?
  }
  else if(nowShowingId==sonsLength*2+2){
    showingId=1+1 // Imagine the answer. (Use DevTools!
  }
  else {return}
  //- change here
  setTimeout(function(){
    father.classList.add("moving")
    sons[showingId].className="showing"
    setTimeout(function(){
      father.style.transform=`translate3d(-${showingId*showWidth-showWidth/2}px, 0, 0)`
      sons[nowShowingId].className=""
      setTimeout(function(){
        father.classList.remove("moving")
      },50) // =1.
    },530) // =2.
  },100) // =3. /= 1,2,3: Specified like that because of setTimeout's time error
}

document.getElementById("left").onclick=function (){go(showingId, -1)}
document.getElementById("right").onclick=function (){go(showingId, 1)}
</script>
</body></html>

原理可以参考随后这篇文章新货!如何制作一个高效轮播图?

  • 思路和普通轮播是一样的

  • 想办法给居中图片加上scale()

新手上路,请多包涵

轮播图插件的话,可以百度swiper,设置slidesPerView,来确定图片显示个数。额,设置两边显示部分图片?可以参考swiper源码,应该是设置 loop模式,slidesPerView设为auto吧。。。记不太清楚了,可以去swiper中文官网看一下

轮播图 网上有很多插件 可以去找找

swipe swiper superSlide 等等 有很多

轮播图 原理都是一样的 你只要会写一种 另一种也就会了

网上如果没有你需要的这种插件的话 你可以自己写一个轮播图

这个 也就是一个大的div包含一个ul 然后显示 几个li

每个li里边有一张图片

然后在设置初始位置的时候

你设置整个ulleftli(-width/2) 也就是整个ul向左挪动一段距离

然后再用按照常规的轮播图 的做法

setInterval控制 运动 就可以了

插件到处都是 自己找 不要说没有

新手上路,请多包涵

1、首屏显示3张图片

说明显示内容块的宽度大于一张图片的宽度

2、左右各显示一部分

说明当前显示的图片居中,这样两边还有空位,而图片与图片的距离不足以填满空白距离,因此下一张图片和前一张图片会显示部分出来。

3、每一张图片有间距

这里可以是margin,也可以是在做定位后left的时候,就把这个距离算进去了。

4、中间的大图

中间的大图没有透明度,表示它是当前显示的图片,因而会以完整图的形式显示,自然要比旁边的只有部分且带有透明的图要大。

总的来说,如果能在看到多张图片,那么它的margin或者是left的值比较小,使得非当前图片也会看到;如果值比较大,已经超过内容块了,那么你始终只有看到一张图片。

现在用纯css就可以实现了

思路:

1、确定总数:
你需要复制藏在背后的图片,比如轮播三张,这样是为了应付左右移动时图片过渡的情景,在左右要各自多复制一张图片。 顺序是 3,1,2,3,1;

2、图片布局:
第一张图片的定位,每一张的间隔控制好,上面说的三张图片,最左的3和最右的1隐掉这样只能看到中间的,1,2,3;

3、动画控制:
在图片上做一个框,框内的显示,框外的不显示;
用css3的动画控制移动动画,动画要控制要做的最主要是对当前索引的控制;当前是什么,上一张是什么,下一张是什么,每次动画左右肯定有一张图片移动,比如,3,1,2,3,1 变成 1,2,3,1,2 或 2,3,1,2,3。 这其中开始、中间、结束都有状态变化,这时候做好状态以及doc的控制。

做好以上三步差不多就出来这个效果,后期就是一些微调,比如动画时间快慢等细节的控制;

图片描述
douguo.com 的轮播应该适合你,在Firebug里看下搜索下就能看到这个jQuery插件:

jQuery('.fivebox').slide({
    mainCell: '.bd ul',
    effect: 'leftLoop',
    vis: 1,
    scroll: 1,
    autoPlay: true
});

(function (A) {
  A.fn.slide = function (B) {
    A.fn.slide.deflunt = {
      effect: 'fade',
      autoPlay: false,
      delayTime: 1000,
      interTime: 5000,
      defaultIndex: 0,
      titCell: '.hd li',
      mainCell: '.bd',
      trigger: 'click',
      scroll: 1,
      vis: 1,
      titOnClassName: 'on',
      autoPage: false,
      prevCell: '.prev',
      nextCell: '.next'
    };
    return this.each(function () {
      var Q = A.extend({
      }, A.fn.slide.deflunt, B);
      var D = Q.defaultIndex;
      var I = A(Q.prevCell, A(this));
      var E = A(Q.nextCell, A(this));
      var C = A(Q.titCell, A(this));
      var M = C.size();
      var O = A(Q.mainCell, A(this));
      var U = O.children().size();
      var S = 0;
      var T = 0;
      var N = 0;
      var J = 0;
      var K = Q.autoPlay;
      var H = null;
      var L = D;
      if (U < Q.vis) {
        return
      }
      if (M == 0) {
        M = U
      }
      if (Q.autoPage) {
        var G = U - Q.vis;
        M = 1 + parseInt(G % Q.scroll != 0 ? (G / Q.scroll + 1)  : (G / Q.scroll));
        C.html('');
        for (var F = 0; F < M; F++) {
          C.append('<li>' + (F + 1) + '</li>')
        }
        var C = A('li', C)
      }
      O.children().each(function () {
        if (A(this).width() > N) {
          N = A(this).width();
          T = A(this).outerWidth(true)
        }
        if (A(this).height() > J) {
          J = A(this).height();
          S = A(this).outerHeight(true)
        }
      });
      switch (Q.effect) {
        case 'top':
          O.wrap('<div class="tempWrap" style="overflow:hidden; position:relative; height:' + Q.vis * S + 'px"></div>').css({
            'position': 'relative',
            'padding': '0',
            'margin': '0'
          }).children().css({
            'height': J
          });
          break;
        case 'left':
          O.wrap('<div class="tempWrap" style="overflow:hidden; position:relative; width:940px"></div>').css({
            'width': U * T,
            'position': 'relative',
            'overflow': 'hidden',
            'padding': '0',
            'margin': '0'
          }).children().css({
            'float': 'left',
            'width': N
          });
          break;
        case 'leftLoop':
        case 'leftMarquee':
          O.children().clone().appendTo(O).clone().prependTo(O);
          O.wrap('<div class="tempWrap" style="overflow:hidden; position:relative; width:width:940px"></div>').css({
            'width': U * T * 3,
            'position': 'relative',
            'overflow': 'hidden',
            'padding': '0',
            'margin-left': '120px',
            'left': - U * T
          }).children().css({
            'float': 'left',
            'width': N
          });
          break;
        case 'topLoop':
        case 'topMarquee':
          O.children().clone().appendTo(O).clone().prependTo(O);
          O.wrap('<div class="tempWrap" style="overflow:hidden; position:relative; height:' + Q.vis * S + 'px"></div>').css({
            'height': U * S * 3,
            'position': 'relative',
            'padding': '0',
            'margin': '0',
            'top': - U * S
          }).children().css({
            'height': J
          });
          break
      }
      var P = function () {
        switch (Q.effect) {
          case 'fade':
          case 'top':
          case 'left':
            if (D >= M) {
              D = 0
            } else {
              if (D < 0) {
                D = M - 1
              }
            }
            break;
          case 'leftMarquee':
          case 'topMarquee':
            if (D >= 2) {
              D = 1
            } else {
              if (D < 0) {
                D = 0
              }
            }
            break;
          case 'leftLoop':
          case 'topLoop':
            var Y = D - L;
            if (M > 2 && Y == - (M - 1)) {
              Y = 1
            }
            if (M > 2 && Y == (M - 1)) {
              Y = - 1
            }
            var W = Math.abs(Y * Q.scroll);
            if (D >= M) {
              D = 0
            } else {
              if (D < 0) {
                D = M - 1
              }
            }
            break
        }
        switch (Q.effect) {
          case 'fade':
            O.children().stop(true, true).eq(D).fadeIn(Q.delayTime).siblings().hide();
            break;
          case 'top':
            O.stop(true, true).animate({
              'top': - D * Q.scroll * S
            }, Q.delayTime);
            break;
          case 'left':
            O.stop(true, true).animate({
              'left': - D * Q.scroll * T
            }, Q.delayTime);
            break;
          case 'leftLoop':
            if (Y < 0) {
              O.stop(true, true).animate({
                'left': - (U - W) * T
              }, Q.delayTime, function () {
                for (var Z = 0; Z < W; Z++) {
                  O.children().last().prependTo(O)
                }
                O.css('left', - U * T)
              })
            } else {
              O.stop(true, true).animate({
                'left': - (U + W) * T
              }, Q.delayTime, function () {
                for (var Z = 0; Z < W; Z++) {
                  O.children().first().appendTo(O)
                }
                O.css('left', - U * T)
              })
            }
            break;
          case 'topLoop':
            if (Y < 0) {
              O.stop(true, true).animate({
                'top': - (U - W) * S
              }, Q.delayTime, function () {
                for (var Z = 0; Z < W; Z++) {
                  O.children().last().prependTo(O)
                }
                O.css('top', - U * S)
              })
            } else {
              O.stop(true, true).animate({
                'top': - (U + W) * S
              }, Q.delayTime, function () {
                for (var Z = 0; Z < W; Z++) {
                  O.children().first().appendTo(O)
                }
                O.css('top', - U * S)
              })
            }
            break;
          case 'leftMarquee':
            var V = O.css('left').replace('px', '');
            if (D == 0) {
              O.animate({
                'left': ++V
              }, 0, function () {
                if (O.css('left').replace('px', '') >= 0) {
                  for (var Z = 0; Z < U; Z++) {
                    O.children().last().prependTo(O)
                  }
                  O.css('left', - U * T)
                }
              })
            } else {
              O.animate({
                'left': --V
              }, 0, function () {
                if (O.css('left').replace('px', '') <= - U * T * 2) {
                  for (var Z = 0; Z < U; Z++) {
                    O.children().first().appendTo(O)
                  }
                  O.css('left', - U * T)
                }
              })
            }
            break;
          case 'topMarquee':
            var X = O.css('top').replace('px', '');
            if (D == 0) {
              O.animate({
                'top': ++X
              }, 0, function () {
                if (O.css('top').replace('px', '') >= 0) {
                  for (var Z = 0; Z < U; Z++) {
                    O.children().last().prependTo(O)
                  }
                  O.css('top', - U * S)
                }
              })
            } else {
              O.animate({
                'top': --X
              }, 0, function () {
                if (O.css('top').replace('px', '') <= - U * S * 2) {
                  for (var Z = 0; Z < U; Z++) {
                    O.children().first().appendTo(O)
                  }
                  O.css('top', - U * S)
                }
              })
            }
            break
        }
        C.removeClass(Q.titOnClassName).eq(D).addClass(Q.titOnClassName);
        L = D
    };
    P();
    if (K) {
      if (Q.effect == 'leftMarquee' || Q.effect == 'topMarquee') {
        D++;
        H = setInterval(P, Q.interTime);
        O.hover(function () {
          if (K) {
            clearInterval(H)
          }
        }, function () {
          if (K) {
            clearInterval(H);
            H = setInterval(P, Q.interTime)
          }
        })
      } else {
        H = setInterval(function () {
          D++;
          P()
        }, Q.interTime);
        A(this).hover(function () {
          if (K) {
            clearInterval(H)
          }
        }, function () {
          if (K) {
            clearInterval(H);
            H = setInterval(function () {
              D++;
              P()
            }, Q.interTime)
          }
        })
      }
  }
  var R;
  if (Q.trigger == 'onclick') {
    C.hover(function () {
      clearTimeout(R);
      D = C.index(this);
      R = window.setTimeout(P, 200)
    }, function () {
      if (!R) {
        clearTimeout(R)
      }
    })
} else {
  C.click(function () {
    D = C.index(this);
    P()
  })
}
E.click(function () {
D++;
P()
});
I.click(function () {
D--;
P()
})
})
}
}) (jQuery);
推荐问题
宣传栏