G* Advent Calendar 2015 16日目です!(更新前に来てくださった方すいません…)
Groovy を altJS にしてしまった驚異の Grooscript を紹介したいと思います。Groovy をかくとソースコードが JavaScript に変換され、ブラウザや node.js 上で実行できてしまいます。
論よりrunということで、Try online がありますので試してみると良いと思います。
Try groovy to javascript conversion with grooscript
ここでは、ブラウザを Grooscript の実行環境とし、Groovy で Canvas を使ったアニメーションのプログラミングをしてみます。
Grooscript を始めるには Grooscript の Gradle plugin を使うと簡単です。初期コードの作成からファイルウォッチからの変換まで可能です。
build.gradle
plugins { id "org.grooscript.conversion" version "1.2.2" }
これで、
gradle initStaticWeb
とすれば、初期コードを生成してくれます。
この状態で次のようにすれば、src/main/groovy 配下の *.groovy ファイルの更新を監視して、src/main/webapp/js/app の下に変換した *.js を入れてくれます。
gradle --daemon convertThread
監視を止める場合は gradle のデーモンを停止させればOKです。(Windows, Linux, OS X とも動作するはずです)
gradle --stop
あとは Groovy をかけば完成です。 🙂
ここでは Canvas アニメーションを実装するために、src/main/webapp/index.html を次のようにしました。
<html> <head> <title>groovy on browser!</title> <link rel="stylesheet" href="css/style.css" /> <script type="text/javascript" src="js/lib/grooscript.min.js"></script> <script type="text/javascript" src="js/app/Presenter.js"></script> <meta name="viewport" content="width=device-width" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <canvas></canvas> </body>
src/main/groovy/Presenter.groovy で Canvas に対するアニメーション処理を Groovy でかきました。
ブラウザの window や document などのオブジェクトはそのまま記述できます。
import org.grooscript.asts.GsNative class Animation { static ANIMATION_FPS = 60; def canvas def context def width def height def actor def line Animation() { window.addEventListener('load', init, false) window.addEventListener('resize', init, false) window.addEventListener('orientationchange', init, false) window.setInterval(update, 1000 / ANIMATION_FPS, false) render() } def init() { actor = [] canvas = document.getElementsByTagName('canvas')[0] context = canvas.getContext('2d') width = canvas.clientWidth height = canvas.clientHeight canvas.setAttribute("width" ,width); canvas.setAttribute("height" ,height); for(def degree = 0 ; degree <= 360; degree += 360/86) { this.actor << new Ham("images/ham.png" , this.width , this.height , degree ) } } def update() { actor.each { it.update() } } def render() { window.requestAnimationFrame(render) if(!context) return context.fillStyle = "#000" context.fillRect(0, 0, width, height) actor.each { it.draw(context) } } } class Ham extends Actor { def swidth def sheight def degree def sx def sy def sv Ham(def url, def w, def h, def d) { super(url) swidth = w sheight = h sx = swidth / 2 sy = sheight / 2 sv = 1 degree = d width = 48 height = 48 } @GsNative def update() {/* var radian = Math.PI / 180 * this.degree this.x = Math.cos(radian) * (this.sx / 2 - 24) + this.swidth / 2 - 24 this.y = Math.sin(radian) * (this.sy / 2 - 24) + this.sheight / 2 - 24 this.degree += 0.9 if(this.degree > 360) { this.degree = 0 } this.sx += this.sv * 8 this.sy += this.sv * 8 if(this.sx >= this.swidth || this.sy >= this.sheight || this.sx <= (this.swidth * -1) + 48 + 24 || this.sy <= (this.sheight * -1) + 48 + 24 ) { this.sv = this.sv * -1 } this.width = 48 + (this.sx / 48) this.height = 48 + (this.sy / 48) */} } abstract class Actor { def image def x = 0 def y = 0 def width def height Actor(def url) { image = Resource.getInstance().getImage(url) } abstract update() @GsNative def draw(context) {/* if(!this.image['loaded']) return context.drawImage(this.image['image'], this.x, this.y, this.width, this.height) */} } class Resource { def static resource = new Resource() def images = [:] private Resource() { } def static getInstance() { return resource } def getImage(url) { if(!images.containsKey(url)) { images[url] = [:] def image = document.createElement('img') image.src = url image.addEventListener('load', { images[url]['image'] = image images[url]['loaded'] = true images[url]['width'] = image.naturalWidth images[url]['height'] = image.naturalHeight }, false) } return images[url] } } new Animation()
本当に Groovy です。 😀
一部 @GsNative というアノテーションがついたコメント実装されているメソッドは JavaScript のネイティブコードです。 速度を稼ぎたい部分は、このように(Groovy で変換された周りのコードを考えつつ) JS をそのままかくこともできます。
以下をクリックすると、実際に動いている様子が見ることができます。
変換された JavaScript のコードを見ると面白いと思います。
Grooscript はここ1年で node.js、require.js や React.js の対応が進むなど、開発を見ているのも楽しいです。
ブラウザとのつなぎも簡単ですので、Groovy な方はぜひ試してみてください 🙂
Keep on Groovy-ing!