piano.js

piano.jsはhtml内に再生可能なピアノを埋め込むJavaScriptライブラリです。

github markgithub リンク

プレビュー

コード表示が崩れてしまう場合があります。その場合はページを再読み込みしてください。
ご迷惑をお掛けしておりますことをお詫び申し上げます。

2オクターブ分の通常のピアノ / C-コードをハイライト / 音名をGフリジアンとして表示

<div class="piano" data-first="60" data-last="84" data-key-width="20px" data-key-height="60px" data-highlight="72 75 79" data-highlight-color="#FFE0FF" data-notename="true" data-key-signature="G phr"></div>

Aから2オクターブ分の通常のピアノ / FをGダブルフラットとして、AをGダブルシャープとして表示

<div class="piano" data-first="57" data-last="81" data-key-width="30px" data-key-height="70px" data-custom-notename="65 Gbb, 69 Gx"></div>

ホバーアニメーションのあるピアノ / EとF#をハイライト

<div class="piano-hover" data-first="48" data-last="60" data-highlight="52 54" data-highlight-color="rgb(223,255,255)"></div>

マウスクリックで三角波を再生するピアノ

<div class="piano-play" data-first="36" data-last="67" data-key-width="30px" data-key-height="90px"></div>

通常のピアノ / 下のボタンでハイライトされたC-13コードを再生 / 音名をFドリアンとして表示

<div id="piano1" class="piano" data-first="48" data-last="72" data-key-width="30px" data-key-height="120px" data-highlight="48 51 55 58 62 65 69" data-highlight-color="#FFFF00" data-notename="true" data-key-signature="C dor"></div>

マウスクリックでのこぎり波を再生する非常に広いピアノ / 下のボタンで巨大なコードや音楽を再生 / A4=432Hzチューニング / 音名をCミクソリディアンとして表示

<div id="piano2" class="piano-play" data-first="24" data-last="96" data-key-width="14px" data-key-height="60px" data-notename="true" data-key-signature="C mix" data-volume="0.2" data-duration="4" data-osc-type="sawtooth" data-tuning="432"></div>

様々な再生ボタン

つかいかた

呼び出し

  1. JavaScriptの読み込み

    基本の機能はpiano.jsのみを読み込むことで利用可能です。
    defer属性を付与する必要があることに注意してください。

    ダウンロードして読み込み

    以下のリンクから該当バージョンを選択し、内部のpiano.jsをダウンロード
    https://github.com/oignonasappy/pianojs/

    github.ioからの読み込み(疑似CDN)

    以下コードを<head>内にコピー [version : v1.2.1]
    <script src="https://oignonasappy.github.io/pianojs/v1.2.1/piano.js" defer></script>

  2. <div>を配置

    記述例:

    • <div class="piano" data-first="48" data-last="60"></div>
    • <div class="piano-hover" data-first="21" data-last="108" data-key-width="10px" data-key-height="40px" data-highlight="46 50 57" data-highlight-color="#A0FFA0" data-notename="true" data-key-signature="G min" data-custom-notename="46 I, 50 III, 57 VII"></div>
    • <div class="piano-play" data-first="28" data-last="103" data-key-width="16px" data-key-height="60px" data-highlight="40 45 50 55 59 64" data-highlight-color="rgb(128,128,255)" data-notename="true" data-key-signature="e AEO" data-custom-notename="40 6, 45 5, 50 4, 55 3, 59 2, 64 1" data-volume="0.35" data-duration="2.5" data-osc-type="sine" data-tuning="427.474"></div>

    種類

    • .piano

      もっとも基本のピアノです。

    • .piano-hover

      .pianoの機能に追加で、 マウスカーソルに反応するアニメーションを追加します。

    • .piano-play

      .piano-hoverの機能に追加で、 マウスでクリックすることで音を鳴らすことができます。
      残念ながらスマホ上では弾けないこともないですが、非常に不自由です。

APIリファレンス

データ属性

<div>内に data-*=""の形でピアノに属性を設定します。

  1. data-first, data-last

    • data-first: <integer> = 0 <= x
    • data-last: <integer> = data-first <= x
    • 記述例 : data-first="48" data-last="79"
    • data-first既定 : 60
    • data-last既定 : data-first+12

    midi midi番号で指定する、表示する鍵盤の範囲です。
    0以上の整数であり、data-lastはdata-first以上である必要があります。
    data-lastはそれ自身の値も含みます(要するに"以下")

  2. data-key-width, data-key-height

    • data-key-width: <length> = 0 < x
    • data-key-height: <length> = 0 < x
    • 記述例 : data-key-width="30px" data-key-height="120px"
    • data-key-width既定 : 20px
    • data-key-height : 60px

    白鍵一つあたりのサイズです。
    30pxなど、CSSで使用可能な構文で設定できます。
    黒鍵のサイズは横幅0.7倍,縦幅0.6倍となります。
    ピアノ全体のサイズから設定することはできません。ゴメン<(_ _)>

  3. data-highlight

    • data-highlight: <integer[*]> = [data-first <= x <= data-last]*
    • 記述例 : data-highlight="59 63 69"
    • 既定 : なし

    指定した鍵盤を色付けして強調します。
    ハイライトする鍵盤のmidi番号をスペース区切りで指定します。
    data-first, data-lastで設定した範囲内でないとハイライトされません。 (後述するplayHighlighted()では機能します)

  4. data-highlight-color

    • data-highlight-color: <color> = x
    • 記述例 : data-highlight-color="#C0FFC0"
    • 既定 : #FFE0E0

    ※このデータ属性はdata-highlightが設定されているときのみ機能します。
    data-highlightで設定したハイライトする鍵盤の色を設定します。
    #E0FFFFrgb(191,191,255)など、 CSSで使用可能な構文で設定できます。

  5. data-notename

    • data-notename: <boolean> = "true" | "false"
    • 記述例 : data-notename="true"
    • 既定 : false

    鍵盤に音名ラベルを表示します。
    trueに設定すると表示します。
    黒鍵の臨時記号デフォルトで'#'で表します。

  6. data-key-signature

    • data-key-signature: <string[2]> = (C ~ B) (lyd ~ loc)
    • 記述例 : data-key-signature="F Phr"
    • 既定 : C Maj

    ※このデータ属性はdata-notename="true"のときのみ機能します。
    教会旋法七つの正格旋法のみに基づいた調号を付与します。
    音名・モードを半角スペースで区切ります。大文字、小文字の区別はありません。
    音名には臨時記号を含めることができます。シャープは'#'で表し、フラットは'b'で表します。 ここに含まれない臨時記号は使用することができません。
    モードはモード名の頭三文字の表記 [Lyd, Ion(Maj), Mix, Dor, Aeo(Min), Phr, Loc]の中から選択します。 ここに含まれないスケールdata-custom-notenameから手動で設定してください。
    調号が6個つく「bと#が切り替わる地点」(例えば、変ト長調嬰ヘ長調)の場合 bが6個の表記を採用します。(つまり、BはCbとして表記します。)

  7. data-custom-notename

    • data-: <integer, string>[*] = [(data-first <= x <= data-last) (string)]*
    • 記述例 : data-custom-notename="66 F#, 70 Bb"
    • 既定 : なし

    鍵盤上に任意のラベルを表示します。
    midi番号 文字列のように2つセットで記述し、 それぞれを半角スペースで区切ります。複数設定する際はカンマ区切りで記述します。

  8. data-volume ※再生用

    • data-volume: <number> = 0.0 < x (<= 1.0)
    • 記述例 : data-volume="0.25"
    • 既定 : 0.25

    音量・振幅です。
    0.0以上1.0以下の小数で設定します。もし1.0以上の値に設定すると、音が歪みディストーションになります。後悔しても知りません。
    入力は対数スケールに変換され、線形な音量変化になります。
    とても音が大きい場合があります! 必ず小さい音量からお試しください。耳を痛めないように

  9. data-duration ※再生用

    • data-duration: <number> = 0.0 < x
    • 記述例 : data-duration="1.5"
    • 既定 : 2

    音がフェードアウトし消えるまでの時間を秒単位で指定します。

  10. data-osc-type ※再生用

    • data-osc-type: <string> = sine | triangle | square | sawtooth
    • 記述例 : data-osc-type="square"
    • 既定 : triangle

    再生する音の波形を指定します。
    [sine, triangle, square, sawtooth]の中から選択します。
    詳しくはOscillatorNode ドキュメント参照してください。

  11. data-tuning ※再生用

    • data-tuning: <number> = 0.0 < x
    • 記述例 : data-tuning="427.474"
    • 既定 : 440

    基本周波数を設定します。
    既定はA4=440Hzです。
    私得である。

JavaScriptメソッド

  1. playNote()

    単一の音を再生します。
    特定のピアノと紐付ける必要はありません。

    引数
    midi
    {number}
    再生するmidi番号です。実は小数も指定することができます。これにより微分音を再生することが可能です。
    volume
    {number} 既定=0.25
    data-volume同等です。
    duration
    {number} 既定=2
    data-duration同等です。
    oscType
    {string} 既定="triangle"
    data-osc-type同等です。
    tuning
    {number} 既定=440
    data-tuning同等です。

    デフォルトを呼び出す際は引数にundefinedを設定します。

    記述例
    
                                    playNote(60, 0.2, 1.5, "square", 442);
                                
  2. playNoteAll()

    第一引数midiArrayに設定した 全てのmidi番号でplayNote()を実行します。

    引数
    midiArray
    {Array}
    再生するmidi番号を列挙した配列です。
    volume
    {number} 既定=0.25
    data-volume同等です。
    duration
    {number} 既定=2
    data-duration同等です。
    oscType
    {string} 既定="triangle"
    data-osc-type同等です。
    tuning
    {number} 既定=440
    data-tuning同等です。
    記述例
    
                                    playNoteAll([60, 65, 69], 0.18, 3, "triangle", 415);
                                
  3. playKeys()

    ピアノに設定されているパラメータで音を再生します。
    ピアノの<div>内に設定した id=""で再生するピアノを選択します。
    以下これらの属性に設定されている値を使用します。

    1. data-volume
    2. data-duration
    3. data-osc-type
    4. data-tuning
    引数
    id
    {string}
    紐づけるピアノのidです。
    midiArray
    {Array}
    再生する鍵盤(midi番号)を列挙した配列です。
    記述例
    
                                    playKeys("piano-alpha", [65, 69, 72, 76]);
                                
  4. playHighlighted()

    data-highlightに設定されている鍵盤で playkeys()を実行します。

    引数
    id
    {string}
    紐づけるピアノのidです。
    記述例
    
                                    playHighLighted("piano-bravo");
                                
  5. sequencer()

    タイミング(リズム)に合わせてコールバック関数を実行します。
    この関数は、valuesの値で 引数の関数をsequenceの分だけ遅延させて実行する関数です。
    本piano.jsのplayKeys()等と併用すると効果的でしょう。

    sequencevalues 要素数は一致、もしくはsequence.length - 1 === values.length である必要があります。
    seqIdが設定されている状態では、 sequenceの最後の値 sequence[values.length - 1]は再生が終了してから 再び呼び出しが可能になるまでの時間を表します。

    引数
    callback
    {Function}
    指定されたタイミングに呼び出される関数です。ラムダ推奨
    sequence
    {number}
    次の関数呼び出しの際に待機させる秒数です。
    values
    {Array}
    callbackに渡す任意の値をもつ配列です。
    bpm
    {number} 既定=240
    sequenceに設定されている値の1を全音符、1/4を1拍とした時のBPMです。
    seqId
    {any} 既定=undefined
    同一Idの処理をロックします。未設定の場合はロックしません。
    記述例 (PLAY SONGボタン)
    
                                    sequencer(
                                        (value) => {
                                            playKeys('piano2', value);
                                        },
                                        [1/8, 1/8, 1/8, 1/8, 1/8, 1/8, 1/8+0.01, 1/8+0.02, 1/8+0.03, 1/8+0.025, 1/8+0.02, 1/8+0.016, 1/8+0.012, 1/8+0.008, 1/8+0.004, 1/8, 3/8, 1/24, 1/24, 1/24, 0],
                                        [[89,48,52,55],[88],[86],[84],[82,53,57,60],[81],[79],[77],[76,40,45,50,55],[74],[84,44,48,51],[82],[80],[78],[77,49,53,56],[75],[77,41,48,52,57],[29],[36],[43],[50]],
                                        120, 'piano2'
                                    )
                                

その他

ピアノ全体に対してスタイリングする時は、 .piano-wrapperに対して行うことを推奨します。 (このクラスはピアノ全体をラップしています)
margin: autoなどを設定する際に適しています。

感想

要件定義は大事ですね。
今回、何もかも思いつきで機能を追加していったので、ソースコードにまとまりがなくなってしまいました。今は多少改善していますが...

このブログで記事を書いていくにあたって、音楽についての解説をするとき、どうするか。
きっと、目で見て分かる形で解説できた方がずっといい。
そう思って、此れを作るに至ったのですね。
このブログの一番目の記事にふさわしい内容にはなったかな?

非効率だと分かっていながら、cssもhoverも何もかも一つのJavaScriptで実装しました。
なぜかと言えばこのpiano.jsを使用するとき、このJavaScriptをただ一つだけ呼び出せばよくなるから。ホントにただそれだけです。

以下、piano.jsソースコードです。[version : v1.2.1]
このページは当ブログでもっとも古い記事です。