HTML5 Canvas火焰文字动画特效

2018-01-31 RaymondMr

本文作者html5tricks,转载请注明出处

HTML5 技术确实挺强大的,特别是Canvas画布更是让网页动画变得丰富多彩。今天我们分享的是一款基于HTML5 Canvas的火焰文字动画特效,它可以让任意文字上方冒出密集的火焰,就像这些文字在熊熊燃烧一样。与这款火焰动画类似的还有以前分享的 HTML5 Canvas幻彩火焰文字特效

在线演示 源码下载

接下来我们一起来看看如何实现这款炫酷的HTML5 Canvas火焰文字动画特效。

HTML代码

由于是基于Canvas的,所有的动画细节都在Canvas上绘制实现,因此html代码就非常简单,仅仅提供一个canvas元素即可。代码如下:

<canvas id="canvas" width="1024" height="600"></canvas>

别看这简单的一个元素,它结合CSS3和JavaScript可以实现非常复杂的动画。

CSS3代码

CSS代码也没有什么特别,仅仅是定义Canvas的背景颜色:

canvas {
  background-color:#000000;
  left: 0;
}

JavaScript代码

这里我们用到了前端游戏引擎框架CreateJS,这火焰动画正是通过这个框架实现。

首先我们在页面上引用脚本框架:

<script src='js/createjs.min.js'></script>
<script src='js/Text3.js'></script>

接下来的JS代码就是初始化动画效果:

var canvas, stage, exportRoot;
var hello;
function init() {
	// --- write your JS code here ---

	canvas = document.getElementById("canvas");
	exportRoot = new lib.Text3();

	canvas.width = window.innerWidth;
	canvas.height = window.innerHeight;

	stage = new createjs.Stage(canvas);
	createjs.Touch.enable(stage);
	stage.addChild(exportRoot);
	stage.update();

	hello = exportRoot.hello;
	stage.on("stagemousedown", handleClick, this);

	container = new createjs.Container();
	exportRoot.addChild(container);

	createjs.Ticker.timingMode = createjs.Ticker.RAF;
	createjs.Ticker.on("tick", onTick);

	handleResize();
	window.addEventListener("resize", handleResize);

	createjs.Tween.get(this).wait(1000).call(function() {
    handleClick()
  })

}

function handleResize() {
	canvas.width = window.innerWidth;
	canvas.height = window.innerHeight;

	scale = Math.min(canvas.width, canvas.height)/720;

	exportRoot.scaleX = exportRoot.scaleY = scale;
	exportRoot.regX = 1024/2;
	exportRoot.regY = 600/2;
	exportRoot.x = canvas.width>>1;
	exportRoot.y = canvas.height>>1;
	stage.update(lastEvent);
}

function handleClick() {
	container.removeAllChildren();
	createjs.Tween.removeAllTweens();

	mapClip(hello.letter1, getRange(120, 160)| 0, {width:181, height:266});
	mapClip(hello.letter2, getRange(120, 160)| 0, {width:161, height:266});
	mapClip(hello.letter3, getRange(110, 130)| 0, {width:155, height:266});
	mapClip(hello.letter4, getRange(110, 130)| 0, {width:155, height:266});
	createjs.Tween.get(hello.letter5).to({alpha:0, y:hello.letter5.y + 200}, 1000);
}

function mapClip(clip, total, area) {
	for(var i=0;i<total;i++) {
		var pt = clip.localToGlobal(0, 0);
		var pt1 = exportRoot.globalToLocal(pt.x, pt.y);
		var _x = Math.random()*area.width | 0;
		var _y = Math.random()*area.height | 0;
		if (clip.hitTest(_x, _y)) {
			var _ball =  getParticle(100, "#F1d345", "rgba(143,0,0,0)");
			var scale = getRange(0.9,1.5);
			_ball.x = pt1.x+(_x*hello.scaleX);
			_ball.y = pt1.y+(_y*hello.scaleX);
			_ball.scaleX = _ball.scaleY = scale;
			createjs.Tween.get(_ball, {loop:true})
								.to({x:(_ball.x-150) + (Math.random()*250)|0, y:(_ball.y-50)-(Math.random()*350)|0}, 1500+Math.random()*2000 | 0)
								.to({x:(_ball.x-150) + (Math.random()*100)|0, y:(_ball.y-250)-(Math.random()*250)|0}, 1500+Math.random()*2500 | 0);
			_ball.compositeOperation = "lighter";
			container.addChild(_ball)
		}
	}
}

function getRange(min, max) {
	var scale = max - min;
	return Math.random()*scale + min;
}

function getParticle(radius, color1, color2) {
  var shape = new createjs.Shape();
  shape.graphics.rf([color1, color2], [0, 1], 0, 0, 0, 0, 0, radius/2).dc(0, 0, radius);
  shape.cache(-radius/2, -radius/2, radius, radius);
  return shape;
}

var lastEvent;
function onTick(event) {
	lastEvent = event;
	stage.update(event);
}
init();

这里正是调用了CreateJS实现了火焰模拟动画,效果是不是很赞。大家也可以研究一下CreateJS游戏开发库,这种简单的动画只是库里面很小一部分。