2014/11/05
「Matter.js」を使ってCanvasの物理演算をやってみました
Canvasなどでのアニメーションでは、物理演算を行うことができれば、
より面白い演出が可能となり、表現の幅も広がるので是非やってみたいものではありますが、
物理演算を自力で行おうとすると、それなりの専門知識と時間・労力が必要となります。
ただ、この物理演算をより簡単に行うことができるようになるJavaScriptのAPIがいくつか提供されています。
「Box2DWeb」というAPIが、Flashの時代から重宝され、JavaScript版も公開されており、
使い方が説明されたサイトも多くあるのですが、
若干ファイルが重い(ver.2.1.a.3のminify版で225KB)という問題もあります。
そこで他にもないかと探していたところ、
「Matter.js」という物理演算APIが軽量(ver.0.8.0のminify版で54KB)で使いやすそうでしたので、
実際にこのAPIを使ってCanvasの物理演算を行ってみました。
↓作ってみたもの
方法
1.「Matter.js」のプロジェクトサイトからAPIをダウンロードします。
「Minified Version」というリンクをクリックして、ダウンロードします。
2.HTMLを準備する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!doctype html> <html> <head> ・・・ <script type="text/javascript" src="js/matter-0.8.0.min.js"></script> <style type="text/css"> /* canvasの背景を設定 */ #canvas-container canvas{ background: url(./images/texture.png) repeat !important; } </style> ・・・ </head> <body> ・・・ <div id="canvas-container"></div> ・・・ </body> </html> |
ダウンロードしたファイルを読み込み、
Canvasを設置する場所を用意します。
今回は「canvas-container」というIDの<div>を用意しました。
また、canvasの背景はAPIの設定でもできるのですが、多少自由が効かない部分がありましたので、
CSSで「!important」をつけて設定しました。
3.「Matter.js」のAPIの設定をする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | //Matter.js モジュール 初期設定 var Engine = Matter.Engine, //物理シュミレーションおよびレンダリングを管理するコントローラーとなるメソッド World = Matter.World, //物理演算領域の作成・操作するメソッドを含む Body = Matter.Body, //剛体のモデルを作成・操作するメソッドを含む Bodies = Matter.Bodies, //一般的な剛体モデルを作成するメソッドを含む Constraint = Matter.Constraint, //制約を作成・操作するメソッドを含む Composites = Matter.Composites, Common = Matter.Common, Vertices = Matter.Vertices, //頂点のセットを作成・操作するメソッドを含む MouseConstraint = Matter.MouseConstraint; //マウスの制約を作成するためのメソッドが含む // Matter.jsのEngineを作成 var container = document.getElementById('canvas-container'); var engine = Engine.create(container, { render: { //レンダリングの設定 options: { wireframes: false, //ワイヤーフレームモードをoff width: 640, //canvasのwidth(横幅) height: 480, //canvasのheight(高さ) background: 'rgba(0, 0, 0, 0)' } } }); // マウス操作を追加 var mouseConstraint = MouseConstraint.create(engine); World.add(engine.world, mouseConstraint); //床を作る World.add(engine.world, [Bodies.rectangle(320, 460, 480, 20, { isStatic: true, //固定する render: { fillStyle: '#977559', // 塗りつぶす色: CSSの記述法で指定 strokeStyle: 'rgba(0, 0, 0, 0)', // 線の色: CSSの記述法で指定 lineWidth: 0 } })]); //物体を追加する for (var i = 0; i < 10; i++) { var rnd = parseInt(Math.random() * 10); var x = 320 + rnd * 10; var y = 0 - rnd * 120; rnd2 = parseInt(Math.random() * 640); var x2 = rnd2; var y2 = 0 - rnd2 * 2; World.add(engine.world, [ Bodies.circle(x, y, 60, { //ボールを追加 density: 0.0005, // 密度: 単位面積あたりの質量 frictionAir: 0.06, // 空気抵抗(空気摩擦) restitution: 1, // 弾力性 friction: 0.01, // 本体の摩擦 render: { //ボールのレンダリングの設定 sprite: { //スプライトの設定 texture: './images/ball.png' //スプライトに使うテクスチャ画像を指定 } }, timeScale: 1.5 //時間の倍率を設定(1で1倍速) }), Bodies.rectangle(x2 , y2, 160, 32, { //長方形を追加する render: { sprite: { //スプライトの設定 texture: './images/logo.png' //スプライトに使うテクスチャ画像を指定 } } }) ]); } // 物理シュミレーションを実行 Engine.run(engine); |
API設定の大きな流れとしては、
- Matter APIの主要なモジュール(メソッド)を初期化
- 物理演算を行う空間の準備
- 演算する物体の設置
- 物理演算の実行
となります。
円、長方形などの基本的な図形はあらかじめ用意されていますし、
パスで図形を作ることもできます。
それぞれの物体に画像をテクスチャとして貼付け、スプライトを設定することもできます。
また、マウスの操作も、
1 2 3 | var MouseConstraint = Matter.MouseConstraint; var mouseConstraint = MouseConstraint.create(engine); World.add(engine.world, mouseConstraint); |
この3行だけで実装できるので、とても簡単です。
また、物理演算は多くの演算処理を必要とするため、
複雑なものになってくると処理が遅くなってしまう可能性が高くなりますが、
「Matter.js」ではレンダリングの方法として、通常のCanvasだけでなく、WebGLを指定することもできるため、
対応している端末ではCPUではなくGPUで演算処理を行うWebGLの特性を利用して、
演算処理を速くして、動作を軽くすることもできます。
参考にさせていただいたサイト
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE