canvas实现扭蛋机动画效果的示例代码
转眼间,已经实习了两个月了,公司每个月都有个会员日的活动要做,这个月的任务是做一个扭蛋机抽奖的活动,数据什么的都有接口,那么前端剩下最大的任务就只剩下扭蛋机的动画实现了。
背景@H_304_4@
本来兴高采烈地从网上找了一个扭蛋机动画,但是发现它是直接用css动画,把扭蛋们的动画写死了,这样我不是很喜欢,于是还是选择用canvas绘制扭蛋的随机动画。先写了个简单的扭蛋机Demo,效果预览
开始
布局
扭蛋机的布局比较简单,只需要在基础背景上添加一些元素就可以,最主要的是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标签的width和height属性设置成和样式的width和height属性相同来解决。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: canvas实现扭蛋机动画效果的示例代码
本文地址: https://pptw.com/jishu/585891.html
