書道webアプリ「sho-time」

![Untitled.gif](https://qiita-image-store.s3.amazonaws.com/0/320472/193eb3d1-ed38-1445-652c-9ed95c4546fb.gif)

## 更新内容
2021/06/03 - webアプリケーションのリンクを削除しました。
2022/02/20 - p5.jsでアプリケーションを書き直し、デプロイしました。

<br><br>

## とりあえずやってみたい
こちらから👇で試してみてください！

https://sho-time.netlify.app

【機能】
- 「b」キー：墨色
- 「r」キー：朱色
- 「スペース」キー：白紙


<br><br>

## はじめに
クリスマスの後は正月🎍ですね〜
突然ですが、最後に書き初めをしたのはいつでしょうか？

筆で字を書くことが好きな僕はwebでも書き初めをやってみたい！と思い、
今回は筆っぽい文字がかけるwebアプリ『sho-time』をProcessing（p5.js）で実装してみました。


### 目標
リアルな筆字をできるだけ理解しやすく、コード記述量を少なくしたwebアプリケーションを実装したい。

<br><br>

## 実装
### 環境
- HTML5
- css3
- ~~Processing.min.js v1.4.8~~ → p5.js


#### そもそもProcessingとは
> Processing.jsは画像、各種データ可視化、動的コンテンツなど描画用に設計されたプログラミング言語であるProcessingのJavaScript移植版である。 Adobe FlashやJavaアプレットを用いることなくウェブブラウザ上で動画、ゲームなどが実装できる。(参照：Processing.js - Wikipedia)<br>

![color.gif](https://qiita-image-store.s3.amazonaws.com/0/320472/f48a8624-d8f9-e8a1-7bf8-5efbe202d225.gif)
(https://www.youtube.com/watch?v=zwWZox1PKw8)<br>こんなアニメーションができます！

<br><br>
### HTML
それではこれからコードを書いていきます。

まずはじめにHTML要素で書き初めに必要な「下敷き」「半紙」を追加します。

```html:sho-time.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>sho-time</title>
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
  <link rel="stylesheet" type="text/css" href="sho-time.css">
</head>

<body>
  <div class="shitajiki">
    <div class="title">
      <h1>It's <ruby>書<rt>show</rt></ruby> time!</h1>
    </div>
    <div class="hanshi">
    </div>
  </div>
</body>
</html>
```
<br><br><br><br>

### css
先程のHTML要素に対してcssで装飾します。

```css:sho-time.css
/*リセットcss*/
* {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}

h1 {
  font-size: 40px;
}
rt {
  font-size: 20px;
}
.title{
  padding: 100px 0 10px;
}
.shitajiki{
  background-image: linear-gradient(to top, #a8edea 0%, #fed6e3 100%);
  height: 800px;
  text-align: center;
}
.hanshi {
  width: fit-content;
  margin: 0 auto;
  border: 10px solid black;
}
```
<br><br>

### Processing.jsの導入
（注意：**現在（2022年）ではProcessing.jsの開発がストップしているので、p5.jsに書き直して使用することを推奨します。**なので、以下の記述では、コードの部分を主に参考にしてください。）

ここで、Processing.jsをHTMLに導入をします。<br>まず [公式サイトからprocessing.min.jsをダウンロード](http://processingjs.org/download/) します。（「processing.js」と「processing.min.js」がありますが、容量の軽い後者で今回は進めます。）

ダウンロードしたら今回使うファイルを「sho-time」というフォルダにまとめます。フォルダ構成は以下のとおりです。

|  sho-time  ||
|--:| ---- |
|1|  sho-time.html  |
|2|  sho-time.css  |
|3|  Processing.min.js  |
Processing.min.jsは、Processingをjsの記述でも扱えるようにしたものです。<br>また、今回はProcessingを直接書くことで、jsより（個人的な感覚として）シンプルなコードにします！<br>
ファイルを移し替えたら「sho-time.html」ファイルにProcessingのコードを書いていきます。

```html:sho-time.html
.
.
  <link rel="stylesheet" type="text/css" href="sho-time.css">
  <script src="processing.min.js"></script>  ←ここも追加
</head>
.
.
    <div class="hanshi">
      <script type="application/processing">
        //=====「各変数の定義」=====
        float lineWeight = 0.6;
        int i;
        int count = 1;
        String picture;
        int R = 20;        //しずくの大きさ調整用
        int A = 3;         //しずくの丸み調整用

        //=====「初期設定」=====
        void setup(){
          smooth();
          frameRate(60);
          size(1170, 390);
          background(250);
          stroke( 54, 54, 54 );
          fill(54, 54, 54);
        }

        //=====「毎回処理される箇所」=====
        void draw() {
          if (mousePressed) {
            strokeWeight( lineWeight );
            mouseDragged();
          }
        }

        //=====「始筆」=====
        void mousePressed() {
          strokeWeight(2);
          pushMatrix();
          translate(mouseX, mouseY + 3);
          rotate(radians(-150));
          beginShape();
          for (int theta = 10; theta < 361; theta++) {
            float r = 1 / (A * sin(radians(theta)/2)+1);
            vertex(R * r * cos(radians(theta)), R * r * sin(radians(theta)));
          }
          endShape(CLOSE);
          popMatrix();
          redraw();
        }

        //=====「運筆」=====
        void mouseDragged() {
          for (int i = 0; i < 10; i++) {
            float x = random(i);
            float y = sqrt(( sq(i) - sq(x) ));
            line(pmouseX - x, pmouseY + y, mouseX, mouseY);              //右下&左上
            line(pmouseX - x, pmouseY - y, mouseX, mouseY);              //右上&左下
            line(pmouseX + x, pmouseY + y, mouseX + x, mouseY + y);      //右下
            line(pmouseX - x, pmouseY - y, mouseX - x, mouseY - y);      //左上
            line(pmouseX + x, pmouseY - y, mouseX + x, mouseY - y);      //右上
            line(pmouseX - x, pmouseY + y, mouseX - x, mouseY + y);      //左下
            line(pmouseX, pmouseY , mouseX, mouseY);
            line(pmouseX, pmouseY + y, mouseX, mouseY);
          }
        }

        //=====「筆先を整える」=====
        void mouseReleased() {
          lineWeight = 0.6;
        }

        //=====「キー操作」=====
        void keyPressed() {               //"スペース"を押したら「リセット」
          if(key == ' ') {
            background(255);
          }
          if(key == 'r') {                //"r"を押したら墨が「朱色」になる
            stroke( 235, 97, 1 );
            fill( 235, 97, 1 );
          }
          if(key == 'b') {                //"b"を押したら「墨色」になる
            stroke( 54, 54, 54 );
            fill(54, 54, 54);
          }
        }
      </script>
      <canvas id="canvas"></canvas>
    </div>
.
.
.
```
ここで、jsは別のファイルに書いてコードをまとめたほうがスマートじゃん、と思った方。そのとおりです！<br>ですが、今回は時間の都合上HTMLファイルに直接書かせていただきます。

<br><br>
以上で書き初めアプリをHTMLに実装することができました！<br>
今回はいかにリアルな筆字を再現するかに時間を費やしてしまって、webアプリケーションの実装まで解説することがありませんでしたが、ぜひ今後もProcessingで遊んでみてください！
<br><br>

最後までお付き合いいただきありがとうございました。
## 参考文献
- [Processing](https://processing.org/)
- [Processing.jsでProcessingをwebブラウザ上で動かす](https://blanche-toile.com/web/processing-cg-js-web-browser)