canvas实现扭蛋机动画效果的示例代码

  发布时间2018-10-17 15:26:17   作者幽小鬼   我要评论

这篇文章主要介绍了canvas实现扭蛋机动画效果的示例代码,小编觉得挺不错的现在分享给大家也给大家做个参考一起跟随小编过来看看吧

转眼间已经实习了两个月了公司每个月都有个会员日的活动要做这个月的任务是做一个扭蛋机抽奖的活动数据什么的都有接口那么前端剩下最大的任务就只剩下扭蛋机的动画实现了

背景

本来兴高采烈地从网上找了一个扭蛋机动画但是发现它是直接用css动画把扭蛋们的动画写死了这样我不是很?#19981;?#20110;是还是选择用canvas绘制扭蛋的随机动画先写了个简单的扭蛋机Demo效果预览

开始

布局

扭蛋机的布?#30452;?#36739;简单只需要在基础背?#21543;?#28155;加一些元素就可以最主要的是canvas标签其他都无所谓

<div class="bg">
    <span id="message">点击抽奖</span>
    <div class="lotterybg">
        <canvas id="myCanvas" width="285px" height="170px"></canvas>
        <img src="img/lighting.png" class="lighting"/>
    </div>
</div>
<img src="img/start-btn.png" id="start" onclick="play()"/>
<div class="award"><span id="awardBall"></span></div>
<img src="img/1.png" id="ball1" class="imgSrc">
<img src="img/2.png" id="ball2" class="imgSrc">
<img src="img/3.png" id="ball3" class="imgSrc">
<img src="img/4.png" id="ball4" class="imgSrc">

附上样式表

body {margin: 0;padding: 0;border: none;}
.bg {background: url(../img/bg.png) top no-repeat;background-size: 100%;overflow: hidden;position: absolute;width: 400px;height: 100%;margin-top: 0;margin-left: 50%;-webkit-transform: translate(-50%);-moz-transform: translate(-50%);-ms-transform: translate(-50%);-o-transform: translate(-50%);transform: translate(-50%);}
#message {position: absolute;text-align: center;height: 25px;font-size: 22px;margin-top: 110px;margin-left: 50%;-webkit-transform: translate(-50%);-moz-transform: translate(-50%);-ms-transform: translate(-50%);-o-transform: translate(-50%);transform: translate(-50%);}
.lotterybg {background: url(../img/lotterybg.png) top no-repeat;background-size: 100%;overflow: visible;width: 80%;height: 100%;margin-top: 160px;margin-left: 50%;-webkit-transform: translate(-50%);-moz-transform: translate(-50%);-ms-transform: translate(-50%);-o-transform: translate(-50%);transform: translate(-50%);}
#myCanvas {position: absolute;border: none;width: 285px;height: 170px;margin-top: 15px;margin-left: 50%;-webkit-transform: translate(-50%);-moz-transform: translate(-50%);-ms-transform: translate(-50%);-o-transform: translate(-50%);transform: translate(-50%);}
.lighting {display: block;max-width: 99%;margin-top: 0;margin-left: 0;}
#start {position: absolute;z-index: 3;width: 202px;margin-top: 413px;margin-left: 50%;-webkit-transform: translate(-50%);-moz-transform: translate(-50%);-ms-transform: translate(-50%);-o-transform: translate(-50%);transform: translate(-50%);}
.imgSrc {display: none;position: absolute;}
.award {position: absolute;border: none;width: 60px;height: 200px;top: 470px;margin-left: 50%;-webkit-transform: translate(-50%);-moz-transform: translate(-50%);-ms-transform: translate(-50%);-o-transform: translate(-50%);transform: translate(-50%);}

这样子布局就算完成了接下来主要工作就在canvas绘制图像上了

扭蛋动画

先把各?#30452;?#37327;定义好

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var ball1 = document.getElementById('ball1');//?#35745;?#23545;象
var ball2 = document.getElementById('ball2');//?#35745;?#23545;象
var ball3 = document.getElementById('ball3');//?#35745;?#23545;象
var ball4 = document.getElementById('ball4');//?#35745;?#23545;象
var ballList = [ball1, ball2, ball3, ball4];//?#35745;?#23545;象数组
var ballNum = 4;//扭蛋机里面的小球数
var awardList = [];//扭蛋机中的小球集合
var timer;//计时器
var award = document.getElementById('awardBall');
var message = document.getElementById('message');

扭蛋对象

扭蛋机里面每个扭蛋都是一个对象所以需要定义一个扭蛋对象

function Ball(index, img) {
    this.r = 30;//小球半径
    this.x = this.rand(canvas.width - this.r * 2);//小球初始横坐标
    this.y = this.rand(canvas.height - this.r * 2);//小球初始纵坐标
    this.color = index;//小球颜色以下标表示
    this.img = img;//小球素材
    do {
        this.speedX = this.rand(20) - 10;
    } while (this.speedX < 5);//小球横坐标改变速度
    do {
        this.speedY = this.rand(20) - 10;
    } while (this.speedY < 5);//小球纵坐标改变速度
}

传入扭蛋对象的值index为小球的颜色用数字1~4表示img是?#35745;?#23545;象用来绘制扭蛋

扭蛋方法

在上一步已经为扭蛋添加了属性接下来就是给扭蛋添加方法

Ball.prototype = {
    rand: function (num) {//随机数
        return Math.random() * num;
    },
    run: function () {//小球运动函数
        this.x += this.speedX;
        this.y += this.speedY;
        if (this.x > canvas.width - this.r * 2) {//小球碰?#25509;?#36793;界横坐标速度变为负
            this.speedX = -this.speedX;
        }
        if (this.x < 0) {//小球碰到左边界横坐标速度变为正
            this.speedX = Math.abs(this.speedX);
        }
        if (this.y > canvas.height - this.r * 2) {//小球碰到下边界纵坐标速度变为负
            this.speedY = -this.speedY;
        }
        if (this.y < 0) {//小球碰到上边界纵坐标速度变为正
            this.speedY = Math.abs(this.speedY);
        }
        ctx.drawImage(this.img, this.x, this.y, 60, 60);//绘制小球
    }
}

主要是为扭蛋对象的原型添加上运动函数运动函数的作用就是让扭蛋根据其速度动起来并且在接触?#22870;?#30028;的时候反弹

初始化

接下来就是把扭蛋们放在扭蛋机里面

function init() {//初始化
    for (let i = 0; i < ballNum; i++) {//随机生成各色小球
        let index = Math.floor(4 * Math.random());
        awardList[i] = new Ball(index, ballList[index]);//新建小球对象
    }
    window.clearInterval(timer);//清除计时器
    timer = setInterval(function () {
        ctx.clearRect(0, 0, canvas.width, canvas.height);//清空画布
        for (let i = 0; i < awardList.length; i++) {
            awardList[i].run();
        }//使小球运动
    }, 15);
}

这样子扭蛋机里面就已经有了小球

开始扭蛋

开始扭蛋主要经历的过程就是点击按钮扭蛋机扭蛋减少获得相应扭蛋中奖显示

function play() {
    if (awardList.length === 0) {//奖池中没有小球
        alert('重新开始');
        init();
        message.innerText = '点击抽奖';
    } else {
        window.clearInterval(timer);//清除计时器
        let r = awardList.pop();//将奖池中的小球减少
        timer = setInterval(function () {
            ctx.clearRect(0, 0, canvas.width, canvas.height);//清空画布
            for (let i = 0; i < awardList.length; i++) {
                awardList[i].run();
            }//使小球运动
        }, 15);
        switch (r.color) {//小球掉落动画
            case 0:
                award.setAttribute('class', 'dropBall1');
                break;
            case 1:
                award.setAttribute('class', 'dropBall2');
                break;
            case 2:
                award.setAttribute('class', 'dropBall3');
                break;
            case 3:
                award.setAttribute('class', 'dropBall4');
                break;
        }
        setTimeout(function () {//扭蛋成功提示
            award.setAttribute('class', '');
            switch (r.color) {
                case 0:
                    message.innerText = '紫球';
                    break;
                case 1:
                    message.innerText = '绿球';
                    break;
                case 2:
                    message.innerText = '黄球';
                    break;
                case 3:
                    message.innerText = '红球';
                    break;
            }
        }, 1100);
    }
}

在这里扭蛋的掉落动画使用css动画的关键帧来完成

.dropBall1 {content: "";position: absolute;left: 0;top: 0;width: 60px;height: 60px;display: block;background: url(../img/1.png) no-repeat;background-size: contain;animation: drop 1s ease-out forwards;-webkit-animation: drop 1s ease-out forwards;}
.dropBall2 {content: "";position: absolute;left: 0;top: 0;width: 60px;height: 60px;display: block;background: url(../img/2.png) no-repeat;background-size: contain;animation: drop 1s ease-out forwards;-webkit-animation: drop 1s ease-out forwards;}
.dropBall3 {content: "";position: absolute;left: 0;top: 0;width: 60px;height: 60px;display: block;background: url(../img/3.png) no-repeat;background-size: contain;animation: drop 1s ease-out forwards;-webkit-animation: drop 1s ease-out forwards;}
.dropBall4 {content: "";position: absolute;left: 0;top: 0;width: 60px;height: 60px;display: block;background: url(../img/4.png) no-repeat;background-size: contain;animation: drop 1s ease-out forwards;-webkit-animation: drop 1s ease-out forwards;}

@keyframes drop {
    0% {
        transform: scale(0.7);
    }
    50% {
        transform: scale(1);
    }
    51% {
        transform: translateY(0px);
    }
    100% {
        transform: translateY(100px);
    }
}

@-webkit-keyframes drop {
    0% {
        -webkit-transform: scale(0.7);
    }
    50% {
        -webkit-transform: scale(1);
    }
    51% {
        -webkit-transform: translateY(0px);
    }
    100% {
        -webkit-transform: translateY(100px);
    }
}

结束

?#27604;?#38656;要最后加上init();来让扭蛋机跑起来到这里这个简单的扭蛋机就算完成了效果预览

总结

虽然这个Demo比较简单但是还是有一些注意点和一些可优化的地方

注意点

img对象

在html中的这些img标签

<img src="img/1.png" id="ball1" class="imgSrc">
<img src="img/2.png" id="ball2" class="imgSrc">
<img src="img/3.png" id="ball3" class="imgSrc">
<img src="img/4.png" id="ball4" class="imgSrc">

样式也写成display: none;这样?#35789;?#20026;了在js中获取img对象?#27604;?#20063;可以不在html中写这些img标签直接在js文件中写

var img = new Image(); 
img.src = 'img/1.png'; 

这样子也可以得到img对象也可以用来绘制扭蛋

清除计时器

代码中清除计时器都是在调用计时器之前之所以这样做的目的是因为不清除计时器计时器会一直计时导致动画越来越鬼畜

画布

在canvas画布上绘制可能会出现图像不清晰放大的情况这种情况可以通过将canvas标签的width和height属性设置成和样式的width和height属性相同来解决

以上就是本文的全部内容希望对大家的学习有所帮助也希望大家多多支持脚本之家

相关文章

  • html5 http的轮询和Websocket原理

    这篇文章主要介绍了html5 http的轮询和Websocket原理的相关资料,小编觉得挺不错的现在分享给大家也给大家做个参考一起跟随小编过来看看吧
    2018-10-19
  • canvas实现扭蛋机动画效果的示例代码

    这篇文章主要介绍了canvas实现扭蛋机动画效果的示例代码,小编觉得挺不错的现在分享给大家也给大家做个参考一起跟随小编过来看看吧
    2018-10-17
  • html5/css3响应式页面开发总结

    响应式一套模板适应所有终端但每种设备看到的版式可以是不一样的这篇文章主要介绍了html5/css3响应式页面开发总结 ,需要的朋友可以参考下
    2018-10-16
  • ?#31243;HTML5中dialog元素尝鲜

    对话框是web项目中用于用户交互的重要部分这篇文章主要介绍了?#31243;HTML5中dialog元素尝鲜
    2018-10-15
  • canvas进阶之如何画出平滑的曲线

    canvas画出来的线条存在锯齿不够平滑这篇文章主要介绍了canvas进阶之如何画出平滑的曲线小编觉得挺不错的现在分享给大家也给大家做个参考一起跟随小编过来看看
    2018-10-15
  • 传统HTML页面实现模块化加载的方法

    这篇文章主要介绍了传统HTML页面实现模块化加载的相关知识非常不错具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2018-10-15
  • iframe在移动端的缩放的示例代码

    这篇文章主要介绍了iframe在移动端的缩放的示例代码小编觉得挺不错的现在分享给大家也给大家做个参考一起跟随小编过来看看吧
    2018-10-12
  • 详解HTML5将footer置于页面最底部的方法(CSS+JS)

    这篇文章主要介绍了详解HTML5将footer置于页面最底部的方法(CSS+JS)的相关资料,小编觉得挺不错的现在分享给大家也给大家做个参考一起跟随小编过来看看吧
    2018-10-11
  • HTML5实现签到 功能

    这篇文章主要介绍了HTML5实现签到 功能 的实现代码非常不错具有一定的参考借鉴价值需要的朋友参考下吧
    2018-10-09
  • HTML5 视频播放(video),JavaScript控制视频的实例代码

    这篇文章主要介绍了HTML5 视频播放(video),JavaScript控制视频的实例代码需要的朋友参考下吧
    2018-10-08

最新评论

35ѡ7