vue扭蛋机抽奖游戏

简易扭蛋机demo

这是一个使用CSS3和JavaScript实现的扭蛋机抽奖游戏。该游戏的主要功能是通过点击按钮进行抽奖,抽奖过程中会显示滚动的小球,最终随机停止并显示一个中奖小球。

该游戏的抽奖过程如下:

  1. 当用户点击抽奖按钮时,首先检查当前是否正在进行抽奖任务或者当前有小球正在滚动。如果有,则不执行抽奖操作。
  2. 如果满足抽奖条件,则设置抽奖状态为开始,并等待4秒钟。
  3. 4秒钟后,停止抽奖,并随机选择一个小球作为中奖结果。
  4. 开始滚动中奖小球,直到小球到达最终位置。
  5. 小球到达最终位置后,停止滚动并隐藏小球。

这个游戏的实现方式是通过CSS3的动画效果和JavaScript的定时器来控制小球的滚动和抽奖的过程。使用CSS3可以轻松地实现小球的滚动效果,而JavaScript则可以控制抽奖的流程和时间。

整体代码

HTML部分

html结构可根据自己需求重新开发,一下代码只是演示,抽奖思路,ball-box下面每个图片是根据index动态添加类名,在css中方便单独设置每个小球位置

<template>
    <div>
        <div class="raffle">
            <div class="collectors">
                <div class="top">Top 3 Xmas Balls Collectors</div>
                <div class="awards-list">
                    <div class="item" v-for="(item, index) in emailList" :key="index">aaa@aaa.com</div>
                </div>
            </div>
            <div class="lottery">
                <!-- 抽奖  -->
                <div class="ball-box" :class="{ 'active': !opportunityStatus }">
                    <img v-for="(item, index) in ballList" :key="index" :src="item" alt="" :class="`ball${index}`">
                </div>
                <!-- 抽奖次数 -->
                <div class="glass">
                    <div class="glass-list">
                        <div class="item">1 MORE CHANCE</div>
                    </div>
                    <img src="./img/glass.png" alt="">
                </div>
                <!-- 滚动小球  -->
                <img :src="lotteryBall" alt="" class="roll-ball" :class="{ 'active': rollBall }">
                <img src="./img/ball-base.png" alt="" class="ball-base">
                <img src="./img/games.png" alt="" class="games-img">
            </div>
            <!-- 抽奖按钮 -->
            <div class="play" @click="rafflePlay">
                <img src="./img/play-go.png" alt="">
            </div>
        </div>
    </div>
</template>
js部分

flexible文件因为布局使用rem,来计算自适应,ballList数组中的图片可自行修改

<script>
export default {
    data() {
        return {
            //抽奖小球
            ballList:[
                require('./img/ball-1.png'),
                require('./img/ball-2.png'),
                require('./img/ball-3.png'),
                require('./img/ball-4.png'),
                require('./img/ball-5.png'),
                require('./img/ball-6.png'),
                require('./img/ball-7.png'),
                require('./img/ball-8.png'),
                require('./img/ball-9.png'),
                require('./img/ball-10.png'),
                require('./img/ball-11.png'),
                require('./img/ball-12.png'),
                require('./img/ball-13.png'),
                require('./img/ball-14.png'),
            ],
            opportunityStatus:true,//抽奖状态,抽奖按钮是否能点击
        }
    },
    mounted() {
        import("public/js/flexible").then(() => {
        })
    },
    methods: {
        rafflePlay(){
            //判断当前是否在执行抽奖任务 当前出现的小球没有消失之前不能点击抽奖
            if(!this.opportunityStatus || this.rollBall) return
            this.opportunityStatus=false
            //抽奖进行4秒后停止出现出奖小球
            setTimeout(()=>{
                this.opportunityStatus=true
                //结束抽奖随机滚动出现一个小球
                this.lotteryBall=this.ballList[Math.floor(Math.random()*13)]
                //开始滚动小球
                this.rollBall=true
                //小球到最终位置后隐藏,这里的计时器,要比css中写的运动轨迹时间长一点,不然没有到终点小球就已经隐藏了
                setTimeout(()=>{
                    this.rollBall=false
                },5000)
            },4000)
        },
    }
}
</script>
css部分

@keyframes动效,这里我只列出了两个小球的运动轨迹,可自行添加

<style scoped lang="scss">
.raffle {
    width: 12.24rem;
    height: 9.01rem;
    background-color: #000;
    background-size: 100% 100%;
    border-radius: 0.6rem;
    padding-top: 0.67rem;
    box-sizing: border-box;
    margin: auto;
    position: relative;
    .title {
        display: block;
        margin: auto;
        height: 0.46rem;
        width: auto;
    }
    .collectors {
        position: absolute;
        right: -1.23rem;
        top: .64rem;
        width: 3.67rem;
        height: 1.61rem;
        background-image: url('../../../../img/cyberxmas/awards-bg.png');
        background-size: 100% 100%;
        .top {
            font-size: 0.2rem;
            font-weight: 400;
            color: #8BFFFB;
            text-align: center;
            padding-top: 0.62rem;
            box-sizing: border-box;
        }
        .awards-list {
            position: absolute;
            bottom: 0.23rem;
            margin: auto;
            right: 0;
            left: 0;
            height: 0.15rem;
            padding: 0.1rem 0;
            overflow: hidden;

            .item {
                text-align: center;
                font-size: 0.19rem;
                margin-bottom: 0.1rem;
                color: rgba(255, 255, 255, 0.83);
                -webkit-animation: 5s rowup linear infinite normal;
                animation: 5s rowup linear infinite normal;
            }
        }
    }
    .lottery {
        width: 5.78rem;
        height: 5.82rem;
        margin: auto;
        margin-top: 0.33rem;
        position: relative;

        .ball-box {
            position: absolute;
            right: 0;
            left: 0;
            top: -0.1rem;
            height: 3.68rem;
            width: 3.52rem;
            border-radius: 68%;
            margin: auto;
            padding: 0.6rem;
            position: relative;

            img {
                height: 0.88rem;
                width: auto;
                position: absolute;
            }

            .ball0 {
                transform: translate(-0.15rem, 1.6rem) rotate(0deg);
            }

            .ball1 {
                transform: translate(-.1rem, 2.2rem) rotate(0deg);
            }

            .ball2 {
                transform: translate(.6rem, 2.5rem) rotate(0deg);
                z-index: 1;
            }

            .ball3 {
                transform: translate(.6rem, 1.7rem) rotate(0deg);
            }

            .ball4 {
                transform: translate(1rem, 2.1rem) rotate(0deg);
                z-index: 1;
            }

            .ball5 {
                transform: translate(1.4rem, 2.2rem) rotate(0deg);
                z-index: 1;
            }

            .ball6 {
                transform: translate(1.4rem, 1.5rem) rotate(0deg);
                z-index: 1;
            }

            .ball7 {
                transform: translate(1.8rem, 1.9rem) rotate(0deg);
            }

            .ball8 {
                transform: translate(2.3rem, 2.4rem) rotate(0deg);
            }

            .ball9 {
                transform: translate(2.1rem, 1rem) rotate(0deg);
            }

            .ball10 {
                transform: translate(2.5rem, 1.7rem) rotate(0deg);
            }

            .ball11 {
                transform: translate(2.8rem, 1.7rem) rotate(0deg);
            }

            .ball12 {
                transform: translate(2.9rem, 2.1rem) rotate(0deg);
            }

            .ball13 {
                transform: translate(3rem, 1.2rem) rotate(0deg);
            }

            &.active {
                @for $i from 0 through 13 {
                    .ball#{$i} {
                        animation: around#{$i} 6s linear infinite;
                    }
                }
            }
        }

        .roll-ball {
            width: 0.43rem;
            height: auto;
            position: absolute;
            top: 2rem;
            left: 0.5rem;
            transform: translate(2.2rem, 2.97rem) rotate(0deg) scale(1.4);
            display: none;

            &.active {
                display: block;
                animation: rollball 3s linear;
                z-index: 2;
            }
        }

        .ball-base {
            width: 4.39rem;
            height: 1.5rem;
            display: block;
            position: absolute;
            left: 0.69rem;
            bottom: 0.2rem;
            z-index: 4;
        }

        .glass {
            width: 2.37rem;
            height: 0.36rem;
            position: absolute;
            bottom: 1.78rem;
            left: 1.73rem;
            font-size: 0.18rem;
            text-align: center;
            line-height: 0.36rem;
            color: #FFFFFF;
            opacity: 0.86;
            z-index: 5;
            overflow: hidden;

            .glass-list {
                display: flex;

                .item {
                    width: 2.4rem;
                    white-space: nowrap;
                }
            }

            img {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
            }
        }

        .games-img {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 1;
            width: 100%;
            height: 100%;
        }
    }
    .play {
        width: 1.47rem;
        height: 0.69rem;
        margin: auto;
        cursor: pointer;
        margin-top: 0.27rem;

        &:hover {
            opacity: 0.6;
        }

        img {
            width: 100%;
            height: 100%;
            display: block;
        }
    }
    //奖品展示
    .prize-left,
    .prize-right {
        width: 1.22rem;
        position: absolute;
        left: 1.14rem;
        bottom: 1.16rem;

        li {
            width: 100%;
            height: 1.56rem;
            background: rgba(118, 73, 175, 0.37);
            border: 0.02rem solid #5F4C86;
            border-radius: 0.08rem;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-top: 0.13rem;
            position: relative;

            .tips {
                position: absolute;
                top: -0.38rem;
                padding: 0.18rem;
                box-sizing: border-box;
                background: rgba(0, 0, 0, 0.42);
                border: 0.02rem solid #948CA4;
                border-radius: 0.02rem;
                font-size: 0.16rem;
                color: #FFFFFF;
                text-align: center;
                white-space: nowrap;
                display: none;
            }

            &:hover {
                .tips {
                    display: block;
                }
            }

            img {
                height: auto;
            }

            &:nth-child(1) {
                img {
                    width: 0.64rem;
                }
            }

            &:nth-child(2) {
                img {
                    width: 0.77rem;
                }
            }

            &:nth-child(3) {
                img {
                    width: 0.4rem;
                }
            }
        }
    }
    .prize-right {
        right: 1.07rem;
        left: initial;

        li:nth-child(1) {
            img {
                width: 0.84rem;
            }
        }

        li:nth-child(2) {
            img {
                width: 1.03rem;
            }
        }

        li:nth-child(3) {
            img {
                width: 0.91rem;
            }
        }
    }
}
@keyframes around0 {
    0% {
        transform: translate(0rem, 1.6rem) rotate(0deg);
    }
    5% {
      transform: translate(1.28rem, .1rem) rotate(50deg);
    }
    10% {
      transform: translate(.2rem, .43rem) rotate(70deg);
    }
    15% {
      transform: translate(.28rem, .2rem) rotate(260deg);
    }
    20% {
      transform: translate(.2rem, .8rem) rotate(80deg);
    }
    25% {
        transform: translate(0.9rem, -.1rem) rotate(140deg);
    }
    30% {
      transform: translate(1.2rem, .9rem ) rotate(60deg);
    }
    35% {
      transform: translate(2.2rem, -0.1rem) rotate(260deg);
    }
    40% {
      transform: translate(0.8rem, .27rem) rotate(260deg);
    }
    45% {
        transform: translate(2.1rem, 0.5rem) rotate(0deg);
    }
    50% {
      transform: translate(3rem, 1.5rem) rotate(0deg);
    }
    55% {
        transform: translate(0.82rem, -.1rem) rotate(50deg);
    }
    60% {
        transform: translate(.29rem, .2rem) rotate(70deg);
    }
    65% {
        transform: translate(.7rem, .9rem) rotate(260deg);
    }
    70% {
        transform: translate(1rem, .4rem) rotate(80deg);
    }
    75% {
        transform: translate(.7rem, 1.4rem) rotate(140deg);
    }
    80% {
        transform: translate(1.1rem, -.2rem) rotate(60deg);
    }
    85% {
        transform: translate(1rem, .6rem) rotate(260deg);
    }
    90% {
        transform: translate(2.6rem, 1.1rem) rotate(260deg);
    }
    95% {
        transform: translate(.1rem, 1.4rem) rotate(0deg);
    }
    100% {
        transform: translate(-0.15rem, 1.6rem) rotate(0deg);
    }
}
// ...... 0_13
@keyframes around13 {
    0% {
        transform: translate(3rem, 1.2rem) rotate(0deg);
    }
    5% {
        transform: translate(1.2rem, 0.4rem) rotate(260deg);
    }
    10% {
        transform: translate(.3rem, 2.3rem) rotate(70deg);
    }
    15% {
        transform: translate(2.3rem, 0rem) rotate(260deg);
    }
    20% {
        transform: translate(3rem, 2.1rem) rotate(260deg);
    }
    25% {
        transform: translate(0.4rem, .1rem) rotate(140deg);
    }
    30% {
        transform: translate(2.7rem, 1.3rem ) rotate(60deg);
    }
    35% {
        transform: translate(2.28rem, 2.1rem) rotate(50deg);
    }
    40% {
        transform: translate(.64rem, .1rem) rotate(260deg);
    }
    45% {
        transform: translate(-0.3rem, 2rem) rotate(0deg);
    }
    50% {
        transform: translate(1.5rem, -0.2rem) rotate(0deg);
    }
    55% {
        transform: translate(2rem, 2.2rem) rotate(60deg);
    }
    60% {
        transform: translate(.2rem, 0.1rem) rotate(70deg);
    }
    65% {
        transform: translate(2rem, 2rem) rotate(260deg);
    }
    70% {
        transform: translate(2.1rem, .3rem) rotate(260deg);
    }
    75% {
        transform: translate(3rem, 2.1rem) rotate(140deg);
    }
    80% {
        transform: translate(.2rem, 0.2rem) rotate(50deg);
    }
    85% {
        transform: translate(1.5rem, 1.8rem) rotate(80deg);
    }
    90% {
        transform: translate(2.4rem, .2rem) rotate(80deg);
    }
    95% {
        transform: translate(1rem, 2.2rem) rotate(0deg);
    }
    100% {
        transform: translate(3rem, 1.2rem) rotate(0deg);
    }
}
@keyframes rollball{
    0%{
        transform: translate(-.0rem, 0) rotate(0deg);
    }
    5%{
        transform: translate(-.28rem, 0) rotate(260deg);
    }
    10%{
        transform: translate(-.38rem, 0) rotate(70deg);
    }
    15%{
        transform: translate(-.48rem, 0) rotate(260deg);
    }
    20%{
        transform: translate(-.48rem, .2rem) rotate(260deg);
    }
    25%{
        transform: translate(-.48rem, .3rem) rotate(140deg);
    }
    30%{
        transform: translate(-.48rem, .4rem) rotate(60deg);
    }
    35%{
        transform: translate(-.48rem, .7rem) rotate(50deg);
    }
    40%{
        transform: translate(-.48rem, 1rem) rotate(260deg);
    }
    45%{
        transform: translate(-.48rem, 1.2rem) rotate(0deg);
    }
    50%{
        transform: translate(-.48rem, 1.5rem) rotate(0deg);
    }
    55%{
        transform: translate(-.48rem, 1.7rem) rotate(60deg);
    }
    60%{
        transform: translate(-.48rem, 2.07rem) rotate(70deg);
    }
    65%{
        transform: translate(-.48rem, 2.57rem) rotate(260deg);
        z-index: 2;
    }
    70%{
        transform: translate(-.28rem, 2.57rem) rotate(260deg);
        z-index: 2;
    }
    75%{
        transform: translate(.6rem, 2.97rem) rotate(140deg);
        z-index: 2;
    }
    80%{
        transform: translate(1rem, 2.97rem) rotate(50deg);
        z-index: 2;
    }
    85%{
        transform: translate(1.58rem, 2.97rem) rotate(80deg);
        z-index: 2;
    }
    90%{
        transform: translate(1.78rem, 2.97rem) rotate(80deg);
        z-index: 2;
    }
    95%{
        transform: translate(2.2rem, 2.97rem) rotate(0deg) scale(1.4);
        z-index: 2;
    }
    100%{
        transform: translate(2.2rem, 2.97rem) rotate(0deg) scale(1.4);
        z-index: 2;
    }
}
</style>

最终效果就是上面视频的demo

  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Vue扭蛋抽奖效果是一种基于Vue框架实现的具有互动性的抽奖效果。在这个效果中,参与者可以点击扭蛋按钮,然后蛋壳会随机转动一段时间,最终停止在一个奖品上。 实现这个效果的关键是利用Vue的动态绑定和过渡效果来实现扭蛋转动和停止的动画效果。首先,可以使用Vue的data属性来存储扭蛋的状态,例如设置一个变量isSpinning来表示是否正在旋转。当点击扭蛋按钮时,可以通过设置isSpinning为true来触发扭蛋的旋转动画。 在旋转动画方面,可以借助Vue的过渡效果来实现。可以使用transition组件来包裹扭蛋元素,并为其添加旋转动画的样式类。在data属性中添加一个变量,例如spinClass,用来控制旋转样式类的切换。在isSpinning为true时,将spinClass设置为启动旋转动画的样式类,当扭蛋停止旋转时,将spinClass设置为停止旋转的样式类。 为了使扭蛋停止在一个奖品上,可以使用Vue的计时器功能来控制扭蛋停止转动的时间。例如,在点击扭蛋按钮后,使用setTimeout函数设置一个定时器,当定时器到达指定的时间后,将isSpinning设置为false,停止扭蛋的旋转。 另外,为了实现随机停止在一个奖品上的效果,可以利用Vue的计算属性来生成随机数,并将该随机数与奖品索引绑定在一起。这样,当扭蛋停止旋转时,可以根据随机数获取对应的奖品信息,并展示在页面上。 综上所述,通过结合Vue的动态绑定、过渡效果和计时器功能,可以实现一个具有扭蛋抽奖效果的交互式页面。用户可以通过点击扭蛋按钮,享受扭蛋转动的动画效果,并在随机停止时获取奖品。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

至_臻

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

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

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

打赏作者

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

抵扣说明:

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

余额充值