Movatterモバイル変換


[0]ホーム

URL:


おんがえしの blog

作ったプログラムと調べた技術情報

Ruby で Processing がブラウザ上からできる p5.rb を作りました

ruby.wasm + p5.js の組み合わせです。ほとんどのAPI は移植したので大体同じことができると思います。

https://p5rb.ongaeshi.me/

使い方

p5.rb を HTML に読みこめばすぐに使えます。

<html><head><scriptsrc="https://cdn.jsdelivr.net/npm/ruby-3_2-wasm-wasi@next/dist/browser.script.iife.js"></script><scriptsrc="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script><scripttype="text/ruby"src="p5.rb"></script><scripttype="text/ruby">def setup  createCanvas(720,400)enddef draw  background(127)  noStroke()0.step(height,20)do |i|    fill(129,206,15)    rect(0, i, width,10)    fill(255)    rect(i,0,10, height)  endendP5::init()</script></head><body><main></main></body></html>

オンラインエディタ

https://p5rb.ongaeshi.me/editor からオンラインエディタが使えます。

作ったものはURLで共有できます。モバイルからも使えるのでまずはこちらを触ってみるのがおすすめです。

できたものは#p5rb タグを付けて共有していただけるとよろこびます。

実装メモ

ruby.wasm のJS::Object 経由で p5.js のメソッドやプロパティをブリッジしています。Ruby の method_missing を使うことで 100 行程度で p5.js の全ての関数やプロパティを呼び出しています。method_missiong すごい。

p5.rb#L217-L332

# JS::Object can call property via function styleclassJS::Objectdefmethod_missing(sym, *args, &block)    ret =self[sym]case ret.typeofwhen"undefined"      str = sym.to_sif str[-1] =="="self[str.chop.to_sym] = args.firstreturn args.firstendsuperwhen"function"self.call(sym, *args, &block).to_relse      ret.to_rendenddefrespond_to_missing?(sym, include_private)returntrueifsuperself[sym].typeof !="undefined"enddefto_rcaseself.typeofwhen"number"self.to_fwhen"string"self.to_selseselfendendend# Call p5.js global functions$p5 =nildefmethod_missing(sym, *args, &block)returnsuperunless$p5.respond_to?(:[])  ret =$p5[sym]case ret.typeofwhen"undefined"# str = sym.to_s# if str[-1] == "="#   $p5[str.chop.to_sym] = args.first#   return args.first# endsuperwhen"function"$p5.call(sym, *args, &block).to_relse    ret.to_rendend# Add new p5() to window.constructors.p5()JS.eval("window.constructors = { p5: (...args) => new p5(...args) };")moduleP5Vector =JS.global[:p5][:Vector]module_functiondefinit(query ="main", obj =self)unless query.is_a?(String)      query, obj ="main", queryend$p5&.remove()$p5 =nil    sketch = ->(p5) {$p5 = p5      init_method(obj,:preload)      init_method(obj,:setup)      init_method(obj,:draw)      init_event_method(obj,:mouseMoved)      init_event_method(obj,:mouseDragged)      init_event_method(obj,:mousePressed)      init_event_method(obj,:mouseReleased)      init_event_method(obj,:mouseClicked)      init_event_method(obj,:doubleClicked)      init_event_method(obj,:mouseWheel)      init_event_method(obj,:keyPressed)      init_event_method(obj,:keyReleased)      init_event_method(obj,:keyTyped)    }        container =JS.global.document.querySelector(query)    container.innerHTML =""JS.global.window.constructors.p5(sketch, container)enddefinit_method(obj, sym)if obj.respond_to?(sym,true)      m = obj.method(sym)$p5[sym] = ->() { m.call() }endenddefinit_event_method(obj, sym)if obj.respond_to?(sym,true)      m = obj.method(sym)if m.parameters.count >=1$p5[sym] = ->(e) { m.call(e) }else$p5[sym] = ->(e) { m.call() }endendendend

おわりに

作ったものがあったら#p5rb タグを付けて放流してもらえたら嬉しいです。

全ての戻り値に to_r するのはやりすぎかもしれないけど、プロパティをRuby の括弧無しメソッド呼び出しで呼べるのは本家でできてもいいのかもと思っています(後で PR 出してみよう)。

ABOUT
id:tuto0621

iOSのRubyプログラム環境PictRuby、電子書籍検索エンジンHonyomi、FirefoxプラグインFireLinkなどを作っています。

検索

引用をストックしました

引用するにはまずログインしてください

引用をストックできませんでした。再度お試しください

限定公開記事のため引用できません。

読者です読者をやめる読者になる読者になる

[8]ページ先頭

©2009-2025 Movatter.jp