class IsoBoxer
constructor: (id) ->
@rot = random() * TWO_PI
@dr = @rot;
@rx = random() * 0.1 + 0.01
@ry = @rx / 2
@x = random()
@y = random()
@dx = @x
@dy = @y
@height = random() * 0.1 + 0.1
@verts = []
@damp = 40
@chance = 0.2
@randStep = 0.15
@halfRandStep = @randStep / 2
@rotStep = @randStep * 10
@halfRotStep = @rotStep / 2
@col = ['#de9268', '#7ba8d4', '#3e8ad6', '#248a81']
@col = id == 0 && @col[1] || @col[floor random() * @col.length]
run: (@id) =>
alpha = 1;
repeat boxNum, (id) =>
if @id != id
repeat @verts.length, (i) =>
if pointInPoly @verts[i][0], @verts[i][1], boxers[id].verts
@dx = random() * 2 - 1
@dy = random() * 2 - 1
alpha = random()
false
if random() < @chance
@dx += random() * @randStep - @halfRandStep
@dr += random() * @rotStep - @halfRotStep
if random() < @chance
@dy += random() * @randStep - @halfRandStep
@dr += random() * @rotStep - @halfRotStep
if @dx > 1 || @dx < 0 then @dx = random()
if @dy > 1 || @dy < 0 then @dy = random()
@rot += (@dr - @rot) / @damp
@x += (@dx - @x) / @damp
@y += (@dy - @y) / @damp
para @x, @y,
range: [ 0, TWO_PI ]
step: HALF_PI
f: (t) =>
x: @rx * cos t + @rot
y: @ry * sin t + @rot
render: (verts, x, y) =>
yOff = verts.map (val) =>
coord = val.slice()
coord[1] += @height
coord
shadow color: '#fff', alpha: 0.04, blur: 1, x: 0, y: @height
fill @col, alpha - 0.7
stroke '#fff', 0.02
repeat 4, (i) =>
i1 = i + 1
poly x, y, [verts[i], yOff[i], yOff[i1], verts[i1]]
noStroke()
fill '#fff', alpha
@verts = poly x, y, verts
noShadow()
boxNum = 9
boxers = []
repeat boxNum, (id) -> boxers.push new IsoBoxer(id)
Z animate, ->
grd = context.createLinearGradient 0, 0, width, height
grd.addColorStop 0, '#1f2a36'
grd.addColorStop 1, '#456b91'
background grd
noStroke()
fill '#59697a'
boxers.sort (a, b) -> a.y > b.y
.forEach (boxer, i) ->
boxer.run(i)
View Compiled