p5.jsのスケッチをSVG変換するライブラリがあった


2017年10月20日
With
p5.jsのスケッチをSVG変換するライブラリがあった はコメントを受け付けていません

最近、YouTubeで見つけた、こちらのチュートリアルビデオシリーズを見ました。

Designing Generative Systems w/ P5.js(YouTube)

Matthew Eplerさんという方が作られたビデオで、p5.jsによるデザインの自動生成プログラムの書き方を説明しておられます。全21本の結構なボリュームのチュートリアルなのですが、英語字幕を流しながら自分でもコードを書いてみたところ、いろいろとタメになりました。

僕が個人的に「目からウロコ」だったポイントは以下の3つです。

  1. p5.jsのスケッチをSVG形式に変換できるライブラリがあった
  2. ES2015が、もうワリと普通にブラウザで動く
  3. 最近はやりの「関数型プログラミング」がなんかスゴそう

とりあえず、このチュートリアルの17章までを終えると、次のプログラムが完成します。

●[DEMO] Designing Generative Systems w/ P5.js by matthew epler(クリックすると別タブが開きます)

リンクを開くと、画面上にこんな画が出てくると思います。

F5キーなどでリロードすると、その度、画面に並ぶグラフィックがランダムに変化します。プログラム自体は、レイヤごとに設定されたパーツの有無やパラメータ(色とか、頂点の数とか)をランダムに変化させ、組み合わせて表示するというものです。

で、面白いパターンが出てきたら、画面左上にある「save SVG」と書かれたボタンを押してみてください。その時、画面に表示されている画をSVG形式でダウンロードできます(Chrome、FireFoxで確認)。

p5.jsのスケッチをSVGに変換するライブラリ

実は、上のスケッチの出力。通常のp5.jsでの「canvas」での出力とは違い、ブラウザ上には「SVG(Scalable Vector Graphics)」として描画されています。

canvasでの描画と、SVGでの描画との違いは、ざっくり言うとブラウザ上でのレンダリングが「ラスタ(ビットマップ)」か、「ベクタ」かの違いです。

下の画像は、以前作った「荒ぶるベジェ曲線」を通常のp5.jsとSVG変換ライブラリを使って表示し、それぞれにブラウザ上で500%まで拡大したものです。canvasだと、拡大したときに線のカーブがピクセルでギザギザになっていますが、SVGだとベクターグラフィックとして拡大されるのでシェイプがキレイに出ているのが分かると思います。Adobeのツールで言うと、ビットマップは「Photoshop」的に扱うデータ、SVGは「Illustrator」的に扱うデータという感じですね。

このチュートリアルビデオで紹介されているSVG変換ライブラリは、zenozeng氏によって作られているもので、こちらで公開されています。Processingには、同様のSVG出力用ライブラリがありましたが、p5.js向けに作っていらっしゃる方がいたのですね。

p5.js-svg(Github)

利用にあたっては「p5.svg.js」を追加のライブラリとしてHTMLのscriptタグで読み込んでおき、「createCanvas」の第3引数として「SVG」と指定すればいいのですが、注意しなければならないのは、一緒に使う「p5.js」本体のバージョンが指定されている点です。基本的には、先ほどのページで、p5.svg.jsと一緒に公開されている「p5.js」をダウンロードし、組み合わせて利用すれば問題ないはずです。ちなみに、公式サイトで公開されているp5.jsの最新版(0.5.16)では動きませんでした。(2022/10/18追記:p5.js-svgの最新版では、p5.js v1.4.xへの対応が行われています。詳細については、p5.js-svgのGitHubを参照してください)

先ほどのデモでは「save SVG」ボタンを使って、スケッチをSVG形式で保存できるのですが、これ、何がいいのかというと、保存したSVGファイルをIllustratorなどのグラフィックツールで開いて、ベクターデータとして編集できるんですね。

ちゃんとそれぞれのコマンドで描画した線やら図形やらが、Illustratorのレイヤに分割されています。canvasでプリントクオリティの画像を作ろうと思うと、サイズ(解像度)をバカでかくする必要があるのですが、SVGとして出力できるのであれば、実用的なサイズで描画しておき、出力されたものに後で微調整を加えて、最終的にプリント向けにフィックスするといった使い方もできそうですよね。

例えば、ラスタとベクタの比較に使った「荒ぶるベジェ曲線」のデータも、

SVGで出力して、Illustratorで開けば、こんな感じで1本ずつ、きちんとパスとして読み込まれています。

SVGで出力するスケッチに利用できる関数に制限などもあるようですが、使いどころを決めておけば、いろいろと応用が利きそうなライブラリです。

たぶんもう(仕事でなければ)「ES2015」で書いてもだいじょうぶ

Matthew Eplerさんのチュートリアルビデオ。見てみると分かるのですが、コードは「ECMAScript 2015」準拠で書かれています。

「ES6」とも呼ばれていた「ES2015」は、仕様の公開が2015年6月でした。公開当時、一般的なブラウザで使えるようになるのは、まだまだ先のような気もしていたのですが、このあたりを見る限り、Edge、FireFox、Chrome、Safariといった主要なブラウザではだいぶ対応が進んでいて、趣味でスケッチを描くくらいの用途であれば、もうES2015の書き方でもよさそうですね。実際、チュートリアルの内容も、そのまま問題なく動きました。

ES2015と以前のJSとの違いで驚いたのは、

  • 変数の宣言として「const」「let」を使う(「var」は非推奨
  • 「class」が使えるようになった

特に「class」については、継承も「extends」や「super()」を使って、前よりシンプルに書けるようになってます。

あとは「配列内に格納された各オブジェクトの特定のメソッドを順に実行する」というよくあるシチュエーションのための記述が、次のような1行でできるようになっていたことです。

ALL_CRYSTALS.forEach(crystal => { crystal.render(); });

ES5から使える「Array.forEach()」と、ES2015からの「アロー関数」との組み合わせなのですが、これまで、こういう時には「for文で配列の添字をカウントアップしながらループで実行させる」方法しか知らなかったんですよね。

classもそうなんですが、これまでよりもシンプルに書ける部分については、今後作るスケッチからなるべく取り入れていこうと思いました。

「関数型プログラミング」がなんかスゴそう

Matthew Eplerさんのチュートリアルビデオでは、0~17章で「オブジェクト指向」のプログラミングスタイルでスケッチを完成させ、18~21章では、完成したプログラムを「関数型プログラミング」のスタイルに書き直すということをやっています。

これまで仕事の中で「関数型プログラミング」や、それに関連する「ラムダ式」「モナド」といった言葉だけは聞いたことがあったのですが、実際にそのスタイルでのプログラミングがどういうものかというのは、恥ずかしながら、このビデオを見て初めて知りました。

正直なところ、まだ理解が追いついておらず、そのうち余裕ができたら日本語の文献でも読みながら勉強してみようと思った程度で、動画も流し見してしまったのですが「オブジェクト指向はある程度使えるけれど、関数型がどういうものかいまいちピンとこない」という方は、じっくりと見てみるとイメージがつかめるのではないかと思います。

というわけで、いろいろと勉強になったビデオでした。