Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call native javascript methods from opal?

Tags:

ruby

opalrb

I'm coding a simple game based on html canvas. I'm now porting from coffeescript to opal.

I'd like to wrap the CanvasRenderingContext2D object in an efficient way.

My current solution is a wrapper, but I'd really like to make that toll free bridged.

app.rb:

class Game
    def initialize
        @canvas = Element.find('#canvas').get(0)
        js_ctx  = `this.canvas.getContext('2d')`        # this is a javascript object
        @ctx    = CanvasRenderingContext2D.new(js_ctx)  # create the proxy
        @ctx.fillStyle='red'
        @ctx.fillRect(10,10,50,50)
    end
end

# the opal proxy class (named $CanvasRenderingContext2D in javascript space)
class CanvasRenderingContext2D
    # I currently model the proxy as a has_a while I'd prefer it to be is_a
    attr_reader :js    # the native javascript object

    def initialize(js)
        @js = js
    end

    # getter
    def fillStyle
        `this.js.fillStyle`
    end

    # setter
    def fillStyle= value
        `this.js.fillStyle= value`
    end

    # method invocation
    def fillRect x,y,width,height
        `this.js.fillRect(x,y,width,height)`
    end
end

Any hints are welcome.

like image 734
edx Avatar asked Feb 25 '14 06:02

edx


1 Answers

Last time I was working with opal I followed the same path as you, created wrappers and even called directly javascript direct from my code. Recently I've come across with blog describing the use of the Native class, so your code would look like this:

require 'native'
class Game
  def initialize
    @canvas = Element.find('#canvas').get(0)
    @ctx  = Native(`this.canvas.getContext('2d')`)
    @ctx.fillStyle='red'
    @ctx.fillRect(10,10,50,50)
  end
end

Haven't really tested this method yet

[1]http://dev.mikamai.com/post/79398725537/using-native-javascript-objects-from-opal

like image 130
gabrielrios Avatar answered Sep 22 '22 17:09

gabrielrios