Skip to content

Instantly share code, notes, and snippets.

@Toady00
Created November 19, 2012 05:50
Show Gist options
  • Save Toady00/4109150 to your computer and use it in GitHub Desktop.
Save Toady00/4109150 to your computer and use it in GitHub Desktop.
A CodePen by Brandon Dennis. Particle System - Attempt at canvas based particle system. Currently trying to get particle system to stream instead of generate all particles simultaneously.
<div class='particles'></div>
class ParticleSystem
constructor: (@ctx, @num=1) ->
@particles = []
@live = 0
@x = canvas.width/2
@y = canvas.height/2
# TODO: figure out how to set x and y
# Keep getting errors
# setSystemLocation: (@x, @y, @lVariation) ->
setParticleVelocity: (@xv, @yv, @vVariation=1) ->
setParticleSize: (@size, @sVariation=1) ->
setLifeTime: (@lifeTime, @ltVariation=1) ->
@rate = Math.floor @num/@lifeTime
# TODO: Refactor to specify whether or not to negate.
# Ex. life should not be negative.
variation: (value, variation=1) ->
negate = false
negate = true unless Math.round(Math.random()) == 0
variation = 0 - variation if negate
value + (variation * Math.random())
generateParticles: (num=@rate)->
for n in [1..num]
x0 = @variation(@x, 25)
y0 = @variation(@y, 15)
xv0 = @variation(@xv, @vVariation)
yv0 = @variation(@yv, @vVariation)
size = @variation(Math.abs(@size))
life = @variation(@lifeTime, @ltVariation)
@live++
p = new Particle x0, y0, xv0, yv0, size
p.life = life
# TODO: remove hard coded floor
p.setFloor(canvas.height/2 + 50)
@particles.push p
reapParticles: ->
@particles.filter (p) ->
@particles = p.live() == true
@live = @particles.length
# TODO: Figure out why all particles are being generated
# at the same time
draw: ->
@reapParticles()
@generateParticles() if @live < @num
ctx.clearRect 0, 0, canvas.width, canvas.height
for p in @particles
p.draw(@ctx)
class Particle
constructor: (@x0, @y0, @xv0, @yv0, @size=5, @gravity=9.8) ->
# Age of Particle
@lifeTime = 0
# Max age of particle
@life = 0
# Generic timer for reseting acceleration, velocity
# without screwing up lifeTime
@timer = 0
@color = 'rgba(224, 178, 27, 0.75)'
@x = @x0
@y = @y0
@xv = @xv0
@yv = @yv0
setFloor: (y) ->
@floor = y - @size
live: ->
return true if @lifeTime < @life
return false
updateCoords: ->
# TODO: Add some type of friction so particles
# lose energy when they bounce
@timer++
@lifeTime++
@yv = @yv0 + (@gravity * @timer/10)
@x = @x0 + (@xv * @lifeTime/10)
@y = @y0 + (@yv * @timer/10)
if @y > @floor
@y0 = @y
@yv0 = -@yv - (@gravity * @timer/10)
@timer = 0
render: (ctx) ->
ctx.save()
ctx.fillStyle = @color
ctx.beginPath()
ctx.arc(@x,@y,@size,0,Math.PI*2,true)
ctx.fill()
ctx.restore()
draw: (ctx) ->
@updateCoords()
@render(ctx)
width = window.innerWidth
height = window.innerHeight
newCanvas = (id) ->
$('.particles').append "<canvas id='#{id}' width='#{width}' height='#{height}'>Sorry you can't see this. It's awesome!</canvas>"
newCanvas('canvas')
ctx = $('#canvas')[0].getContext('2d')
newCanvas('base')
base = $('#base')[0].getContext('2d')
base.moveTo(0, height/2 + 50)
base.lineTo(width, height/2 + 50)
base.stroke()
ps = new ParticleSystem(ctx, 100)
ps.setParticleVelocity(0, -50, 30)
ps.setParticleSize(4, 100)
ps.setLifeTime(1, 1)
# ps.draw()
dotime = ->
iv = setInterval ->
ps.draw()
, 60
# return setTimeout ->
# clearInterval iv
# , 30000
dotime()
#p = new Particle 50, 50, 20, -30
#p.color = '#ffffff'
#p.render ctx
#dotime = ->
# iv = setInterval ->
# p.draw(ctx)
# , 1
# return setTimeout ->
# clearInterval iv
# , 3000
#dotime()
@import "compass";
.particles {
position: relative;
width: 100%;
height: 100%;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
#canvas {
@include background(
radial-gradient(
center center,
ellipse cover,
rgba(150, 150, 150, 1) 0%,
rgba(89, 89, 89, 1) 100%))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment