轮播图实现

前言

做一下轮播图的效果

正文

1.轮播图实现要求:
页面:
1.视觉窗口,即可见区域
2.包含所有图片的容器
3.具体的每一张轮播图片
4,锚点列表, 点击可跳到具体某一页
5.左右切换按钮
让每一个轮播页大小刚好等于视图窗口大小
1.设置视图窗口宽度, 让超过的部分隐藏
2.设置包含所有图片的容器的宽度为 10000%, 目的是为了让容器足够大. 因为如果容器不够大的话容器中每一张图片就算设定了固定宽度也还是会受到挤压导致一定程度的变形.这里设置的宽度10000%为相对与父div(视图窗口)的100倍, 即100% * 100; 所以这个轮播图最多可装下100个轮播页面
4.设置每一个轮播页面的宽度为父div (容器) 1%, 刚好等于爷爷div (视图窗口) 的大小, 即 100% = 100% * 100 * 1% . 这时视图窗口div中就刚好可见一个轮播页.
页面代码:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>轮播图</title>
    <style media="screen">
    * {
    margin: 0;
    padding: 0;
    border: 0;
    }
    #container {
        width: 510px;
        height: 286px;
        margin: 0 auto;
        position: relative;
        background: pink;
        overflow: hidden;
    }

    #inner {
        width: 10000%;/*设置的宽度10000%为相对与视图窗口的100倍*/
        height: 100%;
        position: absolute;
        left: 0px;
        top: 0px;
    }

    #inner img {
        width: 1%;
        height: 100%;
        float: left;
    }
    .paganation {
        width: 100%;
        position: absolute;
        bottom: 10px;
        text-align: center;
    }
    .paganation span {
        padding: 5px 8px;
        background: #F2F2F2;
        color: red;
        border-radius: 50%;
        cursor: pointer
    }
    .paganation .selected {
        background: #888;
        color: white;
    }
    .arrow {
        position: absolute;
        top: 0;
        width: 30px;
        height: 286px;
        line-height: 286px;
        text-align: center;
        color: white;
        cursor: pointer;
    }
    #right {
        right: 0;
    }
    .arrow:hover {
        background: rgba(0, 0, 0, 0.5);
    }
    </style>
  </head>
  <body>
    <!--视图窗口 -->
	<div id="container">
    <!-- 包含所有图片的容器 -->
    <div id="inner" class="clear">
        <img style="background:red;" src="#1#" alt="">
        <img style="background:orange;" src="#2#" alt="">
        <img style="background:green;" src="#3#" alt="">
        <img style="background:cyan;" src="#4#" alt="">
        <img style="background:yellow;" src="#5#" alt="">
        <img style="background:purple;" src="#6#" alt="">
        <img style="background:pink;" src="#7#" alt="">
        <img style="background:blue;" src="#8#" alt="">
        <img style="background:red;" src="#1#" alt="">
    </div>
    <div class="paganation" id="paganation">
        <!-- 锚点列表 -->
        <span class="selected">1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
        <span>6</span>
        <span>7</span>
        <span>8</span>
    </div>
    <div id="left" class="arrow">
        <  <!-- 向左切换按钮 -->
    </div>
    <div id="right" class="arrow">
        >  <!-- 向右切换按钮 -->
    </div>
 </div>
  </body>
  <script type="text/javascript">

  </script>
</html>

js实现
1.改变索引, 添加class使对应锚点设为选中状态
2.计算这次滚动到终点时包含所有图片的容器需要相对与视图窗口左移的位置
3.清空定时器(防止开启多个重名定时器导致图片滚动速度收到影响)
4.开启定时器(刷新速度一般为10~20ms), 每一次将图片移动一定的距离, 直达到达这次移动重点时清空定时器
5.如何让轮播图自动滚动?
设置一个定时器(刷新速度没几秒一次), 每次调用一次轮播的移动函数
6.如何实现无缝轮播(最后一张转到第一张时的衔接)
在最后一张轮播图后复制一份第一张轮播图, 放到最后, 让第一页和最后一页完全相同
最后一张轮播图移动到终点时将包含所有图片的容器的左偏移量设为0, 即最后一张滚动到终点时瞬间将第一张轮播图放置于视图窗口中, 看起来就无缝了
7.让滚动速度为匀减速运动
在定时器中每一次移动距离可以设置为
移动距离 = (终点 - 当前位置) / 15;

js代码:

    let container = document.getElementById('container')
    let inner = document.getElementById('inner')
    let paganation = document.getElementById('paganation')
    let spanList = document.getElementById("paganation").getElementsByTagName('span')
    let right = document.getElementById('right')
    let left = document.getElementById('left')


    function Carousel(container, inner, spanList, left, right, speedControl = 15, autoRoll = true, slideCycle = 5000) {

          this.container = container; //组件容器, 包括所有
          this.inner = inner; //装载图片的容器
          this.spanList = spanList; //每页锚点
          this.left = left; //左移button
          this.right = right; //右移button
          this.speedControl = speedControl; //速度控制,值越小轮播跳转速度越快
          this.autoRoll = autoRoll; //是否自动滚动
          this.slideCycle = slideCycle; //滚动周期
          this.timer; //完成滚动的定时器
          var me = this
          this.distance = this.container.offsetWidth;

    console.log(spanList);
          if (left && right) {
            this.left.onclick = function() {
              if (me.clickFlag) {
                // clickFlag = false
                me.backward()
              }
            }
            this.right.onclick = function() {
              if (me.clickFlag) {
                // clickFlag = false
                me.forward()
              }
            }
          }


          for(let i=0; i < this.spanList.length; i++) {
              this.spanList[i].onclick= function() {
                  me.index = i;
                  me.routate();
              }
          }

          if (this.autoRoll) {
            this.timeAutoGo = setInterval(function() {
              me.index++
              if (this.index == spanList.length) {
                me.index = 0
              }
              me.routate()
            }, this.slideCycle)
          }

        }


    Carousel.prototype = {
      constructor:Carousel,
      index: 0,
      clickFlag: true,

      routate: function () {
          var start=this.inner.offsetLeft;//获取移动块移动前的left的开始坐标, (0,width, width*2, width*3 ...)
          var end=this.index*this.distance*(-1);//获取移动块移动结束的坐标。
          //计算公式即当移动到第三张图片时,图片下标为2乘以图片的宽度就是块的left值。
          var change=end-start;//偏移量
          this.clear();//先把按钮状态清除,再让对应按钮改变状态
          if(this.index==this.spanList.length){
              this.spanList[0].className="selected";
          }else{
              this.spanList[this.index].className="selected";
          }
          var me = this;
          clearInterval(me.timer);//开启计时器前先把之前的清除, 防止多次重复生成定时器,干扰操作,
          me.timer=setInterval(function() {
              var iCur = parseInt(me.getStyle(me.inner, 'left'));
              if(iCur == end){//当图片到达终点停止计时器
                  clearInterval(me.timer);
                  me.clickFlag = false;//当图片到达终点才能切换
                  if(me.index == me.spanList.length ){
                      me.inner.style.left = 0;    //无缝滚动
                      me.index=0; //当图片到最后一张时把它瞬间切换回第一张,由于都同一张图片不会影响效果
                      iCur = 0;
                      end = 0;    //让speed等于0, 即me.inner.style.left = 0;停止此次运动,否则结束时候会向左偏移
                  }
              }
              var speed = (end - iCur) / me.speedControl;
              speed = speed > 0 ? Math.ceil(speed): Math.floor(speed);
              me.inner.style.left = (speed + iCur) + "px";  //每次移动距离=change/maxT*ts
          }, 17);//每个17毫秒让块移动
      },


      forward:function(){
        this.index++
        if(this.index >this.spanList.length){
          this.index = 0
        }
        this.routate();
      },

        backward: function(){
            this.index--;
            //当图片下标到第一张让它返回到倒数第二张,
            //left值要变到最后一张才不影响过渡效果
            if(this.index<0){
                this.index=this.spanList.length-1;
                this.inner.style.left=(this.index+1)*this.distance*(-1)+"px";
            }
            this.routate();
          },

            //清除页面所有按钮状态颜色
            clear : function() {
                for(var i=0;i<this.spanList.length;i++){
                    this.spanList[i].className="";
                }
            },

          getStyle : function(obj, attr) {
              if(obj.currentStyle != undefined ){
                  return obj.currentStyle[attr];
              }
              else{
                 return getComputedStyle(obj, false)[attr];
              }
          }

    }


    var carousel = new Carousel(container, inner, spanList, left, right, 15, true);

最后

引用自:

https://blog.csdn.net/qq_37746973/article/details/80493324

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 轮实现可以使用 ViewPager 或者第三方库,这里以 ViewPager 为例: 1. 首先在布局文件中添加 ViewPager 和指示器(Indicator): ``` <androidx.viewpager.widget.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="200dp"/> <LinearLayout android:id="@+id/indicator" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:gravity="center" android:orientation="horizontal"/> ``` 2. 创建一个 Adapter 类,用于管理轮的数据和布局: ``` public class BannerAdapter extends PagerAdapter { private Context mContext; private List<Integer> mImages; public BannerAdapter(Context context, List<Integer> images) { mContext = context; mImages = images; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView = new ImageView(mContext); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setImageResource(mImages.get(position)); container.addView(imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } @Override public int getCount() { return mImages.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } } ``` 3. 在 Activity 或 Fragment 中设置 ViewPager 和指示器: ``` ViewPager viewPager = findViewById(R.id.viewPager); LinearLayout indicatorLayout = findViewById(R.id.indicator); BannerAdapter adapter = new BannerAdapter(this, images); viewPager.setAdapter(adapter); for (int i = 0; i < images.size(); i++) { ImageView imageView = new ImageView(this); imageView.setImageResource(R.drawable.indicator_selector); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); params.setMargins(10, 0, 10, 0); indicatorLayout.addView(imageView, params); } viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} @Override public void onPageSelected(int position) { for (int i = 0; i < indicatorLayout.getChildCount(); i++) { ImageView imageView = (ImageView) indicatorLayout.getChildAt(i); imageView.setSelected(i == position); } } @Override public void onPageScrollStateChanged(int state) {} }); ``` 这样就完成了一个简单的 Android 轮实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值