<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Canvas煙花
</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
<style type="text/css">body{padding: 0;margin: 0;background: #000;}
</style>
</head>
<body><canvas id="canvas">Canvas is not supported in your browser.
</canvas><script type="text/javascript">window.requestAnimationFrame = (function(){return window.requestAnimationFrame ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||function(callback){window.setTimeout(callback,1000/60);}})();var canvas = document.getElementById("canvas"),ctx = canvas.getContext("2d"),cw = window.innerWidth,ch = window.innerHeight,fireworks = [], particles = [], hue = 120, timerTotal = 80, timerTick = 0;canvas.width = cw;canvas.height = ch;function random(min,max){return Math.random()*(max-min)+min;}function caculateDistance(sx,sy,tx,ty){var xDistance = sx-tx,yDistance = sy-ty;return Math.sqrt(Math.pow(xDistance,2)+Math.pow(yDistance,2));}function Firework(sx,sy,tx,ty){this.x = sx; this.y = sy; this.sx = sx; this.sy = sy; this.tx= tx; this.ty = ty; this.distanceToTarget = caculateDistance(sx,sy,tx,ty); this.distanceTraveled = 0; this.coordinates = []; this.coordinatesCount = 3;while(this.coordinatesCount--){this.coordinates.push([this.x,this.y]);}this.angle = Math.atan2(ty-sy,tx-sx); this.speed = 2; this.acceleration = 1.05 this.brightness = random(50,70); this.targetRadius = 1; }Firework.prototype.update = function(index){this.coordinates.pop(); this.coordinates.unshift([this.x,this.y]);if(this.targetRadius<8) {this.targetRadius += 0.3;} else {this.targetRadius = 1;}this.speed *= this.acceleration; var vx = Math.cos(this.angle)*this.speed,vy = Math.sin(this.angle)*this.speed; this.distanceTraveled = caculateDistance(this.sx,this.sy,this.x+vx,this.y+vy); if(this.distanceTraveled>=this.distanceToTarget){createParticles(this.tx,this.ty);fireworks.splice(index,1);}else{this.x += vx;this.y += vy;}}Firework.prototype.draw = function(){ctx.beginPath();ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][1]);ctx.lineTo(this.x,this.y);ctx.strokeStyle = 'hsl('+hue+',100%,'+this.brightness+'%)';ctx.stroke();ctx.beginPath();ctx.arc(this.tx,this.ty,this.targetRadius,0,Math.PI*2);ctx.stroke();}function Particle(x,y){this.x = x;this.y = y;this.coordinates = [];this.coordinatesCount = 5;while(this.coordinatesCount--){this.coordinates.push([this.x,this.y]);}this.angle = random(0,2*Math.PI); this.speed = random(1,10); this.friction = 0.95 this.gravity = 1; this.hue = random(hue-20,hue+20); this.brightness = random(50,80); this.alpha = 1; this.decay = random(0.015,0.03); }Particle.prototype.update = function(index){this.coordinates.pop(); this.coordinates.unshift([this.x,this.y]);this.speed *= this.friction;this.x += Math.cos(this.angle) * this.speed;this.y += Math.sin(this.angle) * this.speed + this.gravity;this.alpha -= this.decay;if(this.alpha<=this.decay){particles.splice(index,1);}}Particle.prototype.draw = function(){ctx.beginPath();ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][1]);ctx.lineTo(this.x,this.y);ctx.strokeStyle = 'hsla('+this.hue+',100%,'+this.brightness+'%,'+this.alpha+')';ctx.stroke();}function createParticles(x,y){var particleCount = 30;while(particleCount--) {particles.push(new Particle(x,y));}}function loop(){requestAnimationFrame(loop);hue += 0.5;ctx.globalCompositeOperation = 'destination-out';ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';ctx.fillRect( 0, 0, cw, ch );ctx.globalCompositeOperation = 'lighter';var i = fireworks.length;while(i--) {fireworks[i].draw();fireworks[i].update(i);}var i = particles.length;while(i--) {particles[i].draw();particles[i].update(i);}if(timerTick >= timerTotal) {fireworks.push(new Firework(cw/2,ch,random(0,cw),random(0,ch/2)));timerTick = 0;} else {timerTick++;}}window.onload = loop;</script>
</body>
</html>
這個效果之前是在runjs上看到的,看了一段時間才看懂,根據自己的理解,較少了一些效果。
window.requestAnimationFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback){
window.setTimeout(callback,1000/60);//每秒60幀
}
})();
var canvas = document.getElementById(“canvas”),
ctx = canvas.getContext(“2d”),
cw = window.innerWidth,
ch = window.innerHeight,
fireworks = [], //煙花數組
particles = [], //煙花爆炸屑數字
hue = 120, //初始色調 0/360 紅色 120 綠色 240 藍色
timerTotal = 80, //每隔80下釋放一次煙花
timerTick = 0;
//設置canvas畫布的寬高
canvas.width = cw;
canvas.height = ch;
//生成min到max之間的隨機數
function random(min,max){
return Math.random()*(max-min)+min;
}
//計算點(sx,sy)到點(tx,ty)之間的距離
function caculateDistance(sx,sy,tx,ty){
var xDistance = sx-tx,
yDistance = sy-ty;
return Math.sqrt(Math.pow(xDistance,2)+Math.pow(yDistance,2));
}
//煙花對象 (sx,sy)初始位置 (tx,ty)目標位置
function Firework(sx,sy,tx,ty){
this.x = sx; //實時運行坐標x
this.y = sy; //實時運行坐標y
this.sx = sx; //初始位置坐標x
this.sy = sy; //初始位置坐標Y
this.tx= tx; //目標位置坐標x
this.ty = ty; //目標位置坐標Y
this.distanceToTarget = caculateDistance(sx,sy,tx,ty); //計算初始位置到目標位置之間的距離
this.distanceTraveled = 0; //已運行距離
this.coordinates = []; //我理解是一個輔助變量 用于生成實時運動軌跡
this.coordinatesCount = 3;
while(this.coordinatesCount–){
this.coordinates.push([this.x,this.y]);
}
this.angle = Math.atan2(ty-sy,tx-sx); //初始位置和目標位置之間的角度
this.speed = 2; //初始速度
this.acceleration = 1.05 //加速度
this.brightness = random(50,70); //明度
this.targetRadius = 1; //目標位置標示圓圈的初始半徑
}
//更新煙花的位置
Firework.prototype.update = function(index){
this.coordinates.pop();
this.coordinates.unshift([this.x,this.y]);
//上面是一個技巧吧 先將數組最后一個移除,然后將當前煙花位置插入到第一個,那數組最后一個元素和更新之后的坐標之間就形成了一條軌跡
//讓目標標示處圓圈動起來
if(this.targetRadius<8) {
this.targetRadius += 0.3;
} else {
this.targetRadius = 1;
}
this.speed *= this.acceleration; //根據加速度變換速度
var vx = Math.cos(this.angle)*this.speed,//計算水瓶方向速度
vy = Math.sin(this.angle)*this.speed; //計算垂直方向速度
this.distanceTraveled = caculateDistance(this.sx,this.sy,this.x+vx,this.y+vy); //重新計算煙花已運行距離
//如果煙花運行距離大于或等于初始位置到目標位置之間的距離,生成新煙花并移除當前煙花,否則更新煙花位置
if(this.distanceTraveled>=this.distanceToTarget){
createParticles(this.tx,this.ty);
fireworks.splice(index,1);
}else{
this.x += vx;
this.y += vy;
}
}
Firework.prototype.draw = function(){
//畫出煙花運行軌跡
ctx.beginPath();
ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][1]);
ctx.lineTo(this.x,this.y);
ctx.strokeStyle = ‘hsl(‘+hue+’,100%,’+this.brightness+’%)’;
ctx.stroke();
//畫出目標位置標示小圓圈ctx.beginPath();ctx.arc(this.tx,this.ty,this.targetRadius,0,Math.PI*2);ctx.stroke();
}
//煙花爆炸屑對象
function Particle(x,y){
this.x = x;
this.y = y;
this.coordinates = [];
this.coordinatesCount = 5;
while(this.coordinatesCount–){
this.coordinates.push([this.x,this.y]);
}
this.angle = random(0,2*Math.PI); //生成任意方向的碎屑
this.speed = random(1,10); //隨機速度
this.friction = 0.95 //摩擦力
this.gravity = 1; //重力
this.hue = random(hue-20,hue+20); //生成與煙花色彩相近的碎屑
this.brightness = random(50,80); //隨機明度
this.alpha = 1; //初始透明度
this.decay = random(0.015,0.03); //碎屑消失時間
}
Particle.prototype.update = function(index){
this.coordinates.pop();
this.coordinates.unshift([this.x,this.y]);
//上面是一個技巧吧 先將數組最后一個移除,然后將當前煙花位置插入到第一個,那數組最后一個元素和更新之后的坐標之間就形成了一條軌跡
this.speed *= this.friction;
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed + this.gravity;
this.alpha -= this.decay;
if(this.alpha<=this.decay){
particles.splice(index,1);
}
}
Particle.prototype.draw = function(){
ctx.beginPath();
ctx.moveTo(this.coordinates[this.coordinates.length-1][0],this.coordinates[this.coordinates.length-1][1]);
ctx.lineTo(this.x,this.y);
ctx.strokeStyle = ‘hsla(‘+this.hue+’,100%,’+this.brightness+’%,’+this.alpha+’)’;
ctx.stroke();
}
function createParticles(x,y){
//生成30個煙花碎屑
var particleCount = 30;
while(particleCount–) {
particles.push(new Particle(x,y));
}
}
function loop(){
//流暢動畫過程
requestAnimationFrame(loop);
hue += 0.5;
ctx.globalCompositeOperation = ‘destination-out’;
ctx.fillStyle = ‘rgba(0, 0, 0, 0.5)’;
ctx.fillRect( 0, 0, cw, ch );
ctx.globalCompositeOperation = ‘lighter’;
var i = fireworks.length;
while(i–) {
fireworks[i].draw();
fireworks[i].update(i);
}
var i = particles.length;
while(i–) {
particles[i].draw();
particles[i].update(i);
}
if(timerTick >= timerTotal) {
fireworks.push(new Firework(cw/2,ch,random(0,cw),random(0,ch/2)));
timerTick = 0;
} else {
timerTick++;
}
}
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta name="Generator" content="EditPlusR"><meta name="Author" content=""><meta name="Keywords" content=""><meta name="Description" content=""><title>Document
</title><style>body{margin:0;padding:0;overflow: hidden;}.city{width:100%;position:fixed;bottom: 0px;z-index: 100;}.city img{width: 100%;}</style></head><body><canvas id='cas' style="background-color:rgba(0,5,24,1)">canvas
</canvas><div class="city"><img src="city.png" alt="" /></div><img src="moon.png" alt="" id="moon" style="visibility: hidden;"/><div style="display:none"><div class="shape">HAPPY
</div><div class="shape">HAPPY
</div><div class="shape">HAPPY
</div><div class="shape">HAPPY
</div><div class="shape">HAPPY
</div></div><audio src="boom.mp3" preload="auto"></audio><audio src="boom.mp3" preload="auto"></audio><audio src="boom.mp3" preload="auto"></audio><audio src="boom.mp3" preload="auto"></audio><audio src="boom.mp3" preload="auto"></audio><audio src="boom.mp3" preload="auto"></audio><audio src="shotfire.mp3" preload="auto"></audio><audio src="shotfire.mp3" preload="auto"></audio><audio src="shotfire.mp3" preload="auto"></audio></body><script>var cas=document.getElementById('cas'),ctx=cas.getContext('2d'),ocas=document.createElement('canvas'),octx=ocas.getContext('2d'),cw=document.compatMode=='BackCompat'?document.body.clientWidth:document.documentElement.clientWidth,ch=document.compatMode=='BackCompat'?document.body.clientHeight:document.documentElement.clientHeight,last,now,stars=[],booms=[],moon=document.getElementById('moon'),shape=document.querySelectorAll('.shape'),audio=document.getElementsByTagName('audio');cas.width=ocas.width=cw;cas.height=ocas.height=ch;window.onload=function(){createStars();last=+new Date();animate();}function animate(){ctx.save();ctx.globalCompositeOperation='destination-out';ctx.globalAlpha=0.1;ctx.fillRect(0,0,cw,ch);ctx.restore();stars.forEach(function(){this.paint();});createMoon();now=+new Date();if(now-last>1000){var rand=getRand(0,100)>50?true:false,num=Math.floor(getRand(0,shape.length)),x=getRand(cw/3,cw*2/3),y=ch,r=2,color='#fff',tx=getRand(cw/5,cw*4/5),ty=getRand(50,ch-300);if(rand){booms.push(new Firework(x,y,r,color,tx,ty));}else{booms.push(new Firework(x,y,r,color,tx,ty,shape[num]));}for(var i=0;i<audio.length;i++){if(audio[i].src.indexOf('shotfire')>=0 && (audio[i].paused || audio[i].ended)){audio[i].play();break;}}last=now;}booms.forEach(function(){var that=this;if(!this.dead){this.update();this.smoke();}else{this.booms.forEach(function(index){if(!this.dead){this.update();}else{if(index==that.booms.length){booms.splice(booms.indexOf(that),1);}}});}});requestAnimationFrame(animate);}function Particle(x,y,r,color,tx,ty){this.x=x;this.y=y;this.r=r;this.color=color;this.tx=tx;this.ty=ty;this.dead=false;}Particle.prototype={paint:function(){ctx.beginPath();ctx.fillStyle='rgba('+this.color.a+','+this.color.b+','+this.color.c+',1)';ctx.fillRect(this.x-this.r,this.y-this.r,2*this.r,2*this.r);ctx.closePath();},update:function(){this.ty+=0.3;var dx=this.tx-this.x,dy=this.ty-this.y;if(Math.abs(dx)<0.1 && Math.abs(dy)<20){this.dead=true;}else{this.x=Math.abs(dx)<0.1?this.tx:this.x+dx*0.1;this.y=Math.abs(dy)<0.1?this.ty:this.y+dy*0.1;this.paint();}}}function Firework(x,y,r,color,tx,ty,shape){this.x=x;this.y=y;this.r=r;this.color=color;this.tx=tx;this.ty=ty;this.shape=shape || false;this.dead=false;this.ba=getRand(30,50);this.booms=[];}Firework.prototype={paint:function(){ctx.save();ctx.beginPath();ctx.fillStyle=this.color;ctx.arc(this.x,this.y,this.r,0,2*Math.PI);ctx.fill();ctx.closePath();ctx.restore();},smoke:function(){ctx.save();ctx.beginPath();ctx.fillStyle='rgba(255,228,150,0.3)';ctx.arc(this.x,this.y,this.r+Math.random()*3,0,2*Math.PI);ctx.fill();ctx.closePath();ctx.restore();},update:function(){var dx=this.tx-this.x,dy=this.ty-this.y;if(Math.abs(dx)<this.ba && Math.abs(dy)<this.ba){this.dead=true;if(this.shape){this.shapeBoom();}else{this.boom();}for(var i=0;i<audio.length;i++){if(audio[i].src.indexOf('boom')>=0 && (audio[i].paused || audio[i].ended)){audio[i].play();break;}}}else{this.x+=dx*0.03;this.y+=dy*0.03;this.paint();}},boom:function(){var count=getRand(100,300),r,color,tx,ty,angle,distance;for(var i=0;i<count;i++){r=getRand(1,3);angle=getRand(-Math.PI,Math.PI);color={a:parseInt(getRand(0,255)),b:parseInt(getRand(0,255)),c:parseInt(getRand(0,255))},distance=getRand(0,count);tx=Math.cos(angle)*distance+this.x;ty=Math.sin(angle)*distance+this.y;this.booms.push(new Particle(this.x,this.y,r,color,tx,ty));}},shapeBoom:function(){var that=this,step=4,dx=cw/2-this.tx,dy=ch/2-this.ty;getData(this.shape,step,function(dots){dots.forEach(function(){that.booms.push(new Particle(that.x,that.y,1,this.color,this.x-dx,this.y-dy));});});}}function getData(dom,step,callback){var text=dom.innerHTML,imgData=[],dots=[],i;octx.clearRect(0,0,cw,ch);octx.save();octx.font='120px 微?雅黑 bold';octx.textAlign='center';octx.textBaseline='middle';octx.fillStyle='rgba('+parseInt(getRand(168,255))+','+parseInt(getRand(168,255))+','+parseInt(getRand(168,255))+',1)';octx.fillText(text,cw/2,ch/2);octx.restore();imgData=octx.getImageData(0,0,cw,ch);for(var x=0;x<imgData.width;x+=step){for(var y=0;y<imgData.height;y+=step){i=(y*imgData.width+x)*4;if(imgData.data[i+3]>167){dots.push({x:x,y:y,color:{a:imgData.data[i],b:imgData.data[i+1],c:imgData.data[i+2]}});}}}callback(dots);}function createMoon(){var sx=cw-200,sy=100,r=40,add=2;if(moon.complete){ctx.drawImage(moon,sx,sy,2*r,2*r);}else{moon.onload=function(){ctx.drawImage(moon,sx,sy,2*r,2*r);}}ctx.save();ctx.beginPath();ctx.fillStyle='rgba(240,219,120,0.05)';for(var i=0;i<5;i++){ctx.arc(sx+r,sy+r,r+add,0,2*Math.PI);ctx.fill();add+=2;}ctx.closePath();ctx.restore();}function createStars(){for(var i=0;i<100;i++){stars.push(new Star(getRand(0,cw),getRand(0,ch-200),Math.random(),'#fff'));}}function Star(x,y,r,color){this.x=x;this.y=y;this.r=r;this.color=color;}Star.prototype={paint:function(){ctx.save();ctx.beginPath();ctx.fillStyle=this.color;ctx.arc(this.x,this.y,this.r,0,2*Math.PI);ctx.fill();ctx.closePath();ctx.restore();}}function getRand(min,max){return Math.random()*(max-min)+min;}Array.prototype.forEach=function(callback){for(var i=0;i<this.length;i++){if(this[i]!=null){callback.call(this[i],i);}}}</script>
</html>
鼠標點擊實現
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta name="Generator" content="EditPlusR"><meta name="Author" content=""><meta name="Keywords" content=""><meta name="Description" content=""><title>?日快?
</title><style>*{margin:0;padding:0;list-style-type:none;}
a,img{border:0;}
body{font:12px/180% Arial, Helvetica, sans-serif, "新宋體";background:#000 url("pic.jpg") no-repeat center center;background-size: 100% 100%;}#canvas{cursor:crosshair;display:block;color:black;}</style></head><body><canvas id='canvas' width='100%' height='100%'></canvas>
<script type="text/javascript" src="lib/jquery-1.11.3.js"></script><script type="text/javascript">
var canvas=document.getElementById('canvas'),ctx=canvas.getContext('2d'),cw=window.innerWidth,ch=window.innerHeight,mousedown=!1,mx,my,last,now,timerTick=0,timerTotal=80,timeWait=0,timeWaitTotal=10,fireworks=[],particles=[],fl,pl,hue=120,accelerate=1.05,img=new Image();
canvas.width=cw;
canvas.height=ch;
img.src='pic.jpg';document.onmousedown=function(e){mousedown=!0;
}
document.onmouseup=function(e){mousedown=!1;
}
document.onmousemove=function(e){mx=e.pageX-canvas.offsetLeft;my=e.pageY-canvas.offsetTop;
}
window.onload=function(){last=+new Date();animate();
}
function animate(){now=+new Date();if(now-last>30){hue=getRand(50,80);ctx.globalCompositeOperation='destination-out';ctx.globalAlpha=0.5;ctx.fillRect(0,0,cw,ch);ctx.fill();ctx.globalCompositeOperation='lighter';ctx.drawImage(img,0,0,cw,ch);fl=fireworks.length-1;while(fl>=0){fireworks[fl].paint();fireworks[fl].update(fl);fl--;}pl=particles.length-1;while(pl>=0){particles[pl].paint();particles[pl].update(pl);pl--;}if(timerTick>timerTotal){if(!mousedown){fireworks.push(new Firework(cw/2,ch,getRand(0,cw),getRand(50,ch/2)));timerTick=0;}}else{timerTick++;}if(timeWait>timeWaitTotal){if(mousedown){fireworks.push(new Firework(cw/2,ch,mx,my));timeWait=0;}}else{timeWait++;}}if('requestAnimationFrame' in window){requestAnimationFrame(animate);}else if('mozRequestAnimationFrame' in window){mozRequestAnimationFrame(animate);}
}function Firework(sx,sy,tx,ty){this.x=sx;this.y=sy;this.tx=tx;this.ty=ty;this.radius=1;this.brightness=getRand(50,70);this.angle=Math.atan2(this.ty-this.y,this.tx-this.x);this.speed=5;this.xadd=Math.cos(this.angle);this.yadd=Math.sin(this.angle);this.coord=[];for(var i=0;i<3;i++){this.coord.push({x:this.x,y:this.y});}
}
Firework.prototype={paint:function(){ctx.save();ctx.beginPath();ctx.moveTo(this.coord[this.coord.length-1].x,this.coord[this.coord.length-1].y);ctx.lineTo(this.x,this.y);ctx.strokeStyle='hsl('+hue+',100%,'+this.brightness+'%)';ctx.lineWidth=1.5;ctx.stroke();ctx.beginPath();ctx.arc(this.tx,this.ty,this.radius,0,2*Math.PI);ctx.stroke();ctx.closePath();ctx.restore();},update:function(index){var dx=this.tx-this.x,dy=this.ty-this.y;if(Math.abs(dx)<20 && Math.abs(dy)<20){fireworks.splice(index,1);createParticles(this.x,this.y);}else{this.x+=this.speed*this.xadd;this.y+=this.speed*this.yadd;this.speed*=accelerate;this.coord.pop();this.coord.unshift({x:this.x,y:this.y});if(this.radius>8){this.radius=1;}else{this.radius+=0.3;}}}
}
function createParticles(x,y){for(var i=0;i<20;i++){particles.push(new Particle(x,y));}
}
function Particle(x,y){this.x=x;this.y=y;this.hue=getRand(hue-50,hue+50);this.brightness=getRand(50,80);this.alpha=1;this.decay=getRand(0.015,0.03);this.angle=getRand(-Math.PI,Math.PI);this.speed=getRand(5,10);this.friction=0.95;this.gravity=2;this.xadd=Math.cos(this.angle);this.yadd=Math.sin(this.angle);this.coord=[];for(var i=0;i<5;i++){this.coord.push({x:this.x,y:this.y});}
}
Particle.prototype={paint:function(){ctx.beginPath();ctx.moveTo(this.coord[this.coord.length-1].x,this.coord[this.coord.length-1].y);ctx.lineTo(this.x,this.y);ctx.strokeStyle='hsla('+this.hue+',100%,'+this.brightness+'%,'+this.alpha+')';ctx.lineWidth=2;ctx.stroke();ctx.closePath();},update:function(index){this.alpha-=this.decay;if(Math.abs(this.alpha)<=this.decay){particles.splice(index,1);}else{this.x+=this.speed*this.xadd;this.y+=this.speed*this.yadd+this.gravity;this.speed*=this.friction;this.coord.pop();this.coord.unshift({x:this.x,y:this.y});}}
}function getRand(min,max){return Math.random()*(max-min)+min;
}</script></body>
</html>
總結
以上是生活随笔為你收集整理的烟花源代码的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。