光线爆炸特效
<!DOCTYPE html> <html > <head> <meta charset="UTF-8"> <title>光线爆炸特效</title> <script src="jquery.js"></script> <style> html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0} body { background: #000; overflow: hidden; } canvas { display: block; } </style> </head> <body> <canvas id="c"></canvas> <script> /* click to clear and change hue don't look at or judge this code I just kept tweaking values and adding random things in a messy way it's full of magic numbers */ var c, ctx, w, h, cx, cy, branches, startHue, tick; function rand( min, max ) { return Math.random() * ( max - min ) + min; } function randInt( min, max ) { return Math.floor( min + Math.random() * ( max - min + 1 ) ); }; function Branch( hue, x, y, angle, vel ) { var move = 15; this.x = x + rand( -move, move ); this.y = y + rand( -move, move ); this.points = []; this.angle = angle != undefined ? angle : rand( 0, Math.PI * 1 ); this.vel = vel != undefined ? vel : rand( -4, 4 ); this.spread = 0; this.tick = 0; this.hue = hue != undefined ? hue : 200; this.life = 1; this.decay = 0.0015; this.dead = false; this.points.push({ x: this.x, y: this.y }); } Branch.prototype.step = function( i ) { this.life -= this.decay; if( this.life <= 0 ) { this.dead = true; } if( !this.dead ) { var lastPoint = this.points[ this.points.length - 1 ]; this.points.push({ x: lastPoint.x + Math.cos( this.angle ) * this.vel, y: lastPoint.y + Math.sin( this.angle ) * this.vel }); this.angle += rand( -this.spread, this.spread ); this.vel *= 0.99; this.spread = this.vel * 0.04; this.tick++; this.hue += 0.3; } else { branches.splice( i, 1 ); } }; Branch.prototype.draw = function() { if( !this.points.length || this.dead ) { return false; } var length = this.points.length, i = length - 1, point = this.points[ i ], lastPoint = this.points[ i - randInt( 5, 100 ) ]; //jitter = 8; if( lastPoint ) { var jitter = 2 + this.life * 6; ctx.beginPath(); ctx.moveTo( lastPoint.x, lastPoint.y ); ctx.lineTo( point.x + rand( -jitter, jitter ), point.y + rand( -jitter, jitter ) ); ctx.lineWidth = 1; var alpha = this.life * 0.075; ctx.strokeStyle = 'hsla(' + ( this.hue + rand( -10, 10 ) ) + ', 70%, 40%, ' + alpha + ')'; ctx.stroke(); } } function init() { c = document.getElementById( 'c' ); ctx = c.getContext( '2d' ); startHue = 220; branches = []; reset(); loop(); } function reset() { w = window.innerWidth; h = window.innerHeight; cx = w / 2; cy = h / 2; branches.length = 0; c.width = w; c.height = h; tick = 0; for( var i = 0; i < 500; i++ ) { branches.push( new Branch( startHue, cx, cy) ); } } function step() { var i = branches.length; while( i-- ) { branches[ i ].step( i ) } tick++; } function draw() { var i = branches.length; if( tick < 450 ) { ctx.save(); ctx.globalCompositeOperation = 'lighter'; ctx.globalAlpha = 0.002; ctx.translate( cx, cy ); var scale = 1 + tick * 0.00025 ; ctx.scale( scale, scale ); ctx.translate( -cx, -cy ); ctx.drawImage( c, rand( -150, 150 ), rand( -150, 150 ) ); ctx.restore(); } ctx.globalCompositeOperation = 'lighter'; while( i-- ) { branches[ i ].draw() } } function loop() { requestAnimationFrame( loop ); step(); draw(); step(); draw(); } window.addEventListener( 'resize', reset ); window.addEventListener( 'click', function() { startHue += 60; reset(); }); init(); </script> </body> </html>