SVGでクリックすると音の出るピアノを作る

### 作ったもの
- GitHub Pages
https://perzikanz.github.io/play-audio/
- Repository
https://github.com/perzikanz/play-audio

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721983/cc135a4d-ef89-b529-9df2-1fd82f79e2ff.png)


### やること
- 鍵盤のsvgを作る
- 音源を作る
- クリックすると音が鳴るようにする

## 鍵盤のSVGを作る
Inkscapeを使ってSVGを作ります。1つのキーを1つの`<path>`で描き、その音階と同じ`id`を振ります。`id`はオブジェクトのプロパティから編集できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721983/c3ab0856-85af-d152-1394-3776225f56f6.png)

ドの音にあたる位置にはC0～7のキーを書きます。どこのドなのか分かりやすくするためです。

出来上がったらプレーンSVGで保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721983/e8c0e299-0e57-cbcc-3035-4ea1145281e1.png)

保存したSVGをテキストエディタで開くとこのようになってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721983/49003beb-18f1-65c4-dac2-d94c6a9e5c3c.png)

`<svg>`タグの中身をHTML内にコピー＆ペーストします。
`<path>`には`fill`や`stroke`を指定するための`style`が付いていますが、`style`はcssで指定したいので削除し、代わりに`class`をつけます。


```html:index.html
<svg>
    <path d="M 50,25 v 405 h 80 v -180 h -30 v -225 Z" id="c0" class="white" />
    <path  d="M 100,25 v 225 h 50 v -225 Z" id="cs0" class="black" />
    .
    .
    .
    <path d="M 3970,25 v 405 h 80 v -405 Z" id="c7" class="white" />
    <text x="3988" y="400" class="text">C7</text>
</svg>
```

（実は初めてのInkscapeだったので上手く作れず、線がガタガタになって見た目が悪かったので、テキストエディタで`path`を全て書き直して綺麗に整えました）


### CSSでスタイルを指定
SVGでは塗りつぶしは`fill`、線は`stroke`で指定します。
`hover`は普通のCSSと同じように指定できます。

キーが分かるように書いた`text`は、そのままでは鍵盤をクリックする邪魔になるので、`pointer-events`を`none`に指定し、クリックやホバーなどのポインターイベントの対象にならないようにします。
更に`user-select`を`none`に指定し文字を選択できないようにします。


```css:piano.css
.white {
  fill: #fff;
  stroke: #000;
  stroke-width: 1px;
  stroke-linecap: butt;
  stroke-linejoin: miter;
}

.white:hover {
  fill: #ccc;
}

.black {
  fill: #000;
  stroke: #000;
  stroke-width: 1px;
  stroke-linecap: butt;
  stroke-linejoin: miter;
}

.black:hover {
  fill: #222;
}

.text {
  fill: #444;
  font-size: 30px;
  font-weight: bold;
  pointer-events: none;
  user-select: none;
}
```



## 音源を作る
たまたまインストールされていたStudio Oneと、KEYSCAPEの音源を使ってピアノ音源を作りました。
ピアノを１音ずつ鳴らしたものを、mp3で書き出します。ファイル名は鍵盤の`id`と同じ音階にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721983/e8bb1b55-ba50-afaa-f67c-517a95d6c5d6.png)

## クリックで音を鳴らす
JavaScriptで鍵盤をクリックしたら音が鳴るようにします。
JavaScriptで音声を扱うには`Audio`クラスを使います。引数には音声ファイルのパスを指定します。

```js:play.js
const path = document.querySelectorAll('path');

for (let i = 0, l = path.length; l > i; i++) {
  const file = path[i].getAttribute('id');
  const src = `./src/audio/${file}.mp3`;
  const audio = new Audio(src);

  path[i].addEventListener('mousedown', () => {
    audio.currentTime = 0;
    audio.play();
  });
}
```
`querySelectAll`で全ての`<path>`を取得します。

そこから`getAttribute`で取得した`id`をファイル名としてパスを指定し、`Audio`インスタンスを作成します。

`.play()`で再生できますが、そのままだと連打しても1つの音の再生が終わるまで他の音を再生してくれないので、よりピアノっぽくする為に、巻き戻してから再生するようにします。再生位置を決める`currentTime`に、`0`をセットするだけです。

## 参考にしたページ
- [HTML5 SVG + CSS + JS で柔軟なマウス領域を実現 - Qiita](https://qiita.com/ueokande/items/a39277b72b7c6d61162b)
- [Paths - SVG: Scalable Vector Graphics | MDN](https://developer.mozilla.org/ja/docs/Web/SVG/Tutorial/Paths)
- [[HTML5] 音声ファイルをJSで再生/停止する – audioタグ編](https://blog.katsubemakito.net/html5/audio1)
- [クリックすると音が鳴るボタンの作り方](https://syncer.jp/html5-javascript-hello-button)