Skip to content

Instantly share code, notes, and snippets.

Created July 19, 2013 02:42
Show Gist options
  • Save anonymous/6034713 to your computer and use it in GitHub Desktop.
Save anonymous/6034713 to your computer and use it in GitHub Desktop.
A CodePen by Linmiao Xu. Hadoken - A canvas animation inspired by Street Fighter.
<canvas id="canvas"></canvas>
FPS = 30
PI_2 = 2*Math.PI
SQRT_3 = Math.sqrt(3)
canvas = document.getElementById("canvas")
ctx = canvas.getContext("2d")
windowResizeHandler = ->
canvas.width = window.innerWidth
canvas.height = window.innerHeight
window.addEventListener "resize", windowResizeHandler, false
window.onload = ->
setTimeout windowResizeHandler, 0
window.requestAnimationFrame = do ->
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
(cb) -> window.setTimeout(cb, 1000/FPS)
range = (a,b) -> (b-a)*Math.random()+a
randInt = (a,b) -> Math.floor(range(a,b+1))
class Trail
constructor: (x,y,r) ->
@opacity = 1
@xOrig = x+r-5
@yOrig = y
@rOrig = r
rs = r*0.4
@y = range(y-rs,y+rs)
yd = Math.abs(@y-y)/rs
@x = @xOrig-(rs*yd/SQRT_3)+range(-1,8)
@ystep = range(-1,1)
@xstep = range(-r/4*(1-yd),0)
@r = range(1,8)
step: ->
if @opacity < 0.6
@opacity -= 0.06
else
@opacity -= 0.09
return false if @opacity <= 0
@x += @xstep
@y += @ystep
true
draw: ->
r = @r*@opacity*3
style = ctx.createRadialGradient(@x,@y,0,@x,@y,r)
if @opacity < 0.6
style.addColorStop 0, "rgba(0,90,255,#{@opacity})"
style.addColorStop 1, "rgba(0,90,255,0)"
else
style.addColorStop 0, "rgba(0,255,255,0.5)"
style.addColorStop 1, "rgba(0,120,255,0)"
ctx.beginPath()
ctx.arc(@x,@y,@r*2,0,PI_2,true)
ctx.fillStyle = style
ctx.fill()
class Hadouken
constructor: ->
@x = -50
@xstep = 5
@r = 35
@r2 = 2*@r
@priority = 1
destructor: ->
w.addEntity Hadouken
step: ->
@x += @xstep
@y = canvas.height/2
return @x < canvas.width and @y < canvas.height
draw: ->
ctx.beginPath()
ctx.arc(@x+3,@y,@r2,0,PI_2,true)
ctx.fillStyle = do =>
g = ctx.createRadialGradient(@x+@r2,@y,0,@x+3,@y,@r2)
g.addColorStop 0, "rgba(0,255,255,0.6)"
g.addColorStop 1, "rgba(0,0,255,0)"
g
ctx.fill()
ctx.beginPath()
ctx.arc(@x+@r-3+range(-3,3),@y+range(-4,4),@r,0,PI_2,true)
ctx.fillStyle = do =>
g = ctx.createRadialGradient(@x+@r2,@y,0,@x+@r,@y,@r)
g.addColorStop 0, "rgba(255,255,255,0.8)"
g.addColorStop 1, "rgba(255,255,255,0)"
g
ctx.fill()
for i in [1..15]
w.addEntity Trail, @x, @y, @r2
class World
constructor: ->
@entities = {}
@i = 0
@loop()
addEntity: (klass, args...) ->
@entities[@i] = new klass(args...)
@i++
loop: ->
requestAnimationFrame => @loop()
ctx.clearRect(0,0,canvas.width,canvas.height)
ids = []
for k,entity of @entities
if entity.priority == 1
ids.push k
continue
unless entity.step()
delete @entities[k]
continue
entity.draw()
for k in ids
entity = @entities[k]
unless entity.step()
entity.destructor()
delete @entities[k]
continue
entity.draw()
@w = new World
@w.addEntity Hadouken
@import "compass";
body {
background: #000;
margin: 0;
padding: 0;
overflow: hidden;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment