Skip to content

Instantly share code, notes, and snippets.

@xav76
Created October 24, 2012 17:10
Show Gist options
  • Save xav76/3947381 to your computer and use it in GitHub Desktop.
Save xav76/3947381 to your computer and use it in GitHub Desktop.
A CodePen by Linmiao Xu. Fireball - A simple fireball animation in canvas.
<canvas id="canvas"></canvas>
FPS = 20
PI_2 = 2*Math.PI
canvas = document.getElementById("canvas")
context = canvas.getContext("2d")
windowResizeHandler = ->
canvas.width = window.innerWidth
canvas.height = window.innerHeight
window.addEventListener 'resize', windowResizeHandler, false
windowResizeHandler()
range = (a,b) -> (b-a)*Math.random()+a
drawCircle = (x,y,r,style) ->
context.beginPath()
context.arc(x,y,r,0,PI_2,false)
context.fillStyle = style
context.fill()
class Smoke
constructor: (x,y) ->
@opacity = 0.8
@x = x
@y = y
@r = 0.6
step: ->
@y -= range(0,3)
@x += range(-2,2)
@opacity -= 0.01
if @opacity <= 0
@destroyed = true
draw: ->
return if @opacity <= 0
drawCircle(@x,@y,@r,"rgba(30,30,30,#{@opacity})")
class Trail
constructor: (x,y) ->
@opacity = 1
@x = x
@y = y
@r = 5
step: ->
@y -= range(0,8)
@x -= range(-3,3)
@opacity -= 0.05
if @opacity <= 0
@destroyed = true
w.addEntity Smoke, @x, @y-3*@r
draw: ->
return if @opacity <= 0
color = "rgba(255,#{Math.floor(240*@opacity)},0,#{@opacity})"
color2 = "rgba(255,#{Math.floor(240*@opacity)},0,0)"
rg = @r*1.5+range(0,2)
g = context.createRadialGradient(@x,@y,0,@x,@y,rg)
g.addColorStop 0, color
g.addColorStop 1, color2
drawCircle(@x,@y,rg,g)
drawCircle(@x,@y,@r*@opacity,color)
class Flame
constructor: ->
@x = canvas.width/2
@y = canvas.height/2+40
@r = 5
@rg = 12
@g = context.createRadialGradient(@x,@y,0,@x,@y,@r*1.5)
@g.addColorStop 0, "rgba(255,255,255,1)"
@g.addColorStop 1, "rgba(255,220,0,0)"
step: -> false
draw: ->
@x = canvas.width/2
@y = canvas.height/2+40
w.addEntity(Trail,@x,@y-@r/3) for i in [1..10]
g = context.createRadialGradient(@x,@y,0,@x,@y,@rg)
g.addColorStop 0, "rgba(255,180,0,#{range(0.2,0.9)})"
g.addColorStop 1, "rgba(255,180,0,0)"
drawCircle(@x,@y,@rg,g)
drawCircle(@x+range(-1.5,1.5),@y+range(-1.5,1.5),@r,@g)
class World
constructor: ->
@entities = {}
@i = 0
@frame = 0
setInterval =>
@loop()
, 1000/FPS
addEntity: (klass, args...) ->
@entities[@i] = new klass(args...)
@i -= 1
loop: ->
@frame++
context.clearRect(0,0,canvas.width,canvas.height)
for k,entity of @entities
if entity.destroyed == true
delete @entities[k]
continue
entity.step()
entity.draw()
w = new World
w.addEntity Flame
body {
background: #070707;
margin: 0;
padding: 0;
overflow: hidden;
width: 100%;
height: 100%;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment