JavaScript利用Canvas實(shí)現(xiàn)粒子動(dòng)畫(huà)倒計(jì)時(shí)
canvas 粒子動(dòng)畫(huà)介紹
何為canvas
canvas是HTML5中新增的一個(gè)標(biāo)簽,主要是用于網(wǎng)頁(yè)實(shí)時(shí)生成圖像并可操作圖像,它是用JavaScript操作的bitmap。
粒子動(dòng)畫(huà)是啥
粒子動(dòng)畫(huà)就是頁(yè)面上通過(guò)發(fā)射許多微小粒子來(lái)表示不規(guī)則模糊物體,比如:用小圓點(diǎn)來(lái)模擬下雪、下雨的效果,用模糊線條模擬黑客帝國(guó)背景效果等。
canvas
新建一個(gè)HTML文件,寫(xiě)入canvas標(biāo)簽用于后續(xù)展示倒計(jì)時(shí)
<canvas id="canvas-number"></canvas> <canvas id="canvas-dots"></canvas>
- canvas-number 是用于倒計(jì)時(shí)數(shù)字展示
- canvas-dots 是用于全屏粒子動(dòng)畫(huà)展示
加點(diǎn)樣式效果看看吧
body {
background-color: #24282f;
margin: 0;
padding: 0;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
#canvas-number {
width: 680px;
height: 420px;
}主要是定義了 canvas-number 畫(huà)布大小,canvas-dots 畫(huà)布大小會(huì)在JavaScript中定義
定義初始變量
在JavaScript中定義所需的變量
var numberStage, numberStageCtx, numberStageWidth = 680, numberStageHeight = 420, numberOffsetX, numberOffsetY, stage, stageCtx, stageWidth = window.innerWidth, stageHeight = window.innerHeight, stageCenterX = stageWidth / 2, stageCenterY = stageHeight / 2, countdownFrom = 3, countdownTimer = 2800, countdownRunning = true, number, dots = [], numberPixelCoordinates, circleRadius = 2, colors = ['61, 207, 236', '255, 244, 174', '255, 211, 218', '151, 211, 226'];
- numberStage - stageCenterY 這一塊主要是定義畫(huà)布寬高和坐標(biāo)
- countdownFrom 從 10 開(kāi)始倒計(jì)時(shí)
- countdownTimer 數(shù)字顯示的時(shí)長(zhǎng)
- countdownRunning 動(dòng)起來(lái)
- colors 頁(yè)面上所有粒子顏色
- 其他的可以自己理解一下哦~
初始化canvas和數(shù)字文本
創(chuàng)建一個(gè)init函數(shù),里面會(huì)包裹初始化內(nèi)容
function init() {
// 初始化canvas-number
numberStage = document.getElementById("canvas-number");
numberStageCtx = numberStage.getContext('2d');
// 設(shè)置文字文本的窗口大小
numberStage.width = numberStageWidth;
numberStage.height = numberStageHeight;
// 初始化canvas-dots和窗口大小
stage = document.getElementById("canvas-dots");
stageCtx = stage.getContext('2d');
stage.width = stageWidth;
stage.height = stageHeight;
// 設(shè)置一定的偏移量,讓文字居中
numberOffsetX = (stageWidth - numberStageWidth) / 2;
numberOffsetY = (stageHeight - numberStageHeight) / 2;
}根據(jù)代碼中的注釋可以了解初始化的內(nèi)容哦~
初始化完成之后,我們需要直接運(yùn)行方法
init();
在init函數(shù)結(jié)束之后,馬上就需要運(yùn)行該函數(shù)了
創(chuàng)建一定數(shù)量的點(diǎn)
for (var i = 0; i < 2240; i++) {
var dot = new Dot(randomNumber(0, stageWidth), randomNumber(0, stageHeight), colors[randomNumber(1, colors.length)], .3);
dots.push(dot);
tweenDots(dot, '', 'space');
}- 循環(huán)創(chuàng)建點(diǎn),這里循環(huán)給的是個(gè)固定數(shù)據(jù)
- new Dot 是創(chuàng)建點(diǎn)對(duì)象的方法
- tweenDots 是讓點(diǎn)動(dòng)起來(lái)的第三方j(luò)s
function Dot(x, y, color, alpha) {
var _this = this;
_this.x = x;
_this.y = y;
_this.color = color;
_this.alpha = alpha;
this.draw = function () {
stageCtx.beginPath();
stageCtx.arc(_this.x, _this.y, circleRadius, 0, 2 * Math.PI, false);
stageCtx.fillStyle = 'rgba(' + _this.color + ', ' + _this.alpha + ')';
stageCtx.fill();
}
}- 通過(guò) x、y坐標(biāo)定位點(diǎn)
- 通過(guò)隨機(jī)顏色,讓點(diǎn)樣式更豐富
- draw 里面的內(nèi)容都是canvas畫(huà)圖的方法,具體可參考canvas文檔
倒計(jì)時(shí)
function countdown() {
// 發(fā)送倒計(jì)時(shí)數(shù)字
drawNumber(countdownFrom.toString());
// 倒計(jì)時(shí)為 0 時(shí)停止
if (countdownFrom === 0) {
countdownRunning = false;
drawNumber('蠟筆小心');
}
countdownFrom--;
}倒計(jì)時(shí)結(jié)束之后,就可以想干啥干啥了,這里我重新輸出了額外的文字
countdownFrom 需要做遞減的操作
countdown();
我們需要在頁(yè)面進(jìn)入時(shí),直接觸發(fā)倒計(jì)時(shí)函數(shù)
倒計(jì)時(shí)文本繪畫(huà)
每一個(gè)倒計(jì)時(shí)都需要用不同的點(diǎn)去繪制
這里通過(guò)循環(huán) 讓每個(gè)文本都有四種顏色繪制
function drawNumber(num) {
numberStageCtx.clearRect(0, 0, numberStageWidth, numberStageHeight);
numberStageCtx.fillStyle = "#24282f";
numberStageCtx.textAlign = 'center';
numberStageCtx.font = "bold 118px Lato";
numberStageCtx.fillText(num, 250, 300);
var ctx = document.getElementById('canvas-number').getContext('2d');
var imageData = ctx.getImageData(0, 0, numberStageWidth, numberStageHeight).data;
numberPixelCoordinates = [];
for (var i = imageData.length; i >= 0; i -= 4) {
if (imageData[i] !== 0) {
var x = (i / 4) % numberStageWidth;
var y = Math.floor(Math.floor(i / numberStageWidth) / 4);
if ((x && x % (circleRadius * 2 + 3) == 0) && (y && y % (circleRadius * 2 + 3) == 0)) {
numberPixelCoordinates.push({
x: x,
y: y
});
}
}
}
formNumber();
}
function formNumber() {
for (var i = 0; i < numberPixelCoordinates.length; i++) {
tweenDots(dots[i], numberPixelCoordinates[i], '');
}
if (countdownRunning && countdownFrom > 0) {
setTimeout(function () {
breakNumber();
}, countdownTimer);
}
}
function breakNumber() {
for (var i = 0; i < numberPixelCoordinates.length; i++) {
tweenDots(dots[i], '', 'space');
}
if (countdownRunning) {
setTimeout(function () {
countdown();
}, countdownTimer);
}
}循環(huán)繪制
function loop() {
stageCtx.clearRect(0, 0, stageWidth, stageHeight);
for (var i = 0; i < dots.length; i++) {
dots[i].draw(stageCtx);
}
requestAnimationFrame(loop);
}
loop();循環(huán)繪制,需要進(jìn)入頁(yè)面即執(zhí)行,所以在方法之后馬上執(zhí)行該函數(shù)
點(diǎn)動(dòng)畫(huà)
在倒計(jì)時(shí)文本中,我們一直會(huì)調(diào)用tweenDots方法,就是用于點(diǎn)動(dòng)畫(huà)效果的繪制
function tweenDots(dot, pos, type) {
if (type === 'space') {
TweenMax.to(dot, (3 + Math.round(Math.random() * 100) / 100), {
x: randomNumber(0, stageWidth),
y: randomNumber(0, stageHeight),
alpha: 0.3,
ease: Cubic.easeInOut,
onComplete: function () {
tweenDots(dot, '', 'space');
}
});
} else {
TweenMax.to(dot, (1.5 + Math.round(Math.random() * 100) / 100), {
x: (pos.x + numberOffsetX),
y: (pos.y + numberOffsetY),
delay: 0,
alpha: 1,
ease: Cubic.easeInOut,
onComplete: function () {}
});
}
}
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}- 隨機(jī)移動(dòng)畫(huà)布周圍的點(diǎn)
- 讓點(diǎn)和文本內(nèi)容協(xié)調(diào)展示
效果圖

以上就是JavaScript利用Canvas實(shí)現(xiàn)粒子動(dòng)畫(huà)倒計(jì)時(shí)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript Canvas粒子動(dòng)畫(huà)倒計(jì)時(shí)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- JS技巧Canvas性能優(yōu)化臟矩形渲染實(shí)例詳解
- JavaScript+Canvas模擬實(shí)現(xiàn)支付寶畫(huà)年兔游戲
- JavaScript+Canvas實(shí)現(xiàn)文字粒子流特效
- JavaScript?Canvas實(shí)現(xiàn)兼容IE的兔子發(fā)射爆破動(dòng)圖特效
- 利用JS+Canvas給南方的冬季來(lái)一場(chǎng)紛紛揚(yáng)揚(yáng)的大雪
- JS+Canvas實(shí)現(xiàn)滿屏愛(ài)心和文字動(dòng)畫(huà)的制作
- JavaScript使用canvas實(shí)現(xiàn)flappy bird全流程詳解
相關(guān)文章
實(shí)例詳解JSON取值(key是中文或者數(shù)字)方式
本文通過(guò)實(shí)例詳解JSON取值(key是中文或者數(shù)字)方式,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-08-08
uniapp 引用 js 組件的方法(場(chǎng)景分析)
在UniApp開(kāi)發(fā)過(guò)程中,我們不僅需要掌握各種UI組件的使用方法,還需要了解如何在項(xiàng)目中引入JS文件,在本文中,我將介紹UniApp中如何引入JS的方法,感興趣的朋友跟隨小編一起看看吧2023-09-09
解決echarts官網(wǎng)打不開(kāi)訪問(wèn)失敗的問(wèn)題
這篇文章主要介紹了解決echarts官網(wǎng)打不開(kāi)訪問(wèn)失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Electron應(yīng)用顯示隱藏時(shí)展示動(dòng)畫(huà)效果實(shí)例
最近使用electron實(shí)現(xiàn)一個(gè)簡(jiǎn)單的功能,下面這篇文章主要給大家介紹了關(guān)于Electron應(yīng)用顯示隱藏時(shí)展示動(dòng)畫(huà)效果的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
JavaScript實(shí)現(xiàn)動(dòng)態(tài)生成表格案例詳解
本文主要介紹了通過(guò)JavaScript實(shí)現(xiàn)一個(gè)動(dòng)態(tài)添加表格的案例,當(dāng)點(diǎn)擊添加按鈕時(shí),可以彈出一個(gè)表單,然后將輸入的內(nèi)容添加到表格中,也可以將表格中的整行內(nèi)容清除。感興趣的可以學(xué)習(xí)一下2021-12-12
js實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08
讓 JavaScript 輕松支持函數(shù)重載 (Part 2 - 實(shí)現(xiàn))
在上一篇文章里,我們?cè)O(shè)計(jì)了一套能在JavaScript中描述函數(shù)重載的方法,這套方法依賴于一個(gè)叫做Overload的靜態(tài)類,現(xiàn)在我們就來(lái)看看如何實(shí)現(xiàn)這個(gè)靜態(tài)類。2009-08-08

