Created
December 15, 2011 19:36
-
-
Save jackrugile/1482487 to your computer and use it in GitHub Desktop.
Canvas Particles
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 lang="en"> | |
<head> | |
<title>Canvas Particles v2</title> | |
<meta charset="utf-8" /> | |
<style> | |
html, body { | |
margin: 0; | |
padding: 0; | |
} | |
body { | |
background: #111; | |
color: #333; | |
font: 100%/20px helvetica, arial, sans-serif; | |
} | |
canvas { | |
background: #000; | |
border: 1px solid #222; | |
display: block; | |
margin: 0 auto; | |
} | |
#info { | |
margin: 60px auto 30px; | |
width: 400px; | |
} | |
h1 { | |
color: #fff; | |
font-size: 20px; | |
font-weight: normal; | |
letter-spacing: -1px; | |
margin: 0; | |
} | |
h2 { | |
border-bottom: 1px dotted #333; | |
color: #999; | |
font-size: 12px; | |
margin: 0; | |
padding: 0 0 10px | |
} | |
h2 a { | |
color: #f30; | |
text-decoration: none; | |
} | |
h2 a:hover { | |
color: #fff; | |
} | |
p { | |
color: #999; | |
font-size: 11px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="info"> | |
<h1><strong>Canvas</strong>Particles<strong>v2</strong></h1> | |
<h2>by <a href="http://jackrugile.com">Jack Rugile</a></h2> | |
<p>Move your mouse around to change the position and color of the particles. The color change is based on a color wheel, with the center being the middle of the canvas. Click to toggle the particle trail. Don't mind the messy and inefficient JavaScript.</p> | |
</div> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
<script> | |
$(function(){ | |
var $window = $(window); | |
var canvas = document.createElement('canvas'); | |
document.body.appendChild(canvas); | |
var cWidth = 400; | |
var cHeight = 400; | |
canvas.width = cWidth; | |
canvas.height = cHeight; | |
var $canvas = $('canvas'); | |
var ctx = canvas.getContext('2d'); | |
var p = []; | |
var pCount, | |
pSizeMin, | |
pSizeMax, | |
pXSpeedMin, | |
pXSpeedMax, | |
pYSpeedMin, | |
pYSpeedMax, | |
pAlphaMin, | |
pAlphaMax, | |
pHueMin, | |
pHueMax, | |
mx, | |
my, | |
trail, | |
angle; | |
function pSetOptions(){ | |
pCount = 300; | |
pSizeMin = 25; | |
pSizeMax = 350; | |
pXSpeedMin = -100; | |
pXSpeedMax = 100; | |
pYSpeedMin = -100; | |
pYSpeedMax = 100; | |
pAlphaMin = 10; | |
pAlphaMax = 100; | |
pHueMin = -40; | |
pHueMax = 40; | |
mx = 0; | |
my = 0; | |
trail = false; | |
angle = 0; | |
} | |
function createParticle(amount){ | |
while(amount--){ | |
var newSize = rand(pSizeMin, pSizeMax)/100; | |
var newX = cWidth/2; | |
var newY = cHeight/2; | |
var newXSpeed = rand(pXSpeedMin, pXSpeedMax)/100; | |
var newYSpeed = rand(pYSpeedMin, pYSpeedMax)/100; | |
var newXDir = (newXSpeed < 0) ? -1 : 1; | |
var newYDir = (newYSpeed < 0) ? -1 : 1; | |
var newAlpha = rand(pAlphaMin, pAlphaMax); | |
var newHue = rand(pHueMin, pHueMax); | |
p.push({ | |
size: newSize, | |
x: newX, | |
y: newY, | |
xSpeed: newXSpeed, | |
ySpeed: newYSpeed, | |
xDir: newXDir, | |
yDir: newYDir, | |
alpha: newAlpha, | |
hue: newHue | |
}); | |
} | |
} | |
var yAdd = 0; | |
var refill = 1; | |
function draw(){ | |
var i = p.length; | |
ctx.globalCompositeOperation = 'destination-out'; | |
if(trail){ | |
ctx.fillStyle = 'rgba(0,0,0,'+refill+')'; | |
ctx.fillRect(0,0,cWidth,cHeight); | |
if(yAdd < .1){ | |
yAdd += .001; | |
} | |
if(refill > .1){ | |
refill -= .01; | |
} | |
if(refill < .1){ | |
refill = .1; | |
} | |
} else { | |
ctx.fillStyle = 'rgba(0,0,0,'+refill+')'; | |
ctx.fillRect(0,0,cWidth,cHeight); | |
if(yAdd > 0){ | |
yAdd -= .01; | |
} | |
if(yAdd < 0){ | |
yAdd = 0; | |
} | |
if(refill < 1){ | |
refill += .01; | |
} | |
if(refill > 1){ | |
refill = 1; | |
} | |
} | |
while(i--){ | |
var cp = p[i]; | |
ctx.globalCompositeOperation = 'source-over'; | |
ctx.beginPath(); | |
ctx.arc(cp.x,cp.y,cp.size,0, Math.PI*2, true) | |
ctx.moveTo(cWidth/2, cHeight/2); | |
ctx.lineTo(cp.x, cp.y); | |
ctx.fillStyle = 'hsla('+(angle+cp.hue)+', 100%, 50%, '+cp.alpha/100+')'; | |
ctx.fill(); | |
ctx.strokeStyle = 'hsla('+(angle+cp.hue)+', 100%, 50%, '+cp.alpha/1000+')'; | |
ctx.stroke(); | |
cp.size -= .02 + yAdd/5; | |
cp.x += cp.xSpeed + (mx*cp.size)/100; | |
cp.y += cp.ySpeed + (my*cp.size)/100; | |
if(cp.y-(cp.size) > cHeight || cp.y < -cp.size || cp.x > cWidth+cp.size || cp.x < -cp.size || cp.size < 0){ | |
p.splice(i, 1); | |
} | |
} | |
} | |
$window.bind({ | |
mousemove: function(e){ | |
mx = Math.floor(e.pageX - $canvas.offset().left - cWidth/2); | |
my = Math.floor(e.pageY - $canvas.offset().top - cHeight/2); | |
var x1 = 0; | |
var y1 = 0; | |
var x2 = mx; | |
var y2 = my; | |
var rise = y1-y2; | |
var run = x1-x2; | |
var slope = -(rise/run); | |
var radian = Math.atan(slope); | |
angle = Math.floor(radian*(180/Math.PI)); | |
if(x2 < x1 && y2 < y1){angle += 180;} | |
if(x2 < x1 && y2 > y1){angle += 180;} | |
if(x2 > x1 && y2 > y1){angle += 360;} | |
if(y2 < y1 && slope =='-Infinity'){angle = 90;} | |
if(y2 > y1 && slope =='Infinity'){angle = 270;} | |
if(x2 < x1 && slope =='0'){angle = 180;} | |
if(isNaN(angle)){angle = 0;} | |
}, | |
mousedown: function(){ | |
trail = (trail) ? false : true; | |
} | |
}); | |
function animationLoop(){ | |
draw(); | |
if(p.length < pCount){ | |
createParticle(10); | |
} | |
requestAnimFrame(animationLoop, canvas); | |
} | |
window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)}}(); | |
var rand = function(rMi, rMa){return ~~((Math.random()*(rMa-rMi+1))+rMi);} | |
pSetOptions(); | |
animationLoop(); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment