Java基础、中级、高级、架构面试资料

使用HTML5 Canvas实现火焰风暴动画

HTML5 herman 3899浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

继续我们的 HTML5 动画学习系列。本文将为大家分享一款基于 HMTL5 Canvas 实现的火焰风暴动画,通过本文的学习,你将进一步加深对 HTML5 动画的理解。

火焰风暴动画是利用HTML5技术实现的。前面我们已经实现过不少动画特效的HTML5应用,尤其是和Canvas搭配。这次给大家带来的是一款基于HTML5 Canvas的火焰风暴动画特效,改动画效果就像从天上掉落火焰一样,火焰风暴逐渐蔓延到整一个画布。

火焰风暴动画

HTML5 Canvas 火焰风暴动画

相关实现的html5代码如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>HTML5 Canvas炫酷的火焰风暴动画|业余草|www.xttblog.com</title>
  <link rel="stylesheet" href="css/reset.css">
  <link rel="stylesheet" href="css/style.css" media="screen" type="text/css" />
</head>
<body>
  <script src="js/index.js"></script>
</body>
</html>

相关 JavaScript 代码如下:

var c = document.createElement( 'canvas' ),
    ctx = c.getContext( '2d' ),
    w = c.width = 600,
    h = c.height = 400,
    particles = [],
    particleCount = 1000,
    particlePath = 4,
    pillars = [],
    pillarCount = 110,
    hue = 0,
    hueRange = 60,
    hueChange = 1,
    gravity = 0.1,
    lineWidth = 1,
    lineCap = 'round',
    PI = Math.PI,
    TWO_PI = PI * 2;
function rand( min, max ) {
	return Math.random() * ( max - min ) + min;
}
function distance( a, b ) {
  var dx = a.x - b.x,
      dy = a.y - b.y;
  return Math.sqrt( dx * dx + dy * dy );
}
function Particle( opt ) {
  this.path = [];
  this.reset();
}
Particle.prototype.reset = function() {
  this.radius = 1;
  this.x = rand( 0, w );
  this.y = 0;
  this.vx = 0;
  this.vy = 0;
  this.hit = 0;
  this.path.length = 0;
};
Particle.prototype.step = function() {
  this.hit = 0;
  this.path.unshift( [ this.x, this.y ] );
  if( this.path.length > particlePath ) {
    this.path.pop();
  }
  this.vy += gravity;
  this.x += this.vx;
  this.y += this.vy;
  if( this.y > h + 10 ) {
    this.reset();
  }
  var i = pillarCount;
  while( i-- ) {
    var pillar = pillars[ i ];
    if( distance( this, pillar ) < this.radius + pillar.renderRadius ) {
      this.vx = 0;
      this.vy = 0;
      this.vx += -( pillar.x - this.x ) * rand( 0.01, 0.03 );
      this.vy += -( pillar.y - this.y ) * rand( 0.01, 0.03 );
      pillar.radius -= 0.1;
      this.hit = 1;
    }
  }
};
Particle.prototype.draw = function() {
  ctx.beginPath();
  ctx.moveTo( this.x, ~~this.y );
  for( var i = 0, length = this.path.length; i < length; i++ ) {
    var point = this.path[ i ];
    ctx.lineTo( point[ 0 ], ~~point[ 1 ] );
  }
  ctx.strokeStyle = 'hsla(' + rand( hue + ( this.x / 3 ), hue + ( this.x / 3 ) + hueRange ) + ', 50%, 30%, 0.3)';
  ctx.stroke();
  if( this.hit ) {
    ctx.beginPath();
    ctx.arc( this.x, this.y , rand( 1, 25 ), 0, TWO_PI );
    ctx.fillStyle = 'hsla(' + rand( hue + ( this.x / 3 ), hue + ( this.x / 3 ) + hueRange ) + ', 80%, 15%, 0.1)'
    ctx.fill();
  }
};
function Pillar() {
  this.reset();
}
Pillar.prototype.reset = function(){
  this.radius = rand( 50, 100 );
  this.renderRadius = 0;
  this.x = rand( 0, w );
  this.y = rand( h / 2 - h / 4, h );
  this.active = 0;
};
Pillar.prototype.step = function() {
  if( this.active ) {
    if( this.radius <= 1 ) {
      this.reset();
    } else {
      this.renderRadius = this.radius;
    }
  } else {
    if( this.renderRadius < this.radius ) {
      this.renderRadius += 0.5;
    } else {
      this.active = 1;
    }
  }
};
Pillar.prototype.draw = function() {
  ctx.beginPath();
  ctx.arc( this.x, this.y, this.renderRadius, 0, TWO_PI, false );
  ctx.fill();
};
function init() {
  ctx.lineWidth = lineWidth;
  ctx.lineCap = lineCap;
  var i = pillarCount;
  while( i-- ){
    pillars.push( new Pillar() );
  }
  document.body.appendChild( c );
  loop();
}
function step() {
  hue += hueChange;
  if( particles.length < particleCount ) {
    particles.push( new Particle() );
  }
  var i = particles.length;
  while( i-- ) {
    particles[ i ].step();
  }
  i = pillarCount;
  while( i-- ) {
    pillars[ i ].step();
  }
}
function draw() {
  ctx.fillStyle = 'hsla(0, 0%, 0%, 0.1)';
  ctx.fillRect( 0, 0, w, h );
  ctx.globalCompositeOperation = 'lighter';
  var i = particles.length;
  while( i-- ) {
    particles[ i ].draw();
  }
  ctx.globalCompositeOperation = 'source-over';
  i = pillarCount;
  ctx.fillStyle = 'rgba(20, 20, 20, 0.3)';
  while( i-- ) {
    pillars[ i ].draw();
  }
}
function loop() {
  requestAnimationFrame( loop );
  step();
  draw();
}
init();

 相关 css 代码如下:

html,
body {
  height: 100%;
}

body {
  background: #111;
  background: radial-gradient(#222, #000);
  overflow: hidden;
}
canvas {
  background: #000;
  bottom: 0;
  box-shadow:
    0 0 0 10px #222,
    0 30px 30px -20px #000
  ;
  left: 0;
  margin: auto;
  max-height: 100%;
  max-width: 100%;
  position: absolute;
  right: 0;
  top: 0;
}

reset.css 是重置浏览器样式的代码。大家可以使用网上免费的cdn代码。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 使用HTML5 Canvas实现火焰风暴动画