I fell in love with the idea of writing Ruby code in my browser long ago. I promptly wrote that dream off as impossible and learned coffeescript. But while coffeescript makes javascript much nicer to work with, it still doesn’t flow as nicely as good ‘ol Ruby. Opal.rb attempts to solve this problem. Opal.rb is a Ruby-to-javascript, source-to-source compiler. Opal supports most of Ruby already, including classes, modules, blocks and method_missing.
Opal has been under development for a couple of years now by Adam Beynon. There is an active community of people working to improve Opal and build extension libraries like opal-jquery, opal-sprockets, and vienna. I’ve started my own little Opal project while writing this blog post. I ported a basic Pixi.js example to Ruby via Opal.
I plan on cleaning up and completing the Pixi.js wrapper, but that’s a post for another day. Give Opal.rb a try online!
Here’s the example code:
include PIXI
stage = Stage.new 0x66FF99
renderer = WebGLRenderer.new 400, 300
Native(`window.document.body`).appendChild renderer.view
texture = Texture.from_image "bunny.png"
bunny = Sprite.new texture
bunny.anchor = Point.new(0.5, 0.5)
bunny.position = Point.new(300, 150)
stage.add_child(bunny)
animate = proc do
`requestAnimFrame(animate)`
bunny.rotation += 0.1
renderer.render stage
end
`requestAnimFrame(animate)`
and here’s the supporting wrapper code:
require 'opal'
# require 'opal-jquery'
module PIXI
class Stage
%x{
#{self}._proto = window.PIXI.Stage.prototype, def = #{self}._proto;
window.PIXI.Stage.prototype._klass = #{self};
}
def self.new(color)
`new window.PIXI.Stage(color)`
end
def add_child(child)
`#{self}.addChild(child)`
end
end
class WebGLRenderer
%x{
#{self}._proto = window.PIXI.WebGLRenderer.prototype, def = #{self}._proto;
window.PIXI.WebGLRenderer.prototype._klass = #{self};
}
def self.new(width, height)
`new window.PIXI.WebGLRenderer(width, height)`
end
def render(stage)
`self.render(stage)`
end
def view
`self.view`
end
end
class Texture
%x{
#{self}._proto = window.PIXI.Texture.prototype, def = #{self}._proto;
window.PIXI.Texture.prototype._klass = #{self};
}
def self.from_image(name)
`window.PIXI.Texture.fromImage(name)`
end
end
class Sprite
%x{
#{self}._proto = window.PIXI.Sprite.prototype, def = #{self}._proto;
window.PIXI.Sprite.prototype._klass = #{self};
}
def self.new(texture)
`new window.PIXI.Sprite(texture)`
end
def anchor
Point.new `#{self}.anchor.x`,`#{self}.anchor.y`
end
def rotation
`self.rotation`
end
def rotation=(r)
`self.rotation = r`
end
def anchor=(a)
`self.anchor = a`
end
def position=(p)
`self.position = p`
end
end
class Point
%x{
#{self}._proto = window.PIXI.Point.prototype, def = #{self}._proto;
window.PIXI.Point.prototype._klass = #{self};
}
def self.new(x,y)
`new window.PIXI.Point(x,y)`
end
end
end
And here’s what it draws:
Your bunny looks dangerously similar to pedobear.