#はじめに
この記事では以下のような表現をウェブサイト上で実現し,とにかくカッコいいサイトを作ることを目指します.
上記のような表現をするときによく用いられるのはProcessingというプログラミング言語, およびProcessingのJavaScriptラッパーであるp5.jsですが,今回はReactを用いてGenerative Artをコンポーネントとして実現します.
p5.jsをReactでそのまま扱うのは大変なので,今回はreact-p5およびreact-p5-wrapperというp5.jsをReactで簡単に扱えるようにしたライブラリを用います.先人に感謝です.
本記事の対象読者は以下の通りです.
- React.jsを少し触ったことがある
- クリエイティブコーディングに興味がある
- Webサイトの表現の限界を追求してみたい
また,環境構築にはcreate-react-appを用い,github-pagesに作成したアプリケーションをデプロイします.
実行環境は以下の通りです.
- macOS Mojave : 10.14.5
- node : 12.7.0
- npm : 6.10.2
- yarn : 1.17.3
- create-react-app : 3.0.1
- github-pages : 2.1.0
今回は初回なので,p5.jsをReact上でどう動作させるのか,といった所に焦点を当てていきます.
では早速やっていきましょう!!
環境構築
まず自分の好きなディレクトリから,create-react-appを用いてアプリケーションの雛形を作成します.
yarnやcreate-react-appがない場合は以下のようにインストールできます.
brew install yarn
yarn add create-react-app -g
その後プロジェクトディレクトリへ移動してください.
(myappという名前は適宜変更してください)
create-react-app myapp
cd myapp
プロジェクト自体を作成できたら,まずはサイトのデプロイ自体ができるかどうかを試してみましょう.
以下のコマンドを入力してください.
yarn add gh-pages --save-dev
さらに,プロジェクトディレクトリ直下にあるpackage.jsonに,以下のように書き加えてください.
...(省略)
"homepage": "http://username.github.io/myapp"
"scripts": {
...(省略)
"predeploy": "yarn run build",
"deploy": "gh-pages -d build --git git"
}
上記のように記述することで,コマンドラインにてmyappディレクトリで,yarn run deploy
といった形で上記のコマンドを実行できるようになります.
自分用便利コマンドみたいな感じですね.
それでは次に,github pages用の準備をしていきます.
github pagesを使うと,静的なサイトに限りますが,簡単にプロトタイプを作って試せるので便利です.
まず,自分のGitHubのページへ飛び,リポジトリを作成してください.
この時の名前は何でもいいですが,create-react-app
で使った名前と同じ名前がわかりやすいかなと思います.
リポジトリを作成したら,作成直後のページに書いてあるようにremote repositryへのpushまでやってしまいましょう.
多分以下のようなコマンドになると思います(README.md関連のコマンドは省略).
git add -A
git commit -m "first commit"
git remote add origin git@github.com:username/myapp.git
git push -u origin master
さらにpackage.jsonに記述したコマンドを動かしてみましょう.
以下のコマンドを実行してください.
yarn run deploy
なお,github-pagesへのデプロイ時にエラーが出た際は,deployコマンドに--git git
オプションが付いているかを確認してみてください.
2019年8月6日現在, github-pages 2.1.0でデプロイをする際にエラーが発生してしまうバグがあるようです(以下のような感じです).
詳しくは拙文ですが以下をご覧ください.
gh-pages -d buildが出来ない(キレそう)
うまくデプロイができると, https://username.github.io/myapp/にてcreate-react-appによって生成された画面が確認できると思います.
ひとまずこれでデプロイの確認は完了ですね.
react-p5-wrapperを試してみる
改めてp5.jsの説明からいきます.
p5.jsとは,Javaベースのビジュアルアート・デザイン用の言語・開発環境であるprocessingのJavaScriptラッパーです.
processing経験者なら簡単に移行できるよう,構文などもほとんど同じで書かれているらしいです(筆者はprocessingを触ったことがないのであまり言及できません)
今回用いるのは,Reactのコンポーネント指向な考え方に合うように作られた,p5.jsのラッパーライブラリ,react-p5-wrapperです.
このライブラリを用いることで,簡単に動的な描画アートの変更や,アプリケーションの状態による挙動の変化などを実現することができます.
まず以下のように必要なモジュールをインストールしてください.
yarn add react-p5 --save
yarn add react-p5-wrapper --save
yarn upgrade p5@0.9.0 --save
yarn add styled-components --save
yarn add styled-reset --save
yarn add react-router-dom --save
さらに,create-react-appで生成されたファイルをいじっていきます.
ディレクトリ構成は以下のようになる予定なので,適宜参照してください.
.
├── README.md
├── build
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.css
│ ├── App.js
│ ├── index.css
│ ├── index.js
│ ├── serviceWorker.js
│ └── testSketch.js
└── yarn.lock
では,まずsrcディレクトリのApp.jsファイルをいじっていきます.
import React from 'react'
import P5Wrapper from 'react-p5-wrapper'
import testSketch from './testSketch'
import './App.css'
const App = () => (
<P5Wrapper sketch={testSketch} />
)
export default App
上記の通り,react-p5-wrapperモジュールをimportして,Appコンポーネントの中でP5Wrapperコンポーネントを呼び出しています.
P5Wrapperコンポーネントにはsketchという関数オブジェクトを渡します.
sketchがビジュアルアートのための関数で,作品の本体になります.
では,作品を作っていきましょう.
まずはreact-p5-wrapper公式のテストコードを動かしてみることとします.
以下は記載されているコード例をES6記法で書き直したものです.
srcディレクトリ以下にtestSketch.jsファイルを作成して記述していきます.
const testSketch = (p) => {
let rotation = 0
//初期設定
p.setup = () => {
p.createCanvas(p.windowWidth, p.windowHeight, p.WEBGL)
}
//P5Wrapperコンポーネントからのpropsの受け渡し
p.myCustomRedrawAccordingToNewPropsHandler = (props) => {
if (props.rotation){
rotation = props.rotation * Math.PI / 180
}
}
//毎フレームごとの描画内容
p.draw = () => {
p.background(100)
p.normalMaterial()
p.noStroke()
p.push()
p.rotateY(rotation)
p.box(100)
p.pop()
}
}
export default testSketch
上記では,WebGLモードでcanvas要素を生成し,その中に立体の箱を生成します.
そしてコマンドラインにて以下のコマンドを実行してローカルサーバを立ち上げ,結果を確認してみます.
yarn run start
ブラウザで確認して,以下のように表示されれば成功です!!
通常,processingやp5.jsはsetup, draw
などと書くのですが,react-p5-wrapper
ではp.setup, p.draw
のように記述します.
これはp5.jsに存在する関数や定数を一切合切全てpという名前のインスタンスとして渡しているからです.
ちょっとめんどくさいですが, p5.js由来の関数・メソッド・定数には全てp.
とつけてください.
では次にP5Wrapperコンポーネントにプロパティを渡してみます.
以下のように,rotation={45}
という記述を追加します.
...
const App = () => (
+ <P5Wrapper sketch={testSketch} rotation={45} />
)
...
そして結果を確認すると,以下のように45°回転していることが確認できると思います.
ちゃんと立体ですね.
それでは,さらにReactっぽい書き方をしながらこれを改造していきましょう.
今回は,バーによって回転具合を調節できるようにしてみます.
なお,これはreact-p5-wrapperのsampleを簡略化して実装したものです.
https://github.com/and-who/react-p5-wrapper
では早速やっていきましょう.
まずAppコンポーネントをクラスとして書き直しましょう.
import React, { Component } from 'react'
import P5Wrapper from 'react-p5-wrapper'
import testSketch from './testSketch'
import './App.css'
class App extends Component{
//初期値を45°に設定
constructor(props) {
super(props)
this.state = {
rotation: 45,
}
}
//バーの値が変化するごとに回転角を変更
rotationChange(e){
this.setState({rotation:e.target.value});
}
//コンポーネントの描画
//生成されるcanvasの下にバーを置く
render () {
return (
<div>
<P5Wrapper sketch={testSketch} rotation={this.state.rotation} />
<input type="range" value={this.state.rotation} min="0" max="360" step="1" onInput={this.rotationChange.bind(this)}/>
</div>
)
}
}
export default App
sketchの方を変更する必要はありません.
コマンドラインにてyarn run start
を実行すると,以下のように動作させることができると思います.
上記コードでは,バーの値が変化すると,そのイベントを受け取って新しい回転角をstateに設定します.
描画される箱の回転角は,P5Wrapperに渡されているrotationの値によって決まるので,上記のような表現が可能です.
また,sketchにてp.rotateY(rotation)
としていますが,p.rotateX(rotation)
やp.rotateZ(rotation)
に変更したり,追記することで異なった挙動を実現することもできます.
今回は以上で終わりです!最後にgithub pagesにデプロイしておきましょう.
yarn run deploy
お疲れ様でした!
まとめ
次回はp5.jsを生かした作品を作り,Webサイトとして公開するところまでやっていきます.
いい感じにかっこよくなるといいですね(したい).