js动画 - 猜杯子游戏

2019-11-28  本文已影响0人  叫我魏大川
屏幕快照 2019-12-03 下午4.37.15.png

要点1:通过css3动画设置拿起杯子动画。
要点2:在js中动态设置css动画设置。
要点3:使用数组记录杯子元素的状态和顺序,随机两个元素作为运动对象。
要点4:按照顺时针设置每条运动路线的运动轨迹,穷举,总共六条路线,即六个动画样式。
要点5:通过z-index处理运动时的杯子遮盖问题,走上面的在后面,走下面的在前边。

抛砖引玉贴代码。注释已经写到代码中了。

<template>
    <div class="backviewx">
        <div class="wwarp">

            <div class="firstpage">
                <div :class="showTitle? 'titleClass':'titleClass2'" >{{ titleText }}</div>
                <div :class="showLastTitle? 'decriptionClass':'decriptionClass2' " >{{lastTitletext }}</div>
                <div class="midelClass">
                    <img id="cupbackclass" src="../../assets/guesscup_backview.png" alt="">

                    <div class="cupcalss">
                        <div class="item" id="item1" @click="touchCup(1)" style="z-index: 1002">
                            <div class="box" id="box1">
                                <img class="gold" id="gold1"  src="../../assets/guesscup_gold.png" alt="">
                                <img class="cup" id="cup1" src="../../assets/guesscup_cupimg.png" alt="">
                            </div>
                        </div>
                        <div  class="item" id="item2" @click="touchCup(2)" style="z-index: 1002">
                            <div class="box" id="box2">
                                <img class="gold" id="gold2"  src="../../assets/guesscup_gold.png" alt="">
                                <img class="cup" id="cup2" src="../../assets/guesscup_cupimg.png" alt="">
                            </div>
                        </div>
                        <div  class="item" id="item3" @click="touchCup(3)" style="z-index: 1002">
                            <div class="box" id="box3">
                                <img class="gold" id="gold3"  src="../../assets/guesscup_gold.png" alt="">
                                <img class="cup" id="cup3" src="../../assets/guesscup_cupimg.png" alt="">
                            </div>
                        </div>
                        <img v-show="showHand" class="handClass" id="handClass1" src="../../assets/guide_2_hand.png" alt="">
                    </div>
                    
                </div>
                <img :class=" showLastBton?'bottomBton':'bottomBton2' " id="botombtonid"  src="../../assets/guesscip_startimg.png" alt="" @click="run">
            </div>
            
        </div>
    </div>
</template>

<script>
// import { createNamespacedHelpers } from 'vuex';

export default {
    props: {
        //是否应该中奖
        sholdLuky:{
            type:Boolean,
            default: () => {
                return false;
            },
        },
    },
    data(){
        return{
            showTitle: true,      //标题显示
            showLastTitle: true,  //副标题显示
            showLastBton: true,   //显示底部按钮

            showHand: false,      //小手
            titleText: '答对啦',    //标题
            lastTitletext: '恭喜您拥有一次赢奖励的机会',    //副标题
            hadUpCupIndex: 0, 
            itemxArray:[],         //按照从左到右存储item(杯子容器),用来标记item的顺序。
            cupChangeMaxNum: 20,    //杯子交换次数
            cupChangeNum: 0,       //杯子当前的交换次数

        }
    },
    components:{
        // examQuestion,
    },
    created() {
        // this.hadUpCupIndex = -1;
    },
    mounted(){
        let item1 = document.getElementById('item1');
        let item2 = document.getElementById('item2');
        let item3 = document.getElementById('item3');
        this.itemxArray = [item1, item2, item3];
    },
    methods:{
        //关闭
        closeAction(){
            this.$emit('closAlert');
        },

        // 触发动画
       run(){
           if(this.hadUpCupIndex>0){
               this.$emit('close');
            }else{
                this.showTitle = false;
                this.showLastTitle = false;
                this.showLastBton = false;

                let cup = document.getElementById('cup2');
                this.pickUpCup(cup);
                setTimeout(() => {
                    this.backUpCup(cup);
                }, 1000);

                // 2秒后开始执行移动杯子动画。
                setTimeout(() => {
                    this.startMoveCup();
                }, 2000);
            }
       },

       startMoveCup(){
           //    随机从数组中取两个item
            let randomArr = this.getArrRandomly(this.itemxArray, 2);
            let randomItem1 = randomArr[0];
            let randomItem2 = randomArr[1];
            let randomItem1Index = this.itemxArray.indexOf(randomItem1);
            let randomItem2Index = this.itemxArray.indexOf(randomItem2);
            // console.log('随机出的数组', randomArr);

            // 交换两个位置的元素,
            // console.log('准备交换的数组:', this.itemxArray);
            [this.itemxArray[randomItem1Index],this.itemxArray[randomItem2Index]] = [this.itemxArray[randomItem2Index],this.itemxArray[randomItem1Index]];
            // console.log('交换后的额数组:', this.itemxArray);
            
            let item1AnmationName = '';
            let item2AnmationName = '';
            let zindex1 = 1002;
            let zindex2 = 1002;
            if(randomItem1Index == 0 && randomItem2Index == 1){
                item1AnmationName = 'a';
                item2AnmationName = 'f';
                zindex1 = 1001;
                zindex2 = 1003;
            }else if(randomItem1Index == 0 && randomItem2Index == 2){
                item1AnmationName = 'b';
                item2AnmationName = 'e';
                zindex1 = 1001;
                zindex2 = 1003;
            }else if(randomItem1Index == 1 && randomItem2Index == 2){
                item1AnmationName = 'c';
                item2AnmationName = 'd';
                zindex1 = 1001;
                zindex2 = 1003;
            }else if(randomItem1Index == 2 && randomItem2Index == 1){
                item1AnmationName = 'd';
                item2AnmationName = 'c';
                zindex1 = 1003;
                zindex2 = 1001;
            }else if(randomItem1Index == 2 && randomItem2Index == 0){
                item1AnmationName = 'e';
                item2AnmationName = 'b';
                zindex1 = 1003;
                zindex2 = 1001;
            }else if(randomItem1Index == 1 && randomItem2Index == 0){
                item1AnmationName = 'f';
                item2AnmationName = 'a';
                zindex1 = 1003;
                zindex2 = 1001;
            }

            let leftArray = ['10%', '39%', '68%'];
            
            // console.log(item1AnmationName, item2AnmationName);
            randomItem1.classList.add(item1AnmationName);
            randomItem2.classList.add(item2AnmationName);
            randomItem1.style.zIndex = zindex1;
            randomItem2.style.zIndex = zindex2;
            let randomItem3 = '';
            for(let i=0; i<this.itemxArray.length; i++){
                if(this.itemxArray[i].id != randomItem1.id && this.itemxArray[i].id != randomItem2.id){
                    randomItem3 =  this.itemxArray[I];
                }
            }
            randomItem3.style.zIndex = 1002;
            
            // console.log('numxxx1', this.cupChangeNum);
            // console.log('打印zidnex', randomItem1, randomItem1.style.zIndex, randomItem2, randomItem2.style.zIndex, randomItem3, randomItem3.style.zIndex);
            let that = this;
            randomItem2.addEventListener('animationend', setLeft );

            function setLeft() {
                randomItem1.classList.remove(item1AnmationName);
                randomItem2.classList.remove(item2AnmationName);

                randomItem1.style.left = leftArray[randomItem2Index];
                randomItem2.style.left = leftArray[randomItem1Index];
                // console.log(randomItem1,leftArray[randomItem2Index],  randomItem2,leftArray[randomItem1Index]);

                randomItem2.removeEventListener('animationend',setLeft);
                
                // console.log('ddd' + that.cupChangeNum );

                console.log('numxxx2', that.cupChangeNum);
                setTimeout( ()=>{
                    jugeLoop(that);
                }, 1);
                // jugeLoop(that);

                function jugeLoop(that) {
        
                    that.cupChangeNum = that.cupChangeNum+1;
                    // console.log('numxxx3', that.cupChangeNum);
                    if(that.cupChangeNum < that.cupChangeMaxNum){
                        that.startMoveCup();
                    }else{
                        // this.hadUpCupIndex = 0;
                        that.lastTitletext = '猜猜奖励在哪,请点击杯子~';
                        that.showHand = true;
                        that.moveHand();
                    }
                }
            } 

       },

       //随机获取数组中的两个不同元素。先打乱数组顺序,再取前两位。
        getArrRandomly(arr, num){

            let carr = arr.concat();
            var len = carr.length;
            for (var i = len - 1; i >= 0; i--) {
                var randomIndex = Math.floor(Math.random() * (i + 1));
                var itemIndex = carr[randomIndex];
                carr[randomIndex] = carr[I];
                carr[i] = itemIndex;
            }

            const tmpArr = carr;
            let arrList = [];
            for (let i = 0; i < num; i++) {
                arrList.push(tmpArr[i]);
            };
            // console.log(arrList);
            
            return arrList;
        },

        

    //    盒子点击触发事件
       touchCup(index){

           if(this.showHand == false){
               return;
           }

           this.showHand = false;

           let viewName = 'cup'+index;
           let cupbox1 = document.getElementById(viewName);

           if(this.hadUpCupIndex == 0){
                this.hadUpCupIndex = index;
                this.pickUpCup(cupbox1);

                //在这里加判断是否让他中奖的逻辑
                if(this.sholdLuky){
                    setTimeout(() => {
                        this.$emit('hadLuckey');
                    }, 2000);
                }else{
                    this.showTitle = true;
                    this.showLastTitle = true;
                    this.showLastBton = true;
                    this.titleText = '很遗憾!';
                    this.lastTitletext = '没猜中,请明天再来哦~';
                    document.getElementById('botombtonid').src = require('../../assets/medal_close_img.png');

                    let goldView = document.getElementById('gold'+index);
                    goldView.style.visibility = 'hidden';

                    //随机一个开奖
                    let arrvv = [1, 2, 3];
                    for(let i=0; i<3; i++){
                        if(arrvv[i] == index){
                            arrvv.splice(i, 1);
                        }
                    }
                    // console.log(arrvv);
                    let indexxxx =  arrvv[Math.floor((Math.random()*arrvv.length))];
                    this.pickUpCup(document.getElementById('cup'+indexxxx));
                }
           }
           
       },

    //    移动小手
       moveHand(){
            document.getElementById('handClass1').classList.add('moveHandclass');
        },
    //    抬起盒子
       pickUpCup(cup){
            let animationName1 = 'pickupCupbox';
            cup.style = "animation-duration: 0.2s;animation-timing-function: cubic-bezier(0,0,0,0);animation-fill-mode:forwards;animation-name: "+animationName1;
       },
    //    落下盒子
       backUpCup(cup){
            let animationName1 = 'pickupCupboxBack';
            cup.style = "animation-duration: 0.2s;animation-timing-function: cubic-bezier(0,0,0,0);animation-fill-mode:forwards;animation-name: "+animationName1;
       }
    },
}
</script>

<style >
.backviewx{
    position: fixed;
    z-index: 9998;
    background-color: rgba(0, 0, 0, 0.8);
    left: 0px;
    right: 0px;
    top: 0px;
    bottom: 0px;
    overflow: scroll;
}
.wwarp{
    position: fixed;
    display: flex;
    left: 0;
    right: 0;
    top: 0;
    bottom :0; 
    z-index: 9999;
    justify-content: center;
    align-items: center;
    overflow: auto;
}
.firstpage{
    position: relative;
    width: 100%;
    max-width: 400px;
    margin:auto;
    /* background-color: aquamarine; */
    text-align: center;
    color: white;
}
.titleClass{
    color: #FFDD18;
    font-size: 26px;
    visibility: visible;
}
.titleClass2{
    color: #FFDD18;
    font-size: 26px;
    visibility: hidden;
}
.decriptionClass{
    color: #FFFFFF;
    font-size: 20px;
    margin-top: 20px;
    visibility: visible;
}
.decriptionClass2{
    color: #FFFFFF;
    font-size: 20px;
    margin-top: 20px;
    visibility: hidden;
}
.midelClass{
    position: relative;
    width: 100%;
}
#cupbackclass{
    width: 100%;
}
.cupcalss{
    position: absolute;
    top: 30%;
    width: 100%;
    height: 120px;
    /* background-color: #FFDD18; */
}
#item1{
    position: absolute;
    width: 22%;
    left: 10%;
    top: 0px;
    /* background-color: gray; */
}
#item2{
    position: absolute;
    width: 22%;
    left: 39%;
    top: 0px;
    /* background-color: blueviolet; */
}
#item3{
    position: absolute;
    width: 22%;
    left: 68%;
    top: 0px;
    /* background-color: aquamarine; */
}
.box{
    position: relative;
    width: 100%;
    height: 120px;
    /* background-color: orange; */
}
.cup{
    width: 100%;
    position: absolute;
    top: 0px;
    left: 0px;
    /* background-color: aquamarine; */
}
.gold{
    position: absolute;
    top: 45%;
    left: 20%;
    width: 60%;
    /* background-color: gray; */
}
.bottomBton{
    width: 60%;
    visibility: visible;
}
.bottomBton2{
    width: 60%;
    visibility: hidden;
}

#cup1box{
    background-color: green;
    position: absolute;
    left: 0px;
    top: 0px;
    width: 100%;
    height: 100%;
}
.handClass{
    position: absolute;
    top: 80%;
    left: 10%;
    width: 40px;
    z-index: 1100;
}

.pickupCupboxClass{
    animation-duration: 0.2s;
    animation-timing-function: cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
    animation-name: pickupCupbox;
}
@keyframes pickupCupbox {
    0% { }
    100% {left: 30px;top: -60px;transform:rotate(20deg);}
}
.pickupCupboxBackClass{
    animation-duration: 0.2s;
    animation-timing-function: cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
    animation-name: pickupCupboxBack;
}
@keyframes pickupCupboxBack {
    0% {left: 30px;top: -60px;transform:rotate(20deg);}
    100% {left: 0px;top: 0px;transform:rotate(0deg);}
}

.moveHandclass{
    animation-duration: 1.5s;
    animation-timing-function: cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
    animation-direction:alternate; 
    animation-iteration-count:100; 
    animation-name: moveHand
}
@keyframes moveHand {
    0%   { left: 10%; }
    100% { left: 90%; }
}

/* 下面是盒子运动的总共6个路线 */
.a{
    animation-name: ax;
    animation-duration: 0.15s;
    animation-timing-function:cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
}
@keyframes ax{
    0%   { left: 10%; top: 0px }
    50%  { top: -40px }
    100% { left: 39%; top: 0px}
}

.b{
    animation-name: bx;
    animation-duration: 0.15s;
    animation-timing-function:cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
}
@keyframes bx{
    0%   { left: 10%; top: 0px }
    50%  { top: -40px }
    100% { left: 68%; top: 0px}
}

.c{
    animation-name: cx;
    animation-duration: 0.15s;
    animation-timing-function:cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
}
@keyframes cx{
    0%   { left: 39%; top: 0px }
    50%  { top: -40px }
    100% { left: 68%; top: 0px}
}

.d{
    animation-name: dx;
    animation-duration: 0.15s;
    animation-timing-function:cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
}
@keyframes dx{
    0%   { left: 68%; top: 0px }
    50%  { top: 40px }
    100% { left: 39%; top: 0px}
}

.e{
    animation-name: ex;
    animation-duration: 0.15s;
    animation-timing-function:cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
}
@keyframes ex{
    0%   { left: 68%; top: 0px }
    50%  { top: 40px }
    100% { left: 10%; top: 0px}
}

.f{
    animation-name: fx;
    animation-duration: 0.15s;
    animation-timing-function:cubic-bezier(0,0,0,0);
    animation-fill-mode:forwards;
}
@keyframes fx{
    0%   { left: 39%; top: 0px }
    50%  { top: 40px }
    100% { left: 10%; top: 0px}
}


</style>
上一篇下一篇

猜你喜欢

热点阅读