目录
- canvas 粒子动画介绍
- 何为canvas
- 粒子动画是啥
- canvas
- 定义初始变量
- 初始化canvas和数字文本
- 创建一定数量的点
- 倒计时
- 倒计时文本绘画
- 循环绘制
- 点动画
- 效果图
canvas 粒子动画介绍
何为canvas
canvas是HTML5中新增的一个标签,主要是用于网页实时生成图像并可操作图像,它是用JavaScript操作的bitmap。
粒子动画是啥
粒子动画就是页面上通过发射许多微小粒子来表示不规则模糊物体,比如:用小圆点来模拟下雪、下雨的效果,用模糊线条模拟黑客帝国背景效果等。
canvas
新建一个HTML文件,写入canvas标签用于后续展示倒计时
<canvas id="canvas-number"></canvas> | |
<canvas id="canvas-dots"></canvas> |
- canvas-number 是用于倒计时数字展示
- canvas-dots 是用于全屏粒子动画展示
加点样式效果看看吧
body { | |
background-color: #f; | |
margin:; | |
padding:; | |
} | |
canvas { | |
position: absolute; | |
top:; | |
left:; | |
} | |
#canvas-number { | |
width:px; | |
height:px; | |
} |
主要是定义了 canvas-number 画布大小,canvas-dots 画布大小会在JavaScript中定义
定义初始变量
在JavaScript中定义所需的变量
var numberStage, | |
numberStageCtx, | |
numberStageWidth =, | |
numberStageHeight =, | |
numberOffsetX, | |
numberOffsetY, | |
stage, | |
stageCtx, | |
stageWidth = window.innerWidth, | |
stageHeight = window.innerHeight, | |
stageCenterX = stageWidth /, | |
stageCenterY = stageHeight /, | |
countdownFrom =, | |
countdownTimer =, | |
countdownRunning = true, | |
number, | |
dots = [], | |
numberPixelCoordinates, | |
circleRadius =, | |
colors = [', 207, 236', '255, 244, 174', '255, 211, 218', '151, 211, 226']; |
- numberStage - stageCenterY 这一块主要是定义画布宽高和坐标
- countdownFrom 从 10 开始倒计时
- countdownTimer 数字显示的时长
- countdownRunning 动起来
- colors 页面上所有粒子颜色
- 其他的可以自己理解一下哦~
初始化canvas和数字文本
创建一个init函数,里面会包裹初始化内容
function init() { | |
// 初始化canvas-number | |
numberStage = document.getElementById("canvas-number"); | |
numberStageCtx = numberStage.getContext('d'); | |
// 设置文字文本的窗口大小 | |
numberStage.width = numberStageWidth; | |
numberStage.height = numberStageHeight; | |
// 初始化canvas-dots和窗口大小 | |
stage = document.getElementById("canvas-dots"); | |
stageCtx = stage.getContext('d'); | |
stage.width = stageWidth; | |
stage.height = stageHeight; | |
// 设置一定的偏移量,让文字居中 | |
numberOffsetX = (stageWidth - numberStageWidth) /; | |
numberOffsetY = (stageHeight - numberStageHeight) /; | |
} |
根据代码中的注释可以了解初始化的内容哦~
初始化完成之后,我们需要直接运行方法
init();
在init函数结束之后,马上就需要运行该函数了
创建一定数量的点
for (var i =; i < 2240; i++) { | |
var dot = new Dot(randomNumber(, stageWidth), randomNumber(0, stageHeight), colors[randomNumber(1, colors.length)], .3); | |
dots.push(dot); | |
tweenDots(dot, '', 'space'); | |
} |
- 循环创建点,这里循环给的是个固定数据
- new Dot 是创建点对象的方法
- tweenDots 是让点动起来的第三方js
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,, 2 * Math.PI, false); | |
stageCtx.fillStyle = 'rgba(' + _this.color + ', ' + _this.alpha + ')'; | |
stageCtx.fill(); | |
} | |
} |
- 通过 x、y坐标定位点
- 通过随机颜色,让点样式更丰富
- draw 里面的内容都是canvas画图的方法,具体可参考canvas文档
倒计时
function countdown() { | |
// 发送倒计时数字 | |
drawNumber(countdownFrom.toString()); | |
// 倒计时为 时停止 | |
if (countdownFrom ===) { | |
countdownRunning = false; | |
drawNumber('蜡笔小心'); | |
} | |
countdownFrom--; | |
} |
倒计时结束之后,就可以想干啥干啥了,这里我重新输出了额外的文字
countdownFrom 需要做递减的操作
countdown();
我们需要在页面进入时,直接触发倒计时函数
倒计时文本绘画
每一个倒计时都需要用不同的点去绘制
这里通过循环 让每个文本都有四种颜色绘制
function drawNumber(num) { | |
numberStageCtx.clearRect(, 0, numberStageWidth, numberStageHeight); | |
numberStageCtx.fillStyle = "#f"; | |
numberStageCtx.textAlign = 'center'; | |
numberStageCtx.font = "boldpx Lato"; | |
numberStageCtx.fillText(num,, 300); | |
var ctx = document.getElementById('canvas-number').getContext('d'); | |
var imageData = ctx.getImageData(, 0, numberStageWidth, numberStageHeight).data; | |
numberPixelCoordinates = []; | |
for (var i = imageData.length; i >=; i -= 4) { | |
if (imageData[i] !==) { | |
var x = (i /) % numberStageWidth; | |
var y = Math.floor(Math.floor(i / numberStageWidth) /); | |
if ((x && x % (circleRadius * + 3) == 0) && (y && y % (circleRadius * 2 + 3) == 0)) { | |
numberPixelCoordinates.push({ | |
x: x, | |
y: y | |
}); | |
} | |
} | |
} | |
formNumber(); | |
} | |
function formNumber() { | |
for (var i =; i < numberPixelCoordinates.length; i++) { | |
tweenDots(dots[i], numberPixelCoordinates[i], ''); | |
} | |
if (countdownRunning && countdownFrom >) { | |
setTimeout(function () { | |
breakNumber(); | |
}, countdownTimer); | |
} | |
} | |
function breakNumber() { | |
for (var i =; i < numberPixelCoordinates.length; i++) { | |
tweenDots(dots[i], '', 'space'); | |
} | |
if (countdownRunning) { | |
setTimeout(function () { | |
countdown(); | |
}, countdownTimer); | |
} | |
} |
循环绘制
function loop() { | |
stageCtx.clearRect(, 0, stageWidth, stageHeight); | |
for (var i =; i < dots.length; i++) { | |
dots[i].draw(stageCtx); | |
} | |
requestAnimationFrame(loop); | |
} | |
loop(); |
循环绘制,需要进入页面即执行,所以在方法之后马上执行该函数
点动画
在倒计时文本中,我们一直会调用tweenDots方法,就是用于点动画效果的绘制
function tweenDots(dot, pos, type) { | |
if (type === 'space') { | |
TweenMax.to(dot, ( + Math.round(Math.random() * 100) / 100), { | |
x: randomNumber(, stageWidth), | |
y: randomNumber(, stageHeight), | |
alpha:.3, | |
ease: Cubic.easeInOut, | |
onComplete: function () { | |
tweenDots(dot, '', 'space'); | |
} | |
}); | |
} else { | |
TweenMax.to(dot, (.5 + Math.round(Math.random() * 100) / 100), { | |
x: (pos.x + numberOffsetX), | |
y: (pos.y + numberOffsetY), | |
delay:, | |
alpha:, | |
ease: Cubic.easeInOut, | |
onComplete: function () {} | |
}); | |
} | |
} | |
function randomNumber(min, max) { | |
return Math.floor(Math.random() * (max - min) + min); | |
} |
- 随机移动画布周围的点
- 让点和文本内容协调展示