はじめに
こちらは、完走賞ゲットのため小ネタを毎日投稿しようとチャレンジする Advent Calendar 2022 の 7日目の記事です。
今回の記事では、p5.js と JavaScript のモジュール「ES Modules」に関する内容を扱います。HTML+JavaScript で扱う場合、 <script type="module" src="。。。"></script>
といった書き方をしつつ import文で扱ったりするやつの話です。
参照した情報など
今回の記事を書くにあたり、参照した情報や関連するページを記載します。
- 参照した情報など(実装や説明書き関連で)
- simplex-noise.js関連
p5.js で JavaScript のモジュールを使ってみる
実装する環境
それでは、p5.js を使ったプログラムを書く中で、JavaScript のモジュールを使ってみます。実装環境については、自分が Qiitaの記事を書いたり p5.js の試作をする際にもよく使っている、オンラインの環境「p5.js Web Editor」を使います。
simplex-noise.js関連の情報
実装していく前に、今回利用する「simplex-noise.js」についてなど、情報を軽く確認しておきます。
simplex-noise.js について、公式ページでは「A fast simplex noise implementation in Javascript / Typescript.」と説明されています。
simplex noise
説明文の中で「simplex noise」という言葉が出てきますが、そもそもこれは何か、という話が...
それについて、Wikipedia の「パーリンノイズ(Perlin noise)」の日本語ページで知ることができます。(※ ちなみに、パーリンノイズは、p5.js の noise で実装されているノイズです)
●パーリンノイズ - Wikipedia
https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%83%AA%E3%83%B3%E3%83%8E%E3%82%A4%E3%82%BA
上記のとおり、パーリンノイズの「n次元対応版」で、「計算部分が改善されたもの」となるようです。日本語のページはないですが、以下の Wikipedia のページもあったりするようです。
●Simplex noise - Wikipedia
https://en.wikipedia.org/wiki/Simplex_noise
simplex-noise.js の扱い方
この simplex-noise.js は、以下のツイートをしていたころに初めて利用しました。
その時は、最新版の 4系ではなく、古いバージョンの 2系を使っていました。
その理由は、当時は 4系を使う場合の対処法、つまり p5.js で JavaScript のモジュール(ES Modules)を扱うための対処法がすぐに分からなかったためです。これを 2系にしてやれば、 <script src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.4.0/simplex-noise.min.js"></script>
で読み込んで、あとは JavaScript のプログラムで new SimplexNoise();
を呼べばよいだけ、となります(※ 通常のスクリプトになる)。
これを 4系で扱うためには、以下に書かれた使い方を用いる必要があります。
単純に import文を使ってみる
まずは、単純に import文を使ってみます。import文で読み込む対象は、CDN上の最新版の simplex-noise.js とします。
import文を使うために、p5.js Web Editor の index.html で以下の書きかえを行います。差分は、 type="module
を付け加えた部分のみです。
<script src="sketch.js"></script>
<script src="sketch.js" type="module"></script>
次に、sketch.js を作っていきます。JavaScript のプログラムは、単純に 2D のノイズをログ出力するというもので試そうとしてみました。しかし、このプログラムだと動いてくれません。
import { createNoise2D } from "https://cdn.jsdelivr.net/npm/simplex-noise@4.0.1/dist/esm/simplex-noise.js";
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
const noise2D = createNoise2D();
console.log(noise2D(10, 20));
}
単純な import文の利用で動かない原因
単純な import文の利用が p5.js で行えない理由は、以下の MDN のページの記載を見て分かりました。
p5.js は関数がグローバルに追加されますが(※ Instance mode ではなく、Global mode の場合という話になりますが)、上記の import文を扱うための対処を行うと、sketch.js のスコープが限定的になってしまうため、うまく動かなくなるようです。
スコープが限定された中で p5.js の関数を扱う
p5.js の関数がグローバルスコープにあり、それが読めなくなったため、上記の状況が発生した形です。
そこで、この対処法を調べてみて、その 1つの方法が分かりました(※ 上の「参照した情報など」の部分で書いたサイトの情報などから)。具体的には、「windowオブジェクト」を利用する、という対応です。以下で、上記でうまく動かなかったプログラムの書きかえ後のプログラムを掲載してみます。
import { createNoise2D } from "https://cdn.jsdelivr.net/npm/simplex-noise@4.0.1/dist/esm/simplex-noise.js";
window.setup = () => {
createCanvas(500, 400);
};
window.draw = () => {
background(0);
const noise2D = createNoise2D();
console.log(noise2D(10, 20));
};
「window.setup」や「window.draw」と記載することで、グローバルスコープの関数を呼び出すことができ、無事に import文で読み込んだ simplex-noise.js の 4系を利用することができました。
【追記】 別のやり方
その後、「ダイナミックインポート」を使うという別のやり方も試しました。
●p5.js Web Editor で JavaScript のモジュール(ES Modules)を扱う【その2】: simplex-noise.js の CDN からの import でダイナミックインポートを使う - Qiita
https://qiita.com/youtoy/items/838dce76d5be0d44fa14