系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 网页制作 > html5 > 详细页面

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

时间:2019-12-05来源:系统城作者:电脑系统城

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

背景

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

开始

布局

扭蛋机的布局比较简单,只需要在基础背景上添加一些元素就可以,最主要的是canvas标签,其他都无所谓:


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

附上样式表:


 
  1. body {margin: 0;padding: 0;border: none;}
  2. .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%);}
  3. #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%);}
  4. .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%);}
  5. #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%);}
  6. .lighting {display: block;max-width: 99%;margin-top: 0;margin-left: 0;}
  7. #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%);}
  8. .imgSrc {display: none;position: absolute;}
  9. .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绘制图像上了。

扭蛋动画

先把各种变量定义好:


 
  1. var canvas = document.getElementById('myCanvas');
  2. var ctx = canvas.getContext('2d');
  3. var ball1 = document.getElementById('ball1');//图片对象
  4. var ball2 = document.getElementById('ball2');//图片对象
  5. var ball3 = document.getElementById('ball3');//图片对象
  6. var ball4 = document.getElementById('ball4');//图片对象
  7. var ballList = [ball1, ball2, ball3, ball4];//图片对象数组
  8. var ballNum = 4;//扭蛋机里面的小球数
  9. var awardList = [];//扭蛋机中的小球集合
  10. var timer;//计时器
  11. var award = document.getElementById('awardBall');
  12. var message = document.getElementById('message');

扭蛋对象

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


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

传入扭蛋对象的值index为小球的颜色,用数字1~4表示,img是图片对象,用来绘制扭蛋。

扭蛋方法

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


 
  1. Ball.prototype = {
  2. rand: function (num) {//随机数
  3. return Math.random() * num;
  4. },
  5. run: function () {//小球运动函数
  6. this.x += this.speedX;
  7. this.y += this.speedY;
  8. if (this.x > canvas.width - this.r * 2) {//小球碰到右边界,横坐标速度变为负
  9. this.speedX = -this.speedX;
  10. }
  11. if (this.x < 0) {//小球碰到左边界,横坐标速度变为正
  12. this.speedX = Math.abs(this.speedX);
  13. }
  14. if (this.y > canvas.height - this.r * 2) {//小球碰到下边界,纵坐标速度变为负
  15. this.speedY = -this.speedY;
  16. }
  17. if (this.y < 0) {//小球碰到上边界,纵坐标速度变为正
  18. this.speedY = Math.abs(this.speedY);
  19. }
  20. ctx.drawImage(this.img, this.x, this.y, 60, 60);//绘制小球
  21. }
  22. }

主要是为扭蛋对象的原型添加上运动函数,运动函数的作用就是让扭蛋根据其速度动起来,并且在接触到边界的时候反弹。

初始化

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


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

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

开始扭蛋

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


 
  1. function play() {
  2. if (awardList.length === 0) {//奖池中没有小球
  3. alert('重新开始!');
  4. init();
  5. message.innerText = '点击抽奖';
  6. } else {
  7. window.clearInterval(timer);//清除计时器
  8. let r = awardList.pop();//将奖池中的小球减少
  9. timer = setInterval(function () {
  10. ctx.clearRect(0, 0, canvas.width, canvas.height);//清空画布
  11. for (let i = 0; i < awardList.length; i++) {
  12. awardList[i].run();
  13. }//使小球运动
  14. }, 15);
  15. switch (r.color) {//小球掉落动画
  16. case 0:
  17. award.setAttribute('class', 'dropBall1');
  18. break;
  19. case 1:
  20. award.setAttribute('class', 'dropBall2');
  21. break;
  22. case 2:
  23. award.setAttribute('class', 'dropBall3');
  24. break;
  25. case 3:
  26. award.setAttribute('class', 'dropBall4');
  27. break;
  28. }
  29. setTimeout(function () {//扭蛋成功提示
  30. award.setAttribute('class', '');
  31. switch (r.color) {
  32. case 0:
  33. message.innerText = '紫球!';
  34. break;
  35. case 1:
  36. message.innerText = '绿球!';
  37. break;
  38. case 2:
  39. message.innerText = '黄球!';
  40. break;
  41. case 3:
  42. message.innerText = '红球!';
  43. break;
  44. }
  45. }, 1100);
  46. }
  47. }

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


 
  1. .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 1sease-out forwards;-webkit-animation: drop 1s ease-out forwards;}
  2. .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 1sease-out forwards;-webkit-animation: drop 1s ease-out forwards;}
  3. .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 1sease-out forwards;-webkit-animation: drop 1s ease-out forwards;}
  4. .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 1sease-out forwards;-webkit-animation: drop 1s ease-out forwards;}
  5.  
  6. @keyframes drop {
  7. 0% {
  8. transform: scale(0.7);
  9. }
  10. 50% {
  11. transform: scale(1);
  12. }
  13. 51% {
  14. transform: translateY(0px);
  15. }
  16. 100% {
  17. transform: translateY(100px);
  18. }
  19. }
  20.  
  21. @-webkit-keyframes drop {
  22. 0% {
  23. -webkit-transform: scale(0.7);
  24. }
  25. 50% {
  26. -webkit-transform: scale(1);
  27. }
  28. 51% {
  29. -webkit-transform: translateY(0px);
  30. }
  31. 100% {
  32. -webkit-transform: translateY(100px);
  33. }
  34. }
  35.  

结束

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

总结

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

注意点

img对象

在html中的这些img标签:


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

样式也写成display: none;,这样写是为了在js中获取img对象,当然也可以不在html中写这些img标签,直接在js文件中写:


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

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

清除计时器

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

画布

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

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

分享到:

相关信息

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载