RustでWebAssembly: Canvas2dでBallがたくさん動くアニメーション
はじめに
前回 は、Rustに状態を持たせたり、DOMを更新したりしてみました。
今回はなにかアニメーションみたいなのを作ってみようと思います。
Versionなどは前回と同じです。
作ったもの
なんとなく四角の中を赤いBallが大量に飛び回るものを作ってみます。
Ballが何個のときにFPSがどのくらいかなぁ、というのがちょっと気になるところです。
内容
困ったこと
アニメーションさせるのに requestAnimationFrame()
というBrowser側?のAPIを使うことが多いと思いますが、requestAnimationFrame()
は setInterval
とかと違って定期的に呼ばれるわけではないので、 requestAnimationFrame()
の内部でもう一度 requestAnimationFrame()
を呼ばないといけません。
最初は、Rustの on_animation_frame()
みたいな method の中で 再び requestAnimationFrame()
を呼ぶようにしようと思ったのですが、そこで closureを渡すのが尋常じゃなく上手くいかなくて、、、諦めました。(今ならなんとかできるかもしれないが、少し面倒そうなのはかわらない)。したがって、JS側でそのループを作って毎回 Rustのon_animation_frame()
を call してもらうようにしました。まあ、こういうのも無くはないかな、と。
それ以外は、素直なRustプログラムになって、かなりコンパイラに怒られながらも動くものが作れました。
コード
Cargo.toml
-
rand = { version="0.7.3", features =["wasm-bindgen"] }
が追加。- このfeaturesを指定しないと、WASM内でrandが使えないようなので注意が必要
- web-sys feature:
CanvasRenderingContext2d
- Context2d使うので必要
index.html
ちょっと妥協の産物ですが、これで毎回AnimationのFrameを更新するようにしています。
import init, * as wasm from './pkg/rust_wasm_example.js';
async function run() {
await init();
const myApp = wasm.MyApp.new({canvas_id: "canvas", initial_n_balls: 1000});
myApp.init();
function onAnimationFrame(t) {
const ret = myApp.on_animation_frame(t);
if (ret) {
requestAnimationFrame(onAnimationFrame);
}
}
requestAnimationFrame(onAnimationFrame);
}
run();
他
Animationをさせるためにコードは色々書きましたが特筆するようなところはないかな。
ちょっと工夫したのは、Ballに動きの尾ひれ(残像?残影?軌跡?)をつけるために、過去数フレームの位置を保存させて描画しているところかな。全体を保存(コピー)させているけど、Ball毎にVecとかで履歴を持たせたほうが良かったかな。そうすると、1本の線とかにもしやすかっただろうし。
まあ、ちょっと固まったRustのコードを書くいい練習にはなりました。
ちなみに今回requestAnimationFrame() を使うと、1frameあたりの処理が十分早ければちょうどFPS=60になるようでした。遅くなると60を切っていきます。
「衝突」「引力 or 斥力」を全Ball間でしているので、Ballの数が増えると計算量が結構あがっていきます。私のPCだと4~500個くらいで FPSが60を切ってしまうかな、という感じでした。
上記の計算をしない場合は、だいたいCanvasへの描画処理ばかりになるのでもうちょっとBallが多くてもFPS60が維持されます。
さいごに
なんか、仕様&動作確認的な実験的なものばかりだと飽きるので作ってみた他愛のないものですが、せっかくなので書き残しておきました。
Author And Source
この問題について(RustでWebAssembly: Canvas2dでBallがたくさん動くアニメーション), 我々は、より多くの情報をここで見つけました https://qiita.com/mokemokechicken/items/37fec7b97350a26a1932著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .