效果:
- 逼真的火焰跟随鼠标,还冒出火花,照亮背景文字
- 使用canvas绘制
- 使用javascript,但并无复杂逻辑。上手程度:简单
笔记:
google字体
第一步:
很简单的初始化函数。
var oCanvas;
init = function()
{
oCanvas = new Fire();
oCanvas.run();
}
window.onload = init;
web前端开发学习Q-q-u-n:784783012 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法
(学习工具,详细的前端项目实战教程,PDF)
第二步:
初始化canvas,定义各种基础的东西,以及为鼠标添加事件监测。addEventListener第三个参数的意思是,若为false,则为事件处理顺序为先进先处理,为true则为先进后处理。
var Fire = function(){
this.canvas = document.getElementById('fire');
this.ctx = this.canvas.getContext('2d');
this.canvas.height = window.innerHeight;
this.canvas.width = window.innerWidth;
this.aFires = [];
this.aSpark = [];
this.aSpark2 = [];
this.mouse = {
x : this.canvas.width * .5,
y : this.canvas.height * .75,
}
//一旦鼠标移动,就更新this.mouse.x和this.mouse.y,因为设置了false,所以先进来的事件先处理
this.canvas.addEventListener('mousemove', this.updateMouse.bind( this ), false);
}
Fire.prototype.updateMouse = function( e ){
this.mouse.x = e.clientX;
this.mouse.y = e.clientY;
}
web前端开发学习Q-q-u-n:784783012 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法
(学习工具,详细的前端项目实战教程,PDF)
第三步:
使用requestAnimationFrame使下一帧重新运行一遍run函数。为什么不用setInterval呢?因为内在运行机制会让它运行速度随机器性能变化而变化,导致时间控制不精确。而requestAnimationFrame使用系统时间,保证每秒执行60次。
并用bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
Fire.prototype.run = function(){
//重新新绘制火焰和火花
this.update();
this.draw();
//稳定重绘画面
requestAnimationFrame( this.run.bind( this ) );
}
第四步:
重新绘制一个火焰(实际上是红色的圆)和两个火花(实际上是小长方形)。若有火焰或火花的生命周期完了,那么就用删除它。否则继续更新它。
注意火焰火花原本被存储在数组里,所以删除用slice就好了。
web前端开发学习Q-q-u-n:784783012 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法
(学习工具,详细的前端项目实战教程,PDF)
Fire.prototype.update = function(){
//绘制新的火焰(红色的圆)以及火花
this.aFires.push( new Flame( this.mouse ) );
this.aSpark.push( new Spark( this.mouse ) );
this.aSpark2.push( new Spark( this.mouse ) );
//之前元素,即新的火焰(红色的圆)以及火花的生命周期未完的话,就继续更新它,否则就删除它
for (var i = this.aFires.length - 1; i >= 0; i--) {
if( this.aFires[i].alive )
this.aFires[i].update();
else
this.aFires.splice( i, 1 );
}
for (var i = this.aSpark.length - 1; i >= 0; i--) {
if( this.aSpark[i].alive )