Skip to content

Instantly share code, notes, and snippets.

@zerowidth
Created March 24, 2012 22:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zerowidth/2188453 to your computer and use it in GitHub Desktop.
Save zerowidth/2188453 to your computer and use it in GitHub Desktop.
jointhecolorwar rage face
# npm install socket.io-client canvas
io = require "socket.io-client"
util = require "util"
fs = require "fs"
Canvas = require "canvas"
EventEmitter = require("events").EventEmitter
class Pixels extends EventEmitter
constructor: ->
@ready = false
load: (filename) ->
canvas = new Canvas 100, 75
ctx = canvas.getContext '2d'
img = new Canvas.Image()
img.onload = =>
ctx.clearRect 0, 0, 100, 75
ctx.drawImage img, 0, 0
@imageData = ctx.getImageData(0, 0, 100, 75).data
util.puts "image loaded"
@ready = true
@emit 'ready'
img.src = fs.readFileSync "rage.png"
pixels: ->
list = []
for x in [0...100]
for y in [0...75]
[r, g, b] = @at(x, y)
list.push [x, y, r, g, b]
list
at: (x, y) =>
offset = (y * 100 + x) * 4
r = @imageData[offset]
g = @imageData[offset + 1]
b = @imageData[offset + 2]
[r, g, b]
class Painter extends EventEmitter
constructor: (@color) ->
@connect()
@ready = false
@toDraw = []
connect: ->
util.puts "#{@color} connecting..."
@socket = io.connect "http://jointhecolorwar.com", "force new connection": true
@socket.on 'init', (data) =>
if data.color is @color
util.puts "#{@color} connected: #{data.id}"
@id = data.id
@ready = true
@emit 'ready'
@runLoop()
else
util.puts "#{@color} got #{data.color}, retrying"
@socket.disconnect()
@connect()
draw: (x, y) ->
@toDraw.push [x, y]
jitter: (x, y) ->
@dot @calcJitter(x, 800), @calcJitter(y, 600)
calcJitter: (n, max) ->
n = n + 1 - Math.round(Math.random() * 2)
n = 0 if n < 0
n = max if n > max
n
dot: (x, y) ->
@socket.emit 'move', x: x, y: y, id: @id
runLoop: =>
if @toDraw.length
[x, y] = @toDraw.shift()
@toDraw.push [x, y]
@jitter x, y
setTimeout(@runLoop, 10)
class Client
constructor: (file) ->
@red = new Painter "red"
@green = new Painter "green"
@blue = new Painter "blue"
@pixels = new Pixels file
@red.on 'ready', @ready
@green.on 'ready', @ready
@blue.on 'ready', @ready
@pixels.on 'ready', @ready
@pixels.load file
ready: =>
@draw() if @red.ready and @green.ready and @blue.ready and @pixels.ready
draw: ->
for [x, y, r, g, b] in @pixels.pixels()
x = x * 8 + 4
y = y * 8 + 4
@red.draw x, y if r is 255
@green.draw x, y if g is 255
@blue.draw x, y if b is 255
client = new Client 'rage.png'
# repl = require "repl"
# r = repl.start()
# r.context.p = p
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment