html Javascript プログラミング 楽器

コード譜や歌詞サイトを曲に合った速度で自動スクロールさせるブックマークレット

 

コード譜&歌詞サイトを自動スクロールさせたい

昔から多少なりとも音楽をやってきた人間からすると、今はほんとうに夢のような時代です。

音源はYoutubeやサブスク、ダウンロードですぐに手に入りますし、楽器で引いてみたいという時にも、検索すれば大抵の曲の歌詞やコード譜、譜面が手に入ります。

歌詞+コード譜を掲載しているサイトはたくさんあり、ほとんどは無料利用できます。

完コピではなくてもちょっと演奏してみる分には、譜面よりも歌詞の上にコードが書いてあるくらいのが使いやすいです。

ただ、コード譜がウインドウの中に収まっている時はよいのですが、そんな短い曲は滅多になく、たいていは演奏の途中でマウスに手を伸ばしてスクロールする必要があります。

演奏中にこれをやるのは結構大変なんですよね。

コード譜サイトによっては、自動スクロール機能が実装されていたりするのですが、曲の長さにあったスクロール速度を見つけるのがこれまたちょっと難しかったりします。

ないなら作ろうというわけで、書いたのが今回のブックマークレットです。

ブックマークレットなので、コード譜のページ上でブックマークから呼び出すとそのページで自動スクロール機能が使えるようになります。

 

スクロール開始点、終了点、曲の長さを設定

このブックマークレットでは、コード譜のページ上でショートカットキーを使ってスクロール開始場所、終了場所、曲の長さを指定します。

スタートすると設定した時間をかけて開始場所から終了場所まで自動的にスクロールします。

ショートカットキーは以下の通りです。

A 現在の表示位置を自動スクロール開始位置に設定
B 現在の表示位置を自動スクロール終了位置に設定
T 曲の長さを指定するダイアログを表示。分と秒を"3 15"のように半角スペースで区切って入力
S 自動スクロールを開始。スクロール時に何かキーを押すと止まる。

 

使い方はデモページで試していただければ分かると思います。

デモページ(github pages)

ソースコード(github)

 

機能的には音楽に特化しているわけではないので、たとえば朗読とかプレゼンのペースメーカーとしても使えます。

ただ、プレゼンやスピーチ用の時間管理アプリはすでにあるんですよね。

これはあくまで既存のWebページを自動スクロールさせるためのブックマークレットです。

 

setIntervalで自動スクロール。呼び出す頻度で速度を調整

自動スクロールはsetIntervalに設定した関数内でwindow.scrollBy()メソッドを呼ぶことで実現しています。

window.scrollByは現在の表示位置からの相対的なスクロール量を指定できるのでこうした用途にはぴったりです。

一回のスクロール量は一定で、スクロールの頻度(setIntervalのinterval)で速度を調節しています。

頻度は「曲の長さ/移動距離」で計算しています。

最初は一回の移動距離を1ピクセルにしていたのですが、これだと画面のスクロールが曲に遅れてしまいました。

私の環境では2ピクセルでうまく動いています。自分の環境に合わせて適宜変更してください。

個人的にはとても役に立っています。いろんな曲を弾いてみるのが楽しくなりました。

 

元のソースコード

autoscroll = '';//某サイトの自動スクロール機能を無効にする。ブックマークレットとして使う時のみ有効にする
const AUTOSCROLL_STEP = 2;//1回のスクロール幅。処理が間に合わない時はこれを大きくする
var autoScroll_start = 0;
var elm = document.documentElement;
var autoScroll_end = elm.scrollHeight - elm.clientHeight;;
var autoScroll_time = 30;
var autoScroll_lastScrollPosition = 0;
let isTimerOn = false;//自動スクロールを実行中かどうかのフラグ
var autoScrollTimer;
window.addEventListener('keydown', function (event) {
  if (isTimerOn) {
    console.log('timer cleared');
    clearInterval(autoScrollTimer);//自動スクロール中に何かキーが押されたら止める
    isTimerOn = false;
    return;
  }
  console.log(event.code);
  switch (event.code) {
    case 'KeyA'://先頭位置を設定
      autoScroll_start = window.pageYOffset;
      break;
    case 'KeyB'://最終位置を設定
      autoScroll_end = window.pageYOffset;
      break;
    case 'KeyT'://スクロール時間=曲の長さを入力。ダイアログでは3分15秒なら'3 15'のように分と秒を半角スペースで区切って入力
      const userInput = window.prompt('スクロールにかける時間(min sec)を入力');
      const temp = userInput.split(' ');
      autoScroll_time = parseInt(temp[0]) * 60 + parseInt(temp[1]);
      if (!autoScroll_time) { //正しい入力がなければアラートを出してデフォルト値に戻す
        autoScroll_time = '30';
        alert('エラー:分と秒を空白で区切って入力して下さい');
      }
      console.log(autoScroll_time);
      break;
    case 'KeyS'://自動スクロールを開始
      window.scrollTo(0, autoScroll_start);
      const autoScroll_interval = autoScroll_time / (autoScroll_end - autoScroll_start) * 1000 * AUTOSCROLL_STEP;//スクロール速度の計算
      console.log(autoScroll_interval);
      autoScrollTimer = setInterval(function () {
        window.scrollBy({
          left: 0, top: AUTOSCROLL_STEP, behavior: 'smooth'
        });
        if (window.pageYOffset >= autoScroll_end) clearInterval(autoScrollTimer);
      }, autoScroll_interval);
      isTimerOn = true;
      break;
  }
});

 

ブックマークレット版

 bookmarklet
javascript:autoscroll%3D%27%27%3Bconst AUTOSCROLL_STEP%3D2%3Bvar autoScroll_start%3D0%3Bvar elm%3Ddocument.documentElement%3Bvar autoScroll_end%3Delm.scrollHeight-elm.clientHeight%3Bvar autoScroll_time%3D30%3Bvar autoScroll_lastScrollPosition%3D0%3Blet isTimerOn%3Dfalse%3Bvar autoScrollTimer%3Bwindow.addEventListener(%27keydown%27,function(event)%7Bif(isTimerOn)%7Bconsole.log(%27timer cleared%27)%3BclearInterval(autoScrollTimer)%3BisTimerOn%3Dfalse%3Breturn%7Dconsole.log(event.code)%3Bswitch(event.code)%7Bcase%27KeyA%27:autoScroll_start%3Dwindow.pageYOffset%3Bbreak%3Bcase%27KeyB%27:autoScroll_end%3Dwindow.pageYOffset%3Bbreak%3Bcase%27KeyT%27:const userInput%3Dwindow.prompt(%27スクロールにかける時間(min sec)を入力%27)%3Bconst temp%3DuserInput.split(%27 %27)%3BautoScroll_time%3DparseInt(temp%5B0%5D)*60%2BparseInt(temp%5B1%5D)%3Bif(!autoScroll_time)%7BautoScroll_time%3D%2730%27%3Balert(%27エラー:分と秒を空白で区切って入力して下さい%27)%7Dconsole.log(autoScroll_time)%3Bbreak%3Bcase%27KeyS%27:window.scrollTo(0,autoScroll_start)%3Bconst autoScroll_interval%3DautoScroll_time/(autoScroll_end-autoScroll_start)*1000*AUTOSCROLL_STEP%3Bconsole.log(autoScroll_interval)%3BautoScrollTimer%3DsetInterval(function()%7Bwindow.scrollBy(%7Bleft:0,top:AUTOSCROLL_STEP,behavior:%27smooth%27%7D)%3Bif(window.pageYOffset>%3DautoScroll_end)clearInterval(autoScrollTimer)%7D,autoScroll_interval)%3BisTimerOn%3Dtrue%3Bbreak%7D%7D)%3Bvoid(0)%3B

 

ブックマークの作成あれこれ

ソースコードのブックマークレット化にはこちらのサイトを利用しました。改行はもちろん、コメントも削除してくれるので便利です。

ブックマークレット作成

 

あと、WordPressって記事中にブックマークレットを配置できないんですね。aタグを直接書いてみたりとか、色々やってもはじかれてしまう。

また、Dropboxにブックマークレットのソースコード置いて公開しておき、ブックマークからこれを参照することでメンテナンス性を上げるという記事もいくつか見ました。

試しにやってみたのですが、Chromeのセキュリティ制限に引っかかって動きませんでした。

 

 

-html, Javascript, プログラミング, 楽器