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>