相信很多小伙伴都有玩過扭蛋機(jī),今天小編就來和大家來說說:“html中怎么使用實(shí)現(xiàn)扭蛋機(jī)動畫效果?相關(guān)案例分享!”這個(gè)問題,下面是相關(guān)的內(nèi)容分享。
背景
本來興高采烈地從網(wǎng)上找了一個(gè)扭蛋機(jī)動畫,但是發(fā)現(xiàn)它是直接用css動畫,把扭蛋們的動畫寫死了,這樣我不是很喜歡,于是還是選擇用canvas繪制扭蛋的隨機(jī)動畫。先寫了個(gè)簡單的扭蛋機(jī)Demo,效果預(yù)覽
開始
布局
扭蛋機(jī)的布局比較簡單,只需要在基礎(chǔ)背景上添加一些元素就可以,最主要的是canvas標(biāo)簽,其他都無所謂:
<div class="bg">
<span id="message">點(diǎn)擊抽獎</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];//圖片對象數(shù)組
var ballNum = 4;//扭蛋機(jī)里面的小球數(shù)
var awardList = [];//扭蛋機(jī)中的小球集合
var timer;//計(jì)時(shí)器
var award = document.getElementById('awardBall');
var message = document.getElementById('message');
扭蛋對象
扭蛋機(jī)里面每個(gè)扭蛋都是一個(gè)對象,所以需要定義一個(gè)扭蛋對象:
function Ball(index, img) {
this.r = 30;//小球半徑
this.x = this.rand(canvas.width - this.r * 2);//小球初始橫坐標(biāo)
this.y = this.rand(canvas.height - this.r * 2);//小球初始縱坐標(biāo)
this.color = index;//小球顏色,以下標(biāo)表示
this.img = img;//小球素材
do {
this.speedX = this.rand(20) - 10;
} while (this.speedX < 5);//小球橫坐標(biāo)改變速度
do {
this.speedY = this.rand(20) - 10;
} while (this.speedY < 5);//小球縱坐標(biāo)改變速度
}
傳入扭蛋對象的值index為小球的顏色,用數(shù)字1~4表示,img是圖片對象,用來繪制扭蛋。
扭蛋方法
在上一步已經(jīng)為扭蛋添加了屬性,接下來就是給扭蛋添加方法:
Ball.prototype = {
rand: function (num) {//隨機(jī)數(shù)
return Math.random() * num;
},
run: function () {//小球運(yùn)動函數(shù)
this.x += this.speedX;
this.y += this.speedY;
if (this.x > canvas.width - this.r * 2) {//小球碰到右邊界,橫坐標(biāo)速度變?yōu)樨?fù)
this.speedX = -this.speedX;
}
if (this.x < 0) {//小球碰到左邊界,橫坐標(biāo)速度變?yōu)檎? this.speedX = Math.abs(this.speedX);
}
if (this.y > canvas.height - this.r * 2) {//小球碰到下邊界,縱坐標(biāo)速度變?yōu)樨?fù)
this.speedY = -this.speedY;
}
if (this.y < 0) {//小球碰到上邊界,縱坐標(biāo)速度變?yōu)檎? this.speedY = Math.abs(this.speedY);
}
ctx.drawImage(this.img, this.x, this.y, 60, 60);//繪制小球
}
}
主要是為扭蛋對象的原型添加上運(yùn)動函數(shù),運(yùn)動函數(shù)的作用就是讓扭蛋根據(jù)其速度動起來,并且在接觸到邊界的時(shí)候反彈。
初始化
接下來就是把扭蛋們放在扭蛋機(jī)里面:
function init() {//初始化
for (let i = 0; i < ballNum; i++) {//隨機(jī)生成各色小球
let index = Math.floor(4 * Math.random());
awardList[i] = new Ball(index, ballList[index]);//新建小球?qū)ο? }
window.clearInterval(timer);//清除計(jì)時(shí)器
timer = setInterval(function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);//清空畫布
for (let i = 0; i < awardList.length; i++) {
awardList[i].run();
}//使小球運(yùn)動
}, 15);
}
這樣子扭蛋機(jī)里面就已經(jīng)有了小球。
開始扭蛋
開始扭蛋主要經(jīng)歷的過程就是點(diǎn)擊按鈕,扭蛋機(jī)扭蛋減少,獲得相應(yīng)扭蛋,中獎顯示:
function play() {
if (awardList.length === 0) {//獎池中沒有小球
alert('重新開始!');
init();
message.innerText = '點(diǎn)擊抽獎';
} else {
window.clearInterval(timer);//清除計(jì)時(shí)器
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();
}//使小球運(yùn)動
}, 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動畫的關(guān)鍵幀來完成:
.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);
}
}
結(jié)束
當(dāng)然,需要最后加上init();來讓扭蛋機(jī)跑起來,到這里,這個(gè)簡單的扭蛋機(jī)就算完成了,效果預(yù)覽
總結(jié)
雖然這個(gè)Demo比較簡單,但是還是有一些注意點(diǎn)和一些可優(yōu)化的地方。
注意點(diǎn)
img對象
在html中的這些img標(biāo)簽:
<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對象,當(dāng)然也可以不在html中寫這些img標(biāo)簽,直接在js文件中寫:
var img = new Image();
img.src = 'img/1.png';
這樣子也可以得到img對象,也可以用來繪制扭蛋。
清除計(jì)時(shí)器
代碼中清除計(jì)時(shí)器都是在調(diào)用計(jì)時(shí)器之前,之所以這樣做的目的,是因?yàn)椴磺宄?jì)時(shí)器,計(jì)時(shí)器會一直計(jì)時(shí),導(dǎo)致動畫越來越鬼畜。
畫布
在canvas畫布上繪制可能會出現(xiàn)圖像不清晰、放大的情況,這種情況可以通過將canvas標(biāo)簽的width和height屬性設(shè)置成和樣式的width和height屬性相同來解決。
今天有關(guān)于:“html中怎么使用實(shí)現(xiàn)扭蛋機(jī)動畫效果?相關(guān)案例分享!”這個(gè)問題的相關(guān)分享就到這邊了,更多有關(guān)于html5內(nèi)容我們都可以在W3Cschool中進(jìn)行學(xué)習(xí)和了解。希望小編的分享可以幫助到大家。