js_of_ocamlでHTMLにCanvasを追加して操作してみる
前回、前々回に続いてjs_of_ocamlの話。今回はDOM要素をコード側で作成する。
だいたいの元ネタはjs_of_ocaml公式サンプルのこれ:
https://github.com/ocsigen/js_of_ocaml/blob/master/examples/minesweeper/main.ml
ただし、この記事ではCanvas要素を作成・追加して赤い四角を描画してみる。
構成は前回と同様。dune
ファイルには変更なし。
main.mlはこんな感じ:
open Js_of_ocaml module Html = Dom_html let js = Js.string let document = Html.window##.document let create_canvas width height = let canvas = Html.createCanvas document in canvas##.width := width; canvas##.height := height; canvas##.style##.border := (js "1px solid #000000"); canvas let draw_square canvas_context x y w h = canvas_context##.fillStyle := (js "#FF0000"); canvas_context##fillRect x y w h let start _ = let main = Js.Opt.get (document##getElementById (js "main")) (fun () -> assert false) in let canvas = create_canvas 500 500 in let canvas_context = canvas##getContext Html._2d_ in ignore @@ draw_square canvas_context 200. 200. 50. 50.; Dom.appendChild main canvas; Js._false let () = Html.window##.onload := Html.handler start
create_canvas
はCanvas要素を作成してプロパティをいくつかセットしている。draw_square
は与えられたCanvasContextに赤い四角を描く。
start
関数は多少こみいっている。
Js.Opt.get (document##getElementById (js "main")) (fun () -> assert false)
でidがmainのDOM要素を取ってきている。そんな要素が存在しない時のためにgetElementById
はjs_of_ocaml特有のオプション型を返してくるのでJs.Opt.get
でオプションを外してやる(要素が見つからなかったらassert false
!ここは公式サンプルに準拠)
create_canvas
とdraw_square
で赤い四角の描かれたCanvasを作成してから、id=mainの要素の子として追加している。
最後にonload
時のハンドラとしてこのstart
関数を設定。ここでうっかり
let () = start ()
などとしてしまうと、スクリプトが読み込まれた時点ではid=mainなHTML要素がまだ作成されていないのでエラーだけ投げて何も起きない。ここらへんはJSではおなじみ。
HTMLにはid=mainなdivを追加しておく:
<html> <head> <script type="text/javascript" src="_build/default/main.bc.js"></script> </head> <body> <div id="main"></div> </body> </html>
これでdune build ./main.bc.js
してmain.htmlをブラウザで開けば白いCanvasの真ん中に赤い四角が描かれている。