ruby.wasm + p5.js の組み合わせです。ほとんどのAPI は移植したので大体同じことができると思います。
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 すごい。
# 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 出してみよう)。
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。