なでしこさんでcanvasに紙吹雪を舞わすよ！

　アドベントカレンダーもとうとう最終日です☆
　クリスマスですし！　もうすぐ正月ですし！！　いろいろめでたい！！！
　と、ゆうわけで、お祝いに紙吹雪を降らせます～＼（＾▽＾）／
　あるいは、「描画変換マトリクス設定」など、今年強化された[描画関連の命令](https://nadesi.com/v3/doc/index.php?plugin_browser%2F%E6%8F%8F%E7%94%BB&show)をお試しする話し。

# 描画を変化させる命令
　[お月様を描画](https://qiita.com/snowdrops89/items/01d75d85f7eed557335e)する時に、なでしこは円と楕円くらいしか描けないとかぼやいていましたが（ベジェ曲線みたいのが描けないとゆう意味でした）、実はなでしこの描画命令は今年、色々と強化されていて描画内容を変化させる系の命令が加わりました。

## [描画拡大](https://nadesi.com/v3/doc/index.php?plugin_browser%2F%E6%8F%8F%E7%94%BB%E6%8B%A1%E5%A4%A7&show)・[描画回転](https://nadesi.com/v3/doc/index.php?plugin_browser%2F%E6%8F%8F%E7%94%BB%E5%9B%9E%E8%BB%A2&show)・[描画起点設定](https://nadesi.com/v3/doc/index.php?plugin_browser%2F%E6%8F%8F%E7%94%BB%E8%B5%B7%E7%82%B9%E8%A8%AD%E5%AE%9A&show)

　これらについてはマニュアルにも説明とサンプルがあります。
　ふむふむ、とお試し☆

### 描画回転でお花

```
＃ひまわり
花弁色＝「rgba(250,200,0,0.5)」
花芯色＝「rgba(100,60,50,0.5)」
花弁枚数＝12

キャンバス状態保存。
#---
花弁色に塗り色設定。空に線色設定。
[150,150]に描画起点設定。
角度＝0。
花弁枚数回
    角度＝360/(花弁枚数*2)。
    角度に描画回転。
    [0,0,80,20,0,0,360をラジアン変換,0]の楕円描画。
ここまで。
花芯色に塗り色設定。
[0,0]に45の円描画。
#---
キャンバス状態復元。
[0,0]に45の円描画。# 元の位置、元の色
```

![ひまわり.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561177/715e0599-b4e3-a4f3-e7bd-b1448c112edc.png)
　画像回転で、お花が描けました～:sunflower:
　また、変化を加える前に`キャンバス状態保存`して、描画後に`キャンバス状態復元`すると、その後の描画は描画位置や色が元に戻っているのが分かります。

## 描画変換マトリクス追加・描画変換マトリクス設定
> **描画変換マトリクス設定**
> 　描画内容を[a,b,c,d,e,f]の変換マトリクスに設定。既存内容を破棄して設定(setTransform)

> **描画変換マトリクス追加**
> 　描画内容を[a,b,c,d,e,f]のマトリクスで変換。既存のマトリクスに掛け合わせる(transform)

　しか説明が無いぃ～・・・ので、じゃばすくりぷとの`transform`などで検索して、[このへん](http://www.htmq.com/canvas/transform.shtml)を参考にしたのですが・・・式の意味がいっこもわからん( ；∀；)

　しかし、分かったとこととしては、

- 図形を傾けて描画出来る。
- 引数 **[a,b,c,d,e,f]** の内容は、**[伸縮x, 傾斜y, 傾斜x, 伸縮y, 移動x, 移動y]**
- 何も変形しない場合の引数(デフォルト値)は、**[1, 0, 0, 1, 0, 0]**
- `描画拡大`・`描画回転`・`描画起点設定`をまとめて指定できる。

　とゆうこと。
　以下は全て、同じ内容ということになります。

```
[x,y]だけ描画拡大。
#　↓
[x,0,0,y,0,0]だけ描画変換マトリクス追加。
```

```
[x,y]に描画起点設定。
#　↓
[1,0,0,1,x,y]だけ描画変換マトリクス追加。
```

```
角度に描画回転。
#　↓
R角度＝角度をラジアン変換。
[COS(R角度),SIN(R角度),-SIN(R角度),COS(R角度),0,0]だけ描画変換マトリクス追加。
```

　注意点としては、描画回転では角度に普通の角度が指定出来ますが、描画変換マトリクス追加ではSINやCOSなので、ラジアン変換してやらなきゃダメでした。
　ところで、なんでこれで回転するのかって？
　さいんこさいんのじゅもんとともに、円や三角や四角を描いて、頭をひねってみるとよいでしょう（え）

### 描画変換マトリクス追加でお花

　単純に、描画回転を描画変換マトリクス追加に差し替えました。

```
＃描画変換マトリクス追加で描く
花弁色＝「rgba(250,0,150,0.5)」
花芯色＝「rgba(255,240,80,0.9)」
花弁枚数＝8。中心＝150。

キャンバス状態保存。
花弁色に塗り色設定。空に線色設定。
[中心,中心]に描画起点設定。
角度＝0。
花弁枚数回
    角度＝360/(花弁枚数*2)。
    sin＝SIN((角度をラジアン変換))。
    cos＝COS((角度をラジアン変換))。
    [cos,sin,-sin,cos,0,0]だけ描画変換マトリクス追加。
    [0,0,80,20,0,0,360をラジアン変換,0]の楕円描画。
ここまで。
花芯色に塗り色設定。
[0,0]に30の円描画。
キャンバス状態復元。
```

　画像回転の時と同様に動きました！:cherry_blossom:
　
### 描画変換マトリクス設定でお花

　では、 描画変換マトリクス設定の場合はどうかとゆうと・・・
　単純に、描画変換マトリクス**追加**を描画変換マトリクス**設定**に変えてみると、描画起点設定での設定が無視されて、起点が0に戻っちゃいました。描画変換マトリクス設定で、**e,f**に**0,0**を指定しているから、それで上書きされたんですね。
　コレが、**既存内容を破棄**とゆうことですね！
　同様に角度も、描画変換マトリクス**追加**の場合は、角度に同じ数を指定しておくだけで、それがどんどん追加されて回転していくんですが、描画変換マトリクス**設定**の場合は、角度の方をプラスして増やしていかないと、毎回同じ値が設定されてしまうので毎回同じ位置に描画されちゃう。

　で、こんな感じ？

```
＃描画変換マトリクス設定で描く
花弁色＝「rgba(100,150,250,0.5)」
花芯色＝「rgba(255,240,130,1)」
花弁枚数＝4。中心＝150。

キャンバス状態保存。
花弁色に塗り色設定。空に線色設定。
角度＝0。
花弁枚数回
    角度＝角度＋360/(花弁枚数*2)。# 角度を増やす
    sin＝SIN((角度をラジアン変換))。
    cos＝COS((角度をラジアン変換))。
    [cos,sin,-sin,cos,中心,中心]だけ描画変換マトリクス設定。# 起点もここで設定
    [0,0,80,20,0,0,360をラジアン変換,0]の楕円描画。
ここまで。
花芯色に塗り色設定。
[0,0]に30の円描画。
キャンバス状態復元。
```

　できました！:blossom:

### 傾斜
　他の命令で出来ることだけ出来ても面白くありません。
　図形を傾けてみます☆

```
幅＝50。高＝50。
空に線色設定。

キャンバス状態保存。
#---
伸縮ｘ＝1。傾斜ｙ＝0。傾斜ｘ＝0。伸縮ｙ＝1。起点ｘ＝0。起点ｙ＝0。　# デフォルト値
赤色に塗り色設定。
[伸縮ｘ,傾斜ｙ,傾斜ｘ,伸縮ｙ,起点ｘ,起点ｙ]だけ描画変換マトリクス設定。
[0,0,幅,高]へ四角描画。

起点ｘ＝50。起点ｙ＝50。
青色に塗り色設定。空に線色設定。
傾斜ｙ＝1。傾斜ｘ＝0。　# 垂直方向に傾ける
[伸縮ｘ,傾斜ｙ,傾斜ｘ,伸縮ｙ,起点ｘ,起点ｙ]だけ描画変換マトリクス設定。
[0,0,幅,高]へ四角描画。

緑色に塗り色設定。空に線色設定。
傾斜ｙ＝0。傾斜ｘ＝1。　# 水平方向に傾ける
[伸縮ｘ,傾斜ｙ,傾斜ｘ,伸縮ｙ,起点ｘ,起点ｙ]だけ描画変換マトリクス設定。
[0,0,幅,高]へ四角描画。
#---
キャンバス状態復元。
```
![傾斜.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561177/714b8dd9-3aa8-f234-28f2-6e10a2f996e7.png)
　赤はデフォルト値なので、普通に`[0,0,幅,高]に四角描画。`とやったのと同じことです。
　青は垂直方向、緑は水平方向への傾斜です。
　傾斜ｙを設定すると図形の右端が上下に、傾斜ｘを指定すると図形の下側が左右に傾くのが分かります。

# とりあえず１枚だけひらひらさせる

　とゆうわけで！　お勉強終了。やっと紙吹雪☆
　この、傾けたり回転させたりっていうのを組み合わせて、紙がひらひらしている風味にするんですよね。

## 基本の描画
```
紙片幅＝50。紙片高＝50。表示色＝金色。
起点ｘ＝150。起点ｙ＝150。
伸縮ｘ＝1。傾斜ｙ＝0。傾斜ｘ＝0。伸縮ｙ＝1。

「紙吹雪」を画面更新時実行。
●紙吹雪
    全描画クリア。

    ＃ここを変更してひらひらさせる
    伸縮ｘ＝1。傾斜ｙ＝0。傾斜ｘ＝0。伸縮ｙ＝1。
    描画ｘ＝0。描画ｙ＝0。

    キャンバス状態保存。
    #---
    表示色に塗り色設定。空に線色設定。
    [伸縮ｘ,傾斜ｙ,傾斜ｘ,伸縮ｙ,起点ｘ,起点ｙ]だけ描画変換マトリクス設定。
    [描画ｘ,描画ｙ,紙片幅,紙片高]へ四角描画。
    #---
    キャンバス状態復元。
    「紙吹雪」を画面更新時実行。
ここまで。
```

　これは全部デフォルト値固定で価を変化させていないので、ただ四角い紙（？）が表示されるだけですが、実際には`画面更新時実行`により繰り返し描画しています。
　傾斜や伸縮、描画位置などを変更して、いろいろお試しする。
　紙が落ちる時って、あんまりくるくる回転したりはせず、左右に振れる感じだと思うんだよね。

## 降らせる

　まだ変化の余地はあるかもですが、とりあえずこんな感じ？　となったので、上から下へ舞い落ちるようにします。
　起点ｙを加算していくだけですが、画面の下に到達したら０に戻して、再び上から降ってくるようにします。
　左右にもちょっと流れるようにしました。

```
キャンバス幅＝300。キャンバス高さ＝300。
紙片幅＝50。紙片高＝50。表示色＝金色。
起点ｘ＝150。起点ｙ＝0。
伸縮ｘ＝1。傾斜ｙ＝0。傾斜ｘ＝0。伸縮ｙ＝1。
角度＝0。角度加算＝5。
落下速度＝1。風力＝0.5。

「紙吹雪」を画面更新時実行。
●紙吹雪
    全描画クリア。

    起点ｘ＝起点ｘ＋風力。
    起点ｙ＝起点ｙ＋落下速度。
    角度＝角度＋角度加算。
    sin＝SIN((角度をラジアン変換))。
    cos＝COS((角度をラジアン変換))。

    伸縮ｘ＝0.3。傾斜ｙ＝cos。傾斜ｘ＝sin。伸縮ｙ＝0.1。
    描画ｘ＝-1*紙片幅/2。描画ｙ＝-1*紙片幅。
    #---
    キャンバス状態保存。
    表示色に塗り色設定。空に線色設定。
    [伸縮ｘ,傾斜ｙ,傾斜ｘ,伸縮ｙ,起点ｘ,起点ｙ]だけ描画変換マトリクス設定。
    [描画ｘ,描画ｙ,紙片幅,紙片高]へ四角描画。
    キャンバス状態復元。
    #---
    もし、起点ｙ＞キャンバス高さならば、起点ｙ＝０。
    もし、起点ｘ＞キャンバス幅ならば、起点ｘ＝０。
    もし、起点ｘ＜０ならば、起点ｘ＝キャンバス幅。
    「紙吹雪」を画面更新時実行。
ここまで。
```

　降っています！　少なくともワタシにはひらひらして見えます☆

# いっぱい舞わせる！
　起点を変えて、いっぱい描画してやればいいんですが、全部同じ大きさ、同じ動きではアレなので、紙片の枚数分だけデータを作って、それを反復するようにします。

```
変数 紙片データ＝空配列。
変数 [紙片枚数,最大紙片幅,最小紙片幅]＝[45,12,6]
変数 [最大落下速度,最小落下速度]＝[30,20]
変数 [最大風速,最小風速]＝[0.5,-0.5]
変数 [最大角度加算,最小角度加算]＝[15,5]
変数 紙色配列＝["#ff3333","#ff6699","#ff6600","#ffcc00","#ffff66","#99ff66","#33ffff","#33ccff","#9966ff","#ff66ff","#cccccc"]

＃紙片を作成
紙片データ作成。
●紙片データ作成
    紙片データ＝空配列。
    紙片枚数回
        紙片幅＝最小紙片幅＋(最大紙片幅-最小紙片幅+1の乱数)。
        紙片高＝紙片幅。
        表示色＝紙色配列[(紙色配列の要素数)の乱数]。
        起点ｘ＝キャンバス幅
        起点ｙ＝キャンバス高さの乱数。
        落下速度＝(最小落下速度＋(最大落下速度-最小落下速度+1の乱数))/10。
        角度＝360の乱数。
        風力＝(最小風速＋(最大風速-最小風速+1の乱数))
        紙片データ[回数-1]＝{"幅": 紙片幅, "高": 紙片高, "ｘ":起点ｘ, "ｙ":起点ｙ, "色":表示色, "落下速度": 落下速度, "角度":角度, "風力":風力}
    ここまで。
ここまで。
```

　こんな感じ？
　各設定項目に最大値と最小値を設定して、その範囲内でランダムに・・・なるようにしたつもり。
　あってる？？
　あとは、これを「紙吹雪」関数の中で反復して全部描画するだけです！

# 動作確認
　できました！

https://n3s.nadesi.com/id.php?880

　本当は、各パラメーターを変更して遊べるようにしたりしたかったけど、時間切れ。ってゆうか、わりと力尽きました；　ひらひらを眺めすぎて、目がチカチカする・・・（＊＿＊）

# おわります
　今年もおかげさまで何とかカレンダーを全部埋めることが出来ました☆
　書いて下さった方も、読んで下さった方も、ありがとうございました！！！