在vue脚手架中,学习实现一个轮播图(2-旋转木马)

目录

效果展示:

index.html:

template:

data:

methods:

mounted():

style:


效果展示:

轮播图(旋转木马)

index.html:

    <style type="text/css">
        *{
            box-sizing: border-box;
            overflow: hidden;
        }
    </style>

template:

<template>
  <div class="outest">
    <div class="before-ul" @click="user_move(-1)">&lt;</div>
    <!-- 旋转木马轮播图 -->
    <ul class="content" style="left:0px" ref="ul">
        <li ref="li" v-for="e of images" :key="e.id" style="transform:scale(1);opacity:0.68;zIndex:0;">
            <img class="picture"  :src="e.src" :alt="e.alt">
            <div class="text">{{e.alt}}</div>
        </li>
    </ul>
    <div class="after-ul" @click="user_move(1)">&gt;</div>
    <!-- 底部的圆点 -->
    <div>
        <ul class="sub-circle">
            <li ref="circle" v-for="e of images" :key="e.id"></li>
        </ul>
    </div>
  </div>
</template>

data:

        图片素材来自网络!

        return{
            images:[
                {src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fss2.meipian.me%2Fusers%2F120470823%2F80cf36c23f744bdf992abb21619714dc.jpeg%3Fmeipian-raw%2Fbucket%2Fivwen%2Fkey%2FdXNlcnMvMTIwNDcwODIzLzgwY2YzNmMyM2Y3NDRiZGY5OTJhYmIyMTYxOTcxNGRjLmpwZWc%3D%2Fsign%2F41e170ae81aa27e57d5687de957d9609.jpg&refer=http%3A%2F%2Fss2.meipian.me&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387064&t=71853af48512807d15ee43cb3a41737a",alt:"滕王阁",id:"aaa"},
                {src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn%2F20170411%2F77c8-fyeceza2014459.jpg&refer=http%3A%2F%2Fn.sinaimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387194&t=763a6f4f2f6f61606b802285fb955be8",alt:"岳阳楼",id:"bbb"},
                {src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fnews.cnhubei.com%2Fa%2F10001%2F202202%2F536db75fa423794d829cb72eec0a0699.jpeg&refer=http%3A%2F%2Fnews.cnhubei.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387251&t=6a8b11f5a2c0447014185710b623a302",alt:"黄鹤楼",id:"ccc"},
                {src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fss2.meipian.me%2Fusers%2F5738464%2F2ff02d9e5837e9702d35886742752e0f.jpg%3Fmeipian-raw%2Fbucket%2Fivwen%2Fkey%2FdXNlcnMvNTczODQ2NC8yZmYwMmQ5ZTU4MzdlOTcwMmQzNTg4Njc0Mjc1MmUwZi5qcGc%3D%2Fsign%2Fe2a10a52c511e52abe6fb5006bcc78fe.jpg&refer=http%3A%2F%2Fss2.meipian.me&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387424&t=420622e9f16446deee38b3171f123ea3",alt:"鹤雀楼",id:"ddd"},
                {src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20180809%2F941e123006494773931d546abc5b57b3.jpeg&refer=http%3A%2F%2F5b0988e595225.cdn.sohucs.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387463&t=490048000ebfcda3a1b904271d9ab81d",alt:"蓬莱阁",id:"eee"},
            ],
            tipIndex:1,                 // 0-4 用于更新底部圆点  共 5个真实 li
            isChanging:false,           // 是否正在变换
            userChanging:false,         // 是否是用户触发的变换
        }

methods:

        moving(direction){              //控制ul移动的方法 1为 ul左移,-1为 ul右移
            if(direction != 1 && direction != -1){
                return;
            }
            this.isChanging = true;                     // “ 封闭式执行任务,新的任务不能打扰 ,不接新任务”
            if(direction === 1){
                if(this.tipIndex === 6){                //一个循环之后恢复初始化,即只有下标为 1 的li处于放大状态
                    this.tipIndex = 1;
                    this.adjust(this.tipIndex, 6, 0);
                }
                new Promise((res,rej)=>res(this.moveLeft())).then(val => this.tipIndex++);
            }else{
                if(this.tipIndex === 1){                // 先把ul整体瞬移到 以下标为6的li位于中间的位置 再进行右移
                    this.adjust(6, this.tipIndex, -1600);
                }
                new Promise((res,rej)=>res(this.moveRight())).then(val => {
                    if( -- this.tipIndex < 0){
                        this.tipIndex = 4;
                    }
                })
            }
        },
        moveLeft(){                     // ul 向左移动
            let index = this.tipIndex;
            //切换底部圆点
            this.$refs.circle[index%5].style.background="hsl(0,0%,90%)";
            this.$refs.circle[(index+1)%5].style.background='hsl(0,0%,60%)';
            let element = this.getEle('li');
            element[index+1].style.zIndex='10';
            element[index].style.zIndex='0';
            //切换图片 t为变换次数 共32次,每隔10毫秒变换一次,依照宽度来改变,每次左移32px,320ms后移动一个li的距离
            let t = 0;
            let moveLeft = setInterval(()=>{
                //整体移动ul
                this.getEle('ul')[0].style.left = Number.parseInt(this.getEle('ul')[0].style.left) - 10 + 'px';
                //下一个li放大,变清晰
                element[index+1].style.transform=`scale(${1 + 0.5 / 32 * t})`;
                element[index+1].style.opacity=`${0.36 + t * 0.02}`;
                //当前li缩小,变模糊
                element[index].style.transform=`scale(${1.5 - 0.5 / 32 * t})`;
                element[index].style.opacity=`${1 - t * 0.02}`;
                t++;
                if(t >= 32){        //运动一个li默认的宽度之后停止定时任务
                    if(this.userChanging){
                        this.userChanging = false;
                        window.timer = this.defaultTimer();
                    }
                    this.isChanging = false;
                    clearInterval(moveLeft);
                }
            },10);
        },
        moveRight(){                    // ul 向右移动
            let index = this.tipIndex;  //用this.tipIndex来更新圆点,用index来更新ul、li
            if(index === 1){
                index = 6;
            }else if(index === 0){
                index = 5;
            }

            this.$refs.circle[this.tipIndex % 5].style.background="hsl(0,0%,90%)";
            this.$refs.circle[(this.tipIndex - 1 < 0) ? 4 : (this.tipIndex - 1)].style.background='hsl(0,0%,60%)';
            let element = this.getEle('li');
            element[index-1].style.zIndex='10';
            element[index].style.zIndex='0';
            //切换图片 t为变换次数 共32次,每隔10毫秒变换一次,依照宽度来改变,每次右移32px,320ms后移动一个li的距离
            let t = 0;
            let moveright = setInterval(()=>{
                //整体移动ul
                this.getEle('ul')[0].style.left = Number.parseInt(this.getEle('ul')[0].style.left) + 10 + 'px';
                //上一个li放大,变清晰
                element[index-1].style.transform=`scale(${1 + 0.5 / 32 * t})`;
                element[index-1].style.opacity=`${0.36 + t * 0.02}`;
                //当前li缩小,变模糊
                element[index].style.transform=`scale(${1.5 - 0.5 / 32 * t})`;
                element[index].style.opacity=`${1 - t * 0.02}`;
                t++;
                if(t >= 32){        //运动一个li默认的宽度之后停止定时任务
                    this.isChanging = false;
                    if(this.userChanging){
                        this.userChanging = false;
                        window.timer = this.defaultTimer();
                    }
                    clearInterval(moveright);
                }
            },10);
        },
        adjust(largeIndex, smallIndex, left){
            let element = this.getEle('li');
            element[largeIndex].style.transform='scale(1.5)';
            element[largeIndex].style.opacity='1';
            element[largeIndex].style.zIndex='10';
            element[smallIndex].style.transform=`scale(1)`;          
            element[smallIndex].style.opacity=`0.36`;
            element[smallIndex].style.zIndex='0';
            this.getEle('ul')[0].style.left = left + 'px';
        },
        getEle(name){                   //封装一个操作dom的函数
            return document.getElementsByTagName(name);
        },
        // 调用这个函数用来给 window 添加一个 默认的定时器,
        // 只有在用户主动点击切换的时候这个定时器被清除,但执行完用户的切换后又将立马加上
        defaultTimer(){                 
            return setInterval(()=>{
                this.moving(1);      // 参数1 是默认向左整体移动ul  即将当前li缩小,下一个li放大
            },3500);
        },
        user_move(val){
            // 如果当前 window.timer 定时器正在进行切换动作 或者 用户此前点击的切换事件正在执行,则不在执行用户此次的动作
            if(this.isChanging || this.userChanging){       
                return;
            }
            clearInterval(window.timer);            // 先清除默认的定时器
            this.userChanging = true;               // 设置用户主动进行的切换动作正在执行
            this.moving(val);                       // 预执行
        }

mounted():

        //监视浏览器窗口的改变,当浏览器窗口最小化时,将默认定时器停掉,当浏览器可视时,再开启
        document.addEventListener('visibilitychange',()=>{          
            if(document.visibilityState === 'hidden'){
                clearInterval(window.timer);
            }else if(document.visibilityState === 'visible'){
                window.timer = this.defaultTimer();
            }
        })

        for(let i=0; i<3; i++){         //深克隆最前面四个li放在ul的后面
            let templi=this.getEle('li')[i].cloneNode(true);
            this.getEle('ul')[0].appendChild(templi);
        }

        let element = this.getEle('li');
        //初始化构造,将索引为 1 的li放大,变清晰
        element[this.tipIndex].style.transform='scale(1.5)';
        element[this.tipIndex].style.opacity='1';
        element[this.tipIndex].style.zIndex='10';
        this.$refs.circle[this.tipIndex].style.background='hsl(0,0%,60%)';
        // 全局默认定时器
        window.timer = this.defaultTimer();

style:

.outest{
    --custom-width:960px;
    --custom-height:400px;
    --custom-img-number:5;
    width: var(--custom-width);
    height: var(--custom-height);
    border-radius: 0.5rem;
    border: 1px solid hsl(0, 0%, 75%);
    position: relative;
}
.content{
    width:calc(var(--custom-width) * --custom-img-number);
    height: var(--custom-height);
    padding: 0;
    margin: 0;
    position: absolute;
    display: flex;
}
.content > li{
    width: calc(var(--custom-width) / 3);
    list-style: none;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background:hsl(0,0%,90%);
}
.picture{
    width: 100%;
    height: calc(var(--custom-height) / 2);
    margin-bottom: 0.5em;
}
.text{
    font-size: 1.3rem;
    font-weight: 800;
    text-align: center;
}

/** 向左向右按键 */
.before-ul,.after-ul{
    font-size: 1.5rem;
    font-weight: 900;
    padding: 0.3rem;
    background: hsl(0 ,0% ,80%) ;
    opacity: 0.4;
    z-index: 20;
    position: absolute;
    top: 50%;
    transform: translate(0,-50%) scaleY(2);
}
.before-ul{
    left:0px;
    border-top-right-radius: 0.3rem;
    border-bottom-right-radius: 0.3rem;
}
.after-ul{
    right: 0px;
    border-top-left-radius: 0.3rem;
    border-bottom-left-radius: 0.3rem;
}
.before-ul:active{
    color: hsl(0,90%,40%);
    box-shadow: 0.5px 0.5px;
}
.after-ul:active{
    color: hsl(0,90%,40%);
    box-shadow: 0.5px 0.5px;
}
.before-ul:hover{
    cursor: pointer;
    opacity: 1;
    font-weight: bolder;
}
.after-ul:hover{
    cursor: pointer;
    opacity: 1;
    font-weight: bolder;
}

/**底部小圆圈 */
.sub-circle{
    position: absolute;
    left: 3%;
    bottom: 20px;
    display: flex;
    justify-content: space-around;
    padding: 0px;
    margin: 0px;
    z-index: 100;
}
.sub-circle > li{
    list-style: none;
    padding: 0.5rem;
    margin: 0.1rem;
    border-radius: 180px;
    background: hsl(0, 0%, 90%);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bodyHealthy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值