LoginSignup
4
4

More than 3 years have passed since last update.

p5.jsとDjangoでインタラクティブシミュレーション(1) p5.jsのスケッチをDjangoで公開してみよう

Last updated at Posted at 2019-04-11

はじめに

筆者のラボでは,人を含むシステムの挙動を分析するために,またそうしたシステムの中に置かれた人の挙動を分析するために,ユーザが途中で介入できる形式のコンピュータシミュレーション(インタラクティブシミュレーション)をウェブ上のゲームとして開発し,よく利用している.

このドキュメントは,そうしたインタラクティブシミュレーションのアプリケーションをp5.jsとDjangoを用いて開発するための基礎を身につけてもらうことを狙いとしたもので,あまり一般的なニーズはないかもしれないが,もし多少でもどなたかの参考になれば幸いだ.

なお,p5.jsはProcessingをjavaScriptに移植したものである.ここに詳しい情報があるので,必要に応じて参照しながら読み進めてほしい.

Processingに慣れている人は,Processingとp5.jsの違いがここにまとめられているので,はじめに目を通しておくとよいだろう.

また,Djangoについては,ここに入門的な情報をまとめてあるので,馴染みのない人はまずそちらを読んでからこちらに進むことをおすすめする.

今回は全4回中の1回目で,全体のコードはまとめてGitHubに置いた.

p5.jsのスケッチをDjangoで公開してみよう

まず,p5.jsを利用するための準備から始めよう.p5.jsのダウンロードページからComplete Libraryをダウンロードして解凍すると,下記のようなディレクトリ構成でいくつかのファイルが現れる.

p5/
    addons/
        p5.dom.js
        p5.dom.min.js
        p5.sound.js
        p5.sound.min.js
    empty-example/
        index.html
        sketch.js
    p5.js
    p5.min.js
    p5.pre-min.js

これらのファイルのうち,今後編集していくのはhtmlファイル(上ではindex.html)とスケッチのコード(上ではsketch.js)の2つである.

最初に,index.htmlのファイルを開いて,下記のように少し修正を加えよう.

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

<!--    <title>p5.js example</title>
    <style> body {padding: 0; margin: 0;} </style>  -->

    <title>Simulation</title>

    <script src="../p5.min.js"></script>
    <script src="../addons/p5.dom.min.js"></script>
<!--        <script src="../addons/p5.sound.min.js"></script>  -->
    <script src="sketch.js"></script>
  </head>

  <body>
    <h1>Interactive Simulation</h1>
    <div id="mysketch"></div>
    <h1>Please Enjoy!</h1>
  </body>
</html>

まず,タイトルをSimulationに変更し,paddingmarginの設定をコメントアウトしている(これは純粋に好みの問題だ).サウンド関連のライブラリも,このチュートリアルでは利用しないので,コメントアウトしている.

注意してほしいのは,bodyの中にmysketchというidのdivを挿入している点である.p5.jsのスケッチをこのdivの部分に挿入するようにしたい.後でそれが確認できるように,divの前後にInteractive SimulationとPlease Enjoy!というメッセージを表示するようにしている.

次に,sketch.jsの方を編集しよう.まずは慣習に従ってHello World!を表示してみる.

function setup() {
  var my_element = select("#mysketch");
  var my_width = min(my_element.width, 1000);
  var my_canvas = createCanvas(my_width, my_width *0.6);
  my_canvas.parent("mysketch");

  background(200);
  textSize(32);
  textAlign(CENTER, CENTER);
  text("Hello World!", width /2, height /2);
}

function draw() {
}

setup()draw()の役割はProcessingと同じである.基本的には,最初にsetup()が1回だけ実行され,その後,draw()がwhileループのように何度も繰り返し実行される(が,上ではdraw()は空である).

まず,setup()の中で,mysketchのidのdivを選択しそれをmy_elementという変数で参照できるようにしている.そして,キャンバスを作成し,それをmysketchの子要素に設定している.

このキャンバスのサイズ(widthheight)は,my_elementの幅(my_element.width)に基づいて10:6になるように指定されていることもわかる.p5.jsのスケッチはこのキャンバスの中に描かれる(background(), textSize(), textAlign(), text()は基本的なp5.jsの関数である.馴染みのない人はリファレンスを参照してほしい).

ここで一度,index.htmlをブラウザで開いてみよう.グレーの背景のキャンバスが現れ,その中心にHello World!の文字が表示されていれば成功だ.

続いて,このスケッチをDjangoと連携させよう.Django側で,まずmysiteというプロジェクトとsimというアプリケーションを作成したとする(settings.pyのINSTALLED_APPSのリストにsimを忘れずに追加しておく).

この段階で,プロジェクトのディレクトリ構成を下記のように更新しておこう.

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    sim/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        static/ *
            code/ *
                sketch.js **
            p5/ **
        templates/ *
            sim/ *
                index.html **
        tests.py
        urls.py *
        views.py

*を付けているのは,デフォルトで自動的には作成されないディレクトリやファイルである.これらは手動で追加してほしい(sim/urls.pyのファイルはひとまず空でよい).

**を付けているのは,上で作成したスケッチ関連のディレクトリやファイルである.index.htmlはsim/static/templates/simの中に,sketch.jsはsim/static/codeの中に,それぞれコピーし,それら以外はp5ディレクトリごとsim/staticの中に入れる.

次に,urlルーティングを設定しよう.まず,mysite/urls.pyの方を下記のように修正し,simアプリケーション関係のルーティングをsim/urls.pyの方に委ねるようにする.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('sim/', include('sim.urls')),
    path('admin/', admin.site.urls),
]```

sim/urls.pyの方には下記の内容を書き入れる

```python
from django.urls import path
from django.views.generic import TemplateView
from . import views

app_name = 'sim'

urlpatterns = [
    path('', TemplateView.as_view(template_name='sim/index.html'), name='index'),
]

このTemplateViewは,as_view()メソッドで指定されたテンプレート(index.html)をレスポンスとして返してくれる.ただし,Djangoのテンプレートとして機能させるために,index.htmlにも少し修正を加える必要がある.

{% load static %}

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

<!--    <title>p5.js example</title>
    <style> body {padding: 0; margin: 0;} </style>  -->

    <title>Simulation</title>

    <script src="{% static 'p5/p5.min.js' %}"></script>
    <script src="{% static 'p5/addons/p5.dom.min.js' %}"></script>
<!--    <script src="{% static 'p5/addons/p5.sound.min.js' %}"></script>  -->
    <script src="{% static 'code/sketch.js' %}"></script>
  </head>

  <body>
    <h1>Interactive Simulation</h1>
    <div id="mysketch"></div>
    <h1>Please Enjoy!</h1>
  </body>
</html>

最初に{% load static %}を指定することでstaticタグが使えるようになる.これで,staticディレクトリ内に格納してあるstaticファイルに,上記のようにstaticタグを用いてアクセスできるようになる.

これで準備が整ったはずである.Djangoの開発用サーバを立ち上げ,ブラウザで次のアドレスにアクセスしてみよう.

先ほどのHello World!のスケッチが表示されればOKだ.

おわりに

ひとまず第1回はここで終了.第2回に続く.

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4