Home About Contact
Rust , WebAssembly

Rust + Wasm で三角形をキャンバスに描画

Triangle

Rust に入門した。

何から始めるか悩む。 「RustとWebAssemblyによるゲーム開発」という本があり コードした結果がビジュアルにわかるほうが 取り組み易い気がしたので、ここからはじめることにする。 この本は rust-webpack-template を使って説明がはじまるのだが・・・ すでにこのレポジトリはメンテナンスされていないらしくそのままでは動かない。 そこで、 こちらの説明 https://developer.mozilla.org/en/docs/WebAssembly/Guides/Rust_to_Wasm をベースに三角形を描画する部分まで進めたので備忘録としてここに書き残します。

プロジェクトのベースを作成:

$ cargo new --lib triangle

src/lib.rs を書きかえる:

use wasm_bindgen::prelude::*;

#[wasm_bindgen(start)]
pub fn main_js() -> Result<(), JsValue> {
    let window   = web_sys::window().unwrap();
    let document = window.document().unwrap();
    let canvas   = document.get_element_by_id("canvas").unwrap().dyn_into::<web_sys::HtmlCanvasElement>().unwrap();
    let ctx      = canvas.get_context("2d").unwrap().unwrap().dyn_into::<web_sys::CanvasRenderingContext2d>().unwrap();

    ctx.move_to(150.0, 0.0);
    ctx.begin_path();
    ctx.line_to(0.0, 300.0);
    ctx.line_to(300.0, 300.0);
    ctx.line_to(150.0, 0.0);
    ctx.close_path();
    ctx.stroke();
    ctx.fill();

    Ok(())
}

コードの詳細は 「RustとWebAssemblyによるゲーム開発」を読もう。

設定ファイル Cargo.toml に設定を追加:

[package]
name = "triangle"
version = "0.1.0"
edition = "2024"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

[dependencies.web-sys]
version = "0.3.55"
features = ["Window", "Document", "HtmlCanvasElement", "CanvasRenderingContext2d"]

web-sys 関連で今回のコードで使用したものを追記した。

ビルドする:

$ wasm-pack build --target web

index.html を作成:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>triangle</title>
  </head>
  <body>
    <canvas id="canvas" tabindex="0" height="300" width="300"/>
    <script type="module">
        import init from "./pkg/triangle.js";
        init();
    </script>
  </body>
</html>

ビルドされた pkg/triangle.js をインポートして init() を呼ぶことで src/lib.rs で定義したコード(三角形を描画するコード)が実行される。

$ python3 -m http.server 8000

ブラウザで作動を確認:

http://localhost:8000/

Triangle

src/lib.rs の ctx (web_sys::CanvasRenderingContext2d) でどんなメソッドが呼べるかは、 このページをみる:

真っ黒の三角形は味気ないので、ボーダーと背景色を黒以外の別の色に設定してみる:

    let fill_color_str = format!("rgb({}, {}, {})", 238, 232, 213);
    let stroke_color_str = format!("rgb({}, {}, {})", 203, 75, 22);

    ctx.set_fill_style_str(&fill_color_str);
    ctx.set_stroke_style_str(&stroke_color_str);
    ctx.set_line_width(2.0);

これで再度ビルドして作動を確認すると次のようになりました:

Triangle

ストロークを2.0の太さにしたので、三角形の下の部分が表示しきれない。 その場合は index.html に設定した canvas の大きさを調整しよう。

<canvas id="canvas" tabindex="0" height="302" width="302"/>

Rust + Wasm でキャンバスに画像を描画 に続く。