布局

扭蛋机的布局比较简单,只需要在基础背景上添加一些元素就可以,最主要的是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绘制图像上了。

扭蛋动画

先把各种变量定义好:

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var ball1 = document.getElementById('ball1');//图片对象
var ball2 = document.getElementById('ball2');//图片对象
var ball3 = document.getElementById('ball3');//图片对象
var ball4 = document.getElementById('ball4');//图片对象
var ballList = [ball1, ball2, ball3, ball4];//图片对象数组
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是图片对象,用来绘制扭蛋。

扭蛋方法

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

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) {//小球碰到右边界,横坐标速度变为负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);//绘制小球}
}

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

初始化

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

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);}

结束

当然,需要最后加上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;,这样写是为了在js中获取img对象,当然也可以不在html中写这些img标签,直接在js文件中写:

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

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

清除计时器

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

画布

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

canvas实现扭蛋机动画效果相关推荐

  1. 飞桨首款韩女团小卡扭蛋机

    前言 其实一直想做一个韩国女团的安利(推荐)项目,奈何自己太菜了,一直没搞.一眨眼就到2021年年底了,也就想着结合自己的长处写一个充满韩范项目吧,恰巧遇到飞桨黑客松 48H Coding Party ...

  2. 前端搞一个扭蛋抽奖小动画?

    最近新增一个抽奖小模块,就是扭蛋机的形式,产品给了参考网页,奈何不好扒下来用,只得自己动手干了,不多bb,先看效果吧! 效果图: 动画分析 由上面gif可看出,整个动画分为四个部分 扭蛋随机(也不算随 ...

  3. css3扭蛋机,微信小程序 扭蛋抽奖机CSS3动画实现详解_咋地 _前端开发者

    前言 最近快速上线一个抽奖活动,又不想用canvas做,思考了很久,还是决定使用css3的动画来做,只要小球动得快,就没人发现我这些个小球的运动路径都是一样的了.先上动图 wxml文件: 这个做得我头 ...

  4. PHP扭蛋机原理,微信小程序 扭蛋抽奖机css3动画实现详解

    前言 最近快速上线一个抽奖活动,又不想用canvas做,思考了很久,还是决定使用css3的动画来做,只要小球动得快,就没人发现我这些个小球的运动路径都是一样的了.先上动图 wxml文件: 这个做得我头 ...

  5. Vue扭蛋机营销小游戏

    最近有一个需求做一个营销类型小游戏 所以做了一个扭蛋机类型的小游戏出来 大体逻辑: 点击按钮=>播放音乐.扭蛋机内部球滚动=>弹出球=>音乐停止.显示中奖信息 如图所示 h5或小程序 ...

  6. 【Canvas】js用canvas绘制一个钟表时钟动画效果

    学习JavaScript的看过来,有没有兴趣用Canvas画图呢,可以画很多有趣的事物,自由发挥想象,收获多多哦,旋转角度绘图这个重点掌握到了吗,这里有一个例子,如何用canvas画钟表时钟动图效果, ...

  7. html5做 涂色游戏,h5 canvas益智类填色画游戏代码

    特效描述:h5 canvas益智类 填色画游戏代码.h5益智类小游戏,基于canvas填色画图游戏下载.游戏介绍:通过选中色块,来给模型填充颜色.支持多种模型选择填色效果. 代码结构 1. 引入JS ...

  8. ak47怎么得 rust_《CF手游》AK47孟德怎么样 扭蛋机保底自选卡分析

    标签: 扭蛋机 哈喽各位CFer们大家好,CF手游孟德扭蛋机活动将会在2021元旦节发售的消息,早已经人尽皆知.为了更方便大家了解该活动,近期我们还发布了关于扭蛋机活动的详细爆料,引起了更多CFer的 ...

  9. php漂浮雪花,canvas实现雪花随机动态飘落效果(代码示例)

    本篇文章给大家介绍一下使用canvas实现雪花随机动态飘落效果的方法,文中示例代码介绍的非常详细.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 用canvas实现雪花随机动态飘落, ...

最新文章

  1. Dos中重定向与文件追加
  2. linux 压缩以及归档
  3. 人工智能应用上的九大障碍
  4. python代码书写_Python代码的优雅写法,让代码更简洁
  5. java -uf_Java如何快速修改Jar包里的文件内容
  6. 手机连接电脑wifi
  7. php下标排序,php二维数组指定下标排序
  8. npm安装依赖包 版本冲突怎么办 --legacy-peer-deps的正确使用方
  9. 关于pict工具进行测试用例的自动生成过程中:使用 pict.exe test.txt >test.xsl 导出为xls格式的表格文件时,出现拒绝访问的提示解决方案
  10. C#模拟鼠标和键盘操作
  11. kd718和kb688参数_GJK SPP 5BGK AEC F04A tB9 D4 RMP
  12. 新加坡最新的公共交通规划与管理经验借鉴
  13. 计算机进入安全模式,电脑无法进入安全模式如何解决
  14. HDFS--Secondary NameNode
  15. Python Day 10 - 文件与文件系统
  16. GitHub添加SSH key
  17. Python爬取数据分析
  18. An internal error occurred during: Add Deployment.
  19. 【数学篇】论从一题四解到分式与整式
  20. js圆形轨迹公式(转)

热门文章

  1. 再聊聊Python中文社区的翻译
  2. CentOS6.5挂载大于2TB的磁盘使用parted和GPT类型
  3. matlab dcgain,MATLAB实现控制系统的时域分析
  4. React---组件通信的方式
  5. Python-CSV文件存储
  6. Microsoft Web Farm Framework (WFF) 2.0 入门系列之一:WFF 介绍
  7. Hark的数据结构与算法练习之耐心排序
  8. 2020年区块链行业十大趋势
  9. 计算机视觉与深度学习基本环境安装
  10. Java手机号码工具类(判断运营商、获取归属地)