「TAURI」で「ピアノ音楽」アプリを作ろう

2024年1月16日(火)
大西 武 (オオニシ タケシ)
第8回の今回は、「TAURI」でピアノのUIを演奏するとピアノのサウンドが鳴るデスクトップアプリを開発していきます。

起動時のサウンド再生を停止する

次のように「src-tauri」→「src」→「main.rs」をコーディングし、前述の起動時に音を鳴らすようにしたコードを削除します。これを削除し忘れると、毎回起動時にドのサウンドが鳴ってしまうので必ず削除してください。

前述したときは音を鳴らすテストをしたかっただけなので、ここではピアノの鍵盤のクリックに合わせてピアノ音を鳴らせるように変更します。

・「src-tauri」→「src」→「main.rs」のサンプルコード
(前略)
fn main() {
(中略)
  //デスクトップアプリのセットアップ
  tauri::Builder::default()
  .setup(|app| {
    let snd = sound::Sound::new(app,files);
//    snd.play(0);  削除
    app.manage(snd);
    Ok(())
  })
  .invoke_handler(tauri::generate_handler![playpiano])
  .run(tauri::generate_context!())
  .expect("error while running tauri application");
}

【サンプルコードの解説】
アプリ起動時のサウンド再生「snd.play(0);」を削除します。

ピアノの鍵盤をデザインする

ここまでの連載でもうお分かりでしょうが、TAURIのインターフェースはWebページをデザインして作ります。そのため「index.html」ファイルをWebブラウザで開いてWebページだけ見ても、どのようなものが作れるか分かるはずです。

そこで、次の「index.html」「main.js」「styles.css」のコードを書いて、ひとまずWebブラウザで表示してみましょう! …と言いたいところですが、実行エラーで何も表示されません。そこで、いったんJavaScriptからTAURIの部分のコードを削除してWebブラウザで開いてみると、図6のようにピアノのWebページが表示されます(このようなことはすべきではないのですが…)。

図6:無理やりJavaScriptをWebブラウザ用に書き換えて実行

HTMLファイルのデザイン

次のように「src」→「index.html」をコーディングし、デフォルトのWebページの「body」タグ内のコードを削除して「#piano」セレクタのdivタグだけ作ります。このdivタグに白鍵と黒鍵のピアノの鍵盤のdivタグをJavaScriptから挿入します。

もちろん手入力で白鍵と黒鍵を12×3オクターブ配置しても良いのですが、JavaScriptで作った方が効率的なので、今回はJavaScriptから鍵盤を作ります。余談ですが、TAURIで作成したWebページはGoogle検索の対象にならないので関係ありませんが、Web公開する場合はHTMLファイルに手入力した方がSEO対策効果は高いと思います。

・「src」→「index.html」のサンプルコード
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="styles.css" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Tauri App</title>
  </head>

  <body>
    <div id="piano"></div>

    <script type="module" src="main.js" defer></script>
  </body>
</html>

【サンプルコードの解説】
「id」が「piano」のdivタグだけコーディングします。これを「#piano」セレクタと呼びます。

JavaScriptをコーディング

次のように「src」→「main.js」ファイルをコーディングし、DOMが全て読み込み完了したら1回だけ12×3オクターブの鍵盤のdivタグを挿入して、それぞれの鍵盤がクリックされたときに「playPiano」関数を呼び出すようにセットします。

鍵盤の番号はまず0~20以下までが白鍵のド3~シ5以下までで、21~35以下までが黒鍵のレ♭3~シ♭5以下までのインデックス番号に対応します。

・「src」→「main.js」サンプルコード
const { invoke } = window.__TAURI__.tauri;
//ピアノの再生
async function playPiano(index) {
  await invoke("playpiano", { note: index });
}
//DOMが全て読み込み完了したとき
window.addEventListener("DOMContentLoaded", () => {
  const piano = document.querySelector('#piano');
  const WHITE_KEY = 7*3;
  //白鍵のタグの追加
  for ( var i = 0; i < WHITE_KEY; i++ ) {
    piano.insertAdjacentHTML(
      'beforeend',
      '<div class="white"><a> </a>&lt/div>');
  }
  //黒鍵のタグの追加
  for ( var i = 0; i < WHITE_KEY; i++ ) {
    if ( !((i+4) % 7) || !(i % 7) ) continue;
    let style = '"margin-left:'+(30*i-640)+'px"';
    piano.insertAdjacentHTML(
      'beforeend',
      '<div class="black" style='+style+'><a> </a></div>');
  }
  //白鍵がクリックされた時のイベントリスナー
  let white = document.querySelectorAll('.white a');
  white.forEach(function(a,index) {
    a.addEventListener("click", () => playPiano(index));
  });
  //黒鍵がクリックされた時のイベントリスナー
  let black = document.querySelectorAll('.black a');
  black.forEach(function(a,index) {
    a.addEventListener("click", () => playPiano(WHITE_KEY+index));
  });
});

【サンプルコードの解説】
playPiano関数でフロントエンドのJavaScriptからバックエンドのRustに"playpiano"メッセージを鍵盤のインデックス番号(index引数)とともに送り、TAURIコマンドの「playpiano」関数を実行させます。
DOMが全て読み込まれたら(DOMContentLoaded)、#pianoセレクタに白鍵(「.white」セレクタ)と黒鍵(「.black」セレクタ)のdivタグを追加(「insertAdjacentHTML」メソッド)します。「querySelectorAll」メソッドで全ての.whiteセレクタを「white」配列に、.blackセレクタを「black」配列に取得します。それぞれの配列の要素が1つずつ(forEach文)クリック(click)されたら、playPiano関数に鍵盤のインデックス番号を引数に渡して呼び出すようにイベントリスナーを登録(「addEventListener」メソッド)します。

CSSのスタイルシート

CSSは装飾だけで、見た目以外はあまり関係しないように書いてきましたが、鍵盤の形を作るためにはCSSがないと何も表示されず(図7)、白鍵も黒鍵もクリックできません。

そこで、次のように「src」→「styles.css」ファイルをコーディングしたら、ターミナルで「$ cargo-tauri dev」コマンドを実行してみてください。ピアノの鍵盤が表示され、鍵盤をマウスクリックすると正しい音が再生されましたね。この際「src-tauri」→「target」→「debug」フォルダに、冒頭でTAURIに設定したリソースのA3.oggファイルなどが入ったsoundsフォルダがコピーされます。

図7:Webページに何もないpianoアプリ

・「src」→「styles.css」サンプルコード
div#piano {
  width: 630px;
  margin: 0 auto;
}
div.white,
div.black {
  float: left;
}
div.white a {
  display: block;
  border: solid 1px #000;
  background-color: #fff;
  width: 28px;
  height: 200px;
}
div.black a {
  display: block;
  border: solid 1px #000;
  background-color: #000;
  width: 18px;
  height: 130px;
}
div.white a:hover,
div.black a:hover {
  background-color: #999;
}

【サンプルコードの解説】
全ての鍵盤が収まる#pianoセレクタを中央に配置します。
.whiteセレクタと.blackセレクタをできるだけ改行せずに左寄せに並べて配置します。
.whiteセレクタの中の「a」セレクタを白鍵のデザインにします。
.blackセレクタの中のaセレクタを黒鍵のデザインにします。
.whiteセレクタと.blackセレクタの中の「a」セレクタがマウスオーバーしたらグレーの鍵盤に色を変えます。

おわりに

完成したら、ターミナルから「$ cargo-tauri build」コマンドでリリースビルドしてインストーラを作成し、「src-tauri」→「target」→「release」→「bundle」→「msi」のインストーラを実行してみてください。一緒にサウンドファイルも同梱され、ピアノの鍵盤をクリックすると音が鳴りましたね。

今回はTAURIの使い方として、バックエンドのRust側で「State」変数を共有できる機能を使いました。また、デバッグ時やインストーラにリソースファイルを同梱する設定方法も解説しました。

著者
大西 武 (オオニシ タケシ)
1975年香川県生まれ。大阪大学経済学部経営学科中退。プログラミング入門書など30冊以上を商業出版。Microsoftで大賞やNTTドコモでグランプリなど20回以上全国区のコンテストに入賞。オリジナルの間違い探し「3Dクイズ」が全国放送のTVで約10回出題。

連載バックナンバー

開発言語技術解説
第14回

「TAURI」で気象庁の「CSVデータ」を解析する

2024/5/1
第14回の今回は気象庁のWebサイトから指定した地域の1年間の気象データをダウンロードして「TAURI」で解析していきます。
開発言語技術解説
第13回

「TAURI」で「簡易RSSリーダー」を開発してみよう

2024/4/16
第13回の今回は「TAURI」で「RSSフィード」を読み込んでWebページに一覧表示し、リンクのページを開くための新規ウィンドウを作成するところまでを解説します。
開発言語技術解説
第12回

「TAURI」でExcelのデータを読み書きしてWebページに表示してみよう

2024/4/2
第12回の今回は「TAURI」で「Rust」の「umya-spreadsheet」クレートを使って「Excel」の「xlsx」ファイルを読み書きし、Webページに表示するところまでを解説します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています