Vue高仿阿里动态banner,制作组件

banner.vue

// 使用标签变量为必须,动态计算动画 
// 传入的变量依赖于index下标,此处默认无属性,遍历添加index
// 鼠标移入以及移出事件,可以循环修改style属性,也可以动态添加开关控制,两种均可
// 传入的数组长度最多为14,大于这个长度的时候需要自行修改css动画样式
<template>
    <div class="bg-color">
        <div class="rotationchart rotationchart_block" style=" 1250px;">
            <div class="ui_base u_p3d">
                <div class="earth">
                    <!-- <img src="../assets/img/b2b/logo.png"/> -->
                    <h2>logo</h2>
                </div>
                <div class="guiji_1"></div>
                <div class="guiji_2"></div>
                <div class="guiji_3"></div>
                <div class="ball_body_line1">
                    <div class="ball ball1" :style="'--i:' + item.index+';animation-play-state:'+flag"  v-for="item in firstList" :key="item">
                        <div class="content"><a target="_blank">{{item.name}}</a></div>
                    </div>
                </div>
                <div class="ball_body_line2">
                  <div class="ball ball1" :style="'--i:' + item.index+';animation-play-state:'+flag" v-for="item in secondList" :key="item">
                        <div class="content"><a target="_blank">{{item.name}}</a></div>
                    </div>
                </div>
            </div>
        </div>
      </div>
</template>

<script>
export default {
     props: {
      firstList: {
        type: Array
      },
      secondList: {
        type: Array,
      }
    },
    data(){
       return{
           flag:'running',
           firstList:this.props.firstList,
           secondList:this.props.secondList,
       }
   },
   created(){
    this.init();
   },
   mounted(){
    // 事件添加
    this.control();
  },
   methods:{
        init(){
            if(this.firstList){
                let index = 0;
                this.firstList.map(item => {
                    item.index = index++;
                })
            }
        if(this.secondList){
                let index = 0;
                this.secondList.map(item => {
                    item.index = index++;
                })
            }   
        },
        control(){
            
            // let _this = this;
            // let ballArr = document.querySelectorAll('.ball');
            // for(let i=0;i<ballArr.length;i++){
            //     ballArr[i].onmouseover = function(){
            //         _this.flag = 'paused';
            //     }
            //     ballArr[i].onmouseout = function(){
            //         _this.flag = 'running';
            //     }
            // }

            let ballArr = document.querySelectorAll('.ball');
            for(let i=0;i<ballArr.length;i++){
            ballArr[i].onmouseover = function(){
                for(let i=0;i<ballArr.length;i++){
                ballArr[i].style.animationPlayState = 'paused'
                }
            }
            ballArr[i].onmouseout = function(){
                for(let i=0;i<ballArr.length;i++){
                ballArr[i].style.animationPlayState = 'running'
                }
            }
            }
       }
   }
}
</script>

<style>
a:active{text-decoration:none;}
a:hover{text-decoration:none; }
.rotationchart {
    display: none;
    background: url(bg.png) no-repeat;
    background-size: 100% 100%;
    font-family: microsoft yahei;
    position: relative;
    overflow: hidden;
    height: 650px;
    margin: 0 auto;
}

.bg-color {
    height: 650px;
    background-color: #270151;
    position: relative;
    margin-bottom: 70px;
}
.bg-color::before {
    content: "";
    display: block;
    position: absolute;
    right: 0;
     50%;
    height: 100%;
    background-color: #04002d;
}

.rotationchart_block {
     1250px;
    display: block;
}

.ui_base {
    position: relative;
    top: 75px;
}

.rotationchart .earth {
    display: block;
    -webkit-transform-origin: 50% 50%;
    -ms-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    position: absolute;
     465px;
    height: 460px;
    line-height: 460px;
    text-align: center;
    background: url(earth.png) no-repeat;
    background-size: cover;
    left: 50%;
    margin-left: -255px;
    top: 30px;
    color: #fff;
    font-size: 24px;
}
.rotationchart .earth img{
     231px;
    height: 84px;
    margin-top: -110px;
}
.rotationchart .earth h2{
    margin-top: -50px;
    text-transform:uppercase;
}
.rotationchart .earth::after {
    content:"副标题";
    display: block;
    100%;
    height: fit-content;
    position: absolute;
    bottom: -4%;
    font-size: 32px;
    font-weight: 600;

}

.rotationchart .guiji_1 {
    pointer-events: none;
    position: absolute;
     1100px;
    height: 220px;
    background: url(line1.png) no-repeat;
    background-size: 100% 100%;
    top: 115px;
    left: 50%;
    margin-left: -550px;
}

.rotationchart .guiji_2 {
    pointer-events: none;
    position: absolute;
     950px;
    height: 220px;
    background: url(line2.png) no-repeat;
    background-size: 100% 100%;
    top: 220px;
    left: 50%;
    margin-left: -485px;
}

.rotationchart .guiji_3 {
    pointer-events: none;
    position: absolute;
     700px;
    height: 220px;
    background: url(line3.png) no-repeat;
    background-size: 100% 100%;
    top: 317px;
    left: 50%;
    margin-left: -350px;
}

.ball_body_line1 {
    position: absolute;
    top: 91px;
    left: 49%;
    margin-left: -550px;
    z-index: 10;
}

.ball_body_line2 {
    position: absolute;
    top: 194px;
    left: 50%;
    margin-left: -497px;
}

.ball_body_line1>div {
    animation: animXline1 15s cubic-bezier(0.36, 0, 0.64, 1) calc(-4.2855s* var(--i) - 7.5s) infinite alternate,
        animYline1 15s cubic-bezier(0.36, 0, 0.64, 1) calc(-4.2855s * var(--i)) infinite alternate,
        scale 30s cubic-bezier(0.36, 0, 0.64, 1) calc(-4.2855s * var(--i)) infinite alternate;
}

.ball_body_line2>div {
    animation: animXline2 15s cubic-bezier(0.36, 0, 0.64, 1) calc(-4.2855s* var(--i) - 7.5s) infinite alternate,
        animYline2 15s cubic-bezier(0.36, 0, 0.64, 1) calc(-4.2855s * var(--i)) infinite alternate,
        scale 30s cubic-bezier(0.36, 0, 0.64, 1) calc(-4.2855s * var(--i)) infinite alternate;
}

.ball {
     20px;
    height: 20px;
    border-radius: 50%;
    position: absolute;
    cursor: pointer;
    font-size: 22px;
    background: -o-linear-gradient(281deg, #00ffff 0%, #ffffff 100%);
    background: linear-gradient(169deg, #00ffff 0%, #ffffff 100%);
    -webkit-box-shadow: 0px -1px 7px 4px #00ffff;
    box-shadow: 0px -1px 7px 4px #00ffff;
}
.ball:hover {
    animation-play-state: paused;
}
.ball .content {
     160px;
    height: 30px;
    text-align: center;
    position: absolute;
    top: 30px;
    left: 50%;
    margin-left: -80px;
    overflow: hidden;
}

.ball .content a,
.ball .content span {
    font-size: 16px;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight: 400;
    color: #ffffff;
    line-height: 28px;
}

@keyframes animXline1 {
    0% {
        left: 0px;
    }

    100% {
        left: 1100px;
    }
}

@keyframes animYline1 {
    0% {
        top: 0px;
    }

    100% {
        top: 220px;
    }
}

@keyframes animXline2 {
    0% {
        left: 0px;
    }

    100% {
        left: 950px;
    }
}

@keyframes animYline2 {
    0% {
        top: 0px;
    }

    100% {
        top: 220px;
    }
}


@keyframes scale {
    0% {
        -webkit-transform: scale(1);
        transform: scale(1);
    }

    50% {
        -webkit-transform: scale(1);
        transform: scale(1);
    }

    100% {
        -webkit-transform: scale(1);
        transform: scale(1);
    }
}
</style>
愿以往所学皆有所获
原文地址:https://www.cnblogs.com/Azune/p/14602245.html