2008年8月22日金曜日

GWTでCanvasタグを使ってみる (drawImageメソッドの補完)

GWTを使ってみている.
Canvasタグ周りはgwt-canvasというプロジェクトでサポートしていた.
こいつを使う(gwt-canvas-x.x.x.jarにパスを通す)とこう書ける.

Test.gwt.xml
<module> 
<inherits name="com.google.gwt.user.User"/>
<inherits name='gwt.canvas.gwt-canvas'/>
<entry-point class='sample.client.Test'/>
</module>


sample.client.Test.java
package sample.client;

import gwt.canvas.client.Canvas;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;

public class Test implements EntryPoint {

public void onModuleLoad() {
Canvas canvas = new Canvas(300, 300);

canvas.beginPath();
canvas.moveTo(0, 0);
canvas.lineTo(300, 300);
canvas.stroke()
;

RootPanel.get().add(canvas);
}

}


こんな感じ.


Contextを取得しないらしい'2d'限定.まぁ今のところ2dしか仕様にもないらしいので問題にならないのだろうけど….
2dコンテキストのメソッドはこことかにある.(感謝.)

さて, drawImageが使いたかったのだがこれが未実装とのことでちょっと困った.
だがこれをJSNIとJavaScriptObjectで対応することで回避できた.(JSNIとJavaScriptObject関連の解説はここにある.感謝)
つまりCanvasの位置,大きさや装飾はGWTで管理して描画はレガシーな方法で逃げるということである.どうせ直ぐに対応されていらなくなるtipsであるだろうけどw.

コードは以下.
sample.client.Test.java
package sample.client;

import gwt.canvas.client.Canvas;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.ui.RootPanel;

public class Test implements EntryPoint {

public void onModuleLoad() {
Canvas canvas = new Canvas(300, 300);
RootPanel.get().add(canvas);

JavaScriptObject context = getCtx();
JavaScriptObject image = createImage("http://www.google.com/images/logo.gif");
canvas.fillRect(0, 0, 300, 300);
drawImage(context, image, 5, 5);
}

protected native JavaScriptObject getCtx()
/*-{
var canvas= $doc.getElementsByTagName('canvas');
$wnd.ctx= canvas[0].getContext('2d');
return $wnd.ctx;
}-*/;

protected native JavaScriptObject createImage(String imageUrl)
/*-{
var image= new Image();
image.src= imageUrl;
return image;
}-*/;

protected native void drawImage(JavaScriptObject ctx,
JavaScriptObject image, int x, int y)
/*-{
ctx.drawImage(image, x, y);
}-*/;
}


JSNIのコメントの付け方はEclipseでフォーマットを走らせたときにズレていかないようにするための対応(のつもり).

こんな感じ.


欠点いろいろ(というか私の不勉強):
  • 上のコードの欠点はImageまでJSNIしなくてはいけない.GWTで作ってJSNIで取り出せるとうれしいんだけどImageの場合どっから取り出すと良いのだろう?docmentかなにかかな?
  • Canvasは作ってタグ名で検索して配列の最初のモノとベタに決め込んでいるところがダメ.GWTで要素に一意にするにはaddStyleNameが正攻法なのかな.

    まぁ参考にもならないだろうけど最近更新してないのでネットのノイズとして掲載.
  • 0 件のコメント: