Last active
August 29, 2015 14:08
-
-
Save taoalpha/8aaf18ad3843fdd5235d to your computer and use it in GitHub Desktop.
Use canvas show a beautiful fireworks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>I love U</title> | |
| <meta charset="UTF-8"> | |
| <script type="text/javascript" src="jquery.min.js"></script> | |
| <script type="text/javascript" src="improvedNoise.js"></script> | |
| <script type="text/javascript" src="fizzyText.js"></script> | |
| <script type="text/javascript"> | |
| //requestAnimationFrame动画方法的兼容性 | |
| (function() { | |
| var lastTime = 0; | |
| var vendors = ['webkit', 'moz']; | |
| for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { | |
| window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; | |
| window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // Webkit中此取消方法的名字变了 | |
| window[vendors[x] + 'CancelRequestAnimationFrame']; | |
| } | |
| if (!window.requestAnimationFrame) { | |
| window.requestAnimationFrame = function(callback, element) { | |
| var currTime = new Date().getTime(); | |
| var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); | |
| var id = window.setTimeout(function() { | |
| callback(currTime + timeToCall); | |
| }, timeToCall); | |
| lastTime = currTime + timeToCall; | |
| return id; | |
| }; | |
| } | |
| if (!window.cancelAnimationFrame) { | |
| window.cancelAnimationFrame = function(id) { | |
| clearTimeout(id); | |
| }; | |
| } | |
| }()); | |
| </script> | |
| <script type="text/javascript"> | |
| //配置参数-全局参数 | |
| var gravity = 0.01 //重力加速度 | |
| var colorweaken = 0.003//颜色衰减速度 | |
| var tail = 0.2//小球拖尾效果(1为无,0为拖尾不消失) | |
| var stopCount = 0 //切换爆炸效果到闪烁效果 | |
| //配置参数-升空部分 | |
| var ammospeed = 5 //出膛速度 | |
| var ammoradius = 15 //弹药半径 | |
| var ammocolor = '255,100,0' //弹药颜色 | |
| var ammoalpha= 0.8 //弹药透明度 | |
| //配置参数-爆炸部分 | |
| var maxballcount = 500//小球最大数量 | |
| var ballradius = 3//小球半径 | |
| var startspeedx = 4//横向初速度范围(-x到x) | |
| var startspeedy = 4//纵向初速度范围(向上,-y到0) | |
| var newballcount = 10//每轮补球最大数量 | |
| var tail = 0.2//小球拖尾效果(1为无,0为拖尾不消失) | |
| //全局对象 | |
| var canvas //绘图对象 | |
| var context //绘图内容 | |
| var imgData //当前图形 | |
| var balls = new Array() //小球数组 | |
| var ammo = new Object() //升空火药 | |
| var framestarttime//计算帧数开始时间 | |
| var framecount = 0//上次计数清空以来经过的帧数 | |
| var lastframecount = 0//上一秒的帧数 | |
| //页面加载 | |
| $(function () { | |
| init() | |
| }) | |
| //初始化 | |
| function init() { | |
| canvas = document.getElementById("image") | |
| textbitmap = document.getElementById("image") | |
| if (!canvas.getContext) self.location = "/nohtml5.html" | |
| else { | |
| var container = $("#container") | |
| container.width($(window).width()) | |
| container.height($(window).height()) | |
| canvas.width = container.width() | |
| textbitmap.width = container.width() | |
| canvas.height = container.height() | |
| textbitmap.height = container.height() | |
| context = canvas.getContext("2d") | |
| tbcontext = textbitmap.getContext("2d") | |
| tbcontext.font = "16px Arial" | |
| tbcontext.textAlign = "center"; | |
| tbcontext.textBaseline = "middle"; | |
| framestarttime = new Date() | |
| //开始动画 | |
| //ammolauch() | |
| ammo.speedy = ammospeed | |
| ammo.x = canvas.width/2 | |
| ammo.y = canvas.height-50 | |
| ammo.alpha = 1 | |
| ammo.color = ammocolor | |
| ammo.r = ammoradius | |
| drawammo(ammo) | |
| ammoflying() | |
| } | |
| } | |
| // 运行弹药升空环节 | |
| function ammoflying() { | |
| //绘制半透明遮罩,淡化上一帧的颜色以达到拖尾效果 | |
| context.fillStyle = "rgba(0,0,0," + tail + ")" | |
| context.fillRect(0, 0, canvas.width, canvas.height) | |
| ammo.speedy -= gravity//重力 | |
| ammo.y -= ammo.speedy | |
| if(ammo.y<100) ammo.alpha = 0 | |
| if (ammo.speedy < 0 || ammo.y<50) { | |
| // 控制弹药爆炸位置 | |
| cancelAnimationFrame(ammoflying) | |
| ammoexplode() | |
| }else{ | |
| drawammo(ammo) | |
| requestAnimationFrame(ammoflying) | |
| } | |
| } | |
| //弹药闪烁 | |
| function ammoshining() { | |
| } | |
| // 绘制弹药 | |
| function drawammo(ammo) { | |
| context.beginPath() | |
| context.arc(ammo.x, ammo.y, ammo.r, 0, Math.PI * 2, true) | |
| context.closePath() | |
| context.fillStyle = "rgba(" + ammo.color + "," + ammo.alpha + ")" | |
| context.fill() | |
| } | |
| //弹药爆炸 | |
| function ammoexplode() { | |
| //绘制半透明遮罩,淡化上一帧的颜色以达到拖尾效果 | |
| context.fillStyle = "rgba(0,0,0," + tail + ")" | |
| context.fillRect(0, 0, canvas.width, canvas.height) | |
| var newballs = new Array()//下一帧小球数组 | |
| for (var i in balls) { | |
| var ball = balls[i] | |
| ball.speedy += gravity//重力 | |
| ball.x += ball.speedx | |
| ball.y += ball.speedy | |
| ball.alpha -= colorweaken | |
| if (ball.x > 0 && ball.x < canvas.width && ball.y > 0 && ball.y < canvas.height && ball.alpha > 0) { | |
| //只有小球在界内并尚未完全透明时才显示并保留到下一帧 | |
| newballs.push(ball) | |
| drawball(ball) | |
| } | |
| } | |
| //如果数量不足(初始,或有球出界),则补球,但不能超过最大数量 | |
| //if (newballs.length < maxballcount) { | |
| for (var i = 0; i < Math.min(newballcount, maxballcount - newballs.length); i++) { | |
| newballs.push(generaterandomball()) | |
| stopCount ++ | |
| } | |
| //} | |
| //交换帧 | |
| balls = newballs | |
| newballs = null | |
| if(stopCount>800) { | |
| cancelAnimationFrame(ammoexplode) | |
| var fizzyText = new FizzyText(document.getElementById("image"), "XXX,我爱你!", window.innerWidth, window.innerHeight) | |
| } | |
| else{ | |
| requestAnimationFrame(ammoexplode) | |
| } | |
| } | |
| //绘制单个小球 | |
| function drawball(ball) { | |
| if (!ball) return | |
| context.beginPath() | |
| context.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2, true) | |
| context.closePath() | |
| context.fillStyle = "rgba(" + ball.color + "," + ball.alpha + ")" | |
| context.fill() | |
| } | |
| //生成随机颜色和速度的球 | |
| function generaterandomball() { | |
| var ball = new Object() | |
| //初始位置在中央区域 | |
| //ball.x = Math.round(Math.random() * canvas.width / 10) + (canvas.width / 2 - canvas.width / 20) | |
| ball.x = canvas.width / 2 | |
| ball.y = Math.round(Math.random() * 50) + (75) | |
| ball.r = ballradius | |
| ball.color = randomcolor() | |
| ball.alpha = 1 | |
| //小球初速度,横向随机,纵向默认向上 | |
| ball.speedx = Math.round(Math.random() * startspeedx*4) - startspeedx*2 | |
| ball.speedy = Math.round(Math.random() * startspeedy*2) - startspeedy | |
| return ball | |
| } | |
| //生成RGB字符串格式的颜色 | |
| function randomcolor() { | |
| var yellow = Math.round(Math.random() * 255) | |
| return "255," + yellow + ",0" | |
| } | |
| </script> | |
| <style type="text/css"> | |
| body { | |
| margin: 0px; | |
| } | |
| #container { | |
| width: 100%; | |
| height: 100%; | |
| } | |
| #image { | |
| background-color: #000; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="container"> | |
| <canvas id="image"> | |
| </canvas> | |
| </div> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment