mo49
1/18/2020 - 12:08 PM

00_Metronome.md

デモ:http://codepen.io/mo4_9/pen/WRVXvR

BPMと拍数を渡して、リズムがずれないようにするコード(メトロノーム)。

.wrapperのdata属性のインデックスを参照すれば、ページ全体でリズムが揃う。

class Metronome {
  constructor(opts={}) {
    this.BPM = isNaN(opts.BPM) ? 120 : opts.BPM;
    this.NUM_BEATS = isNaN(opts.NUM_BEATS) ? 4 : opts.NUM_BEATS;
    this.msPerBeat = 60000 / this.BPM;
    this.wrapper = document.getElementsByClassName("wrapper")[0];

    this.start();
  }

  start() {
    this.startTime = Date.now()
    requestAnimationFrame(() => this.loop())
  }

  loop() {
    const elapsedTime = Date.now() - this.startTime;
    const currentBeatIndex = Math.floor( elapsedTime / this.msPerBeat ) % this.NUM_BEATS;
    this.setBeatIndex(currentBeatIndex)
    this.loopId = requestAnimationFrame(() => this.loop())
  }

  stop() {
    cancelAnimationFrame(this.loopId)
  }

  // 何拍目かを設定
  setBeatIndex(index) {
    switch (this.NUM_BEATS) {
      case 4: this.wrapper.setAttribute("data-beat4-index", index+1); break;
      case 3: this.wrapper.setAttribute("data-beat3-index", index+1); break;
      case 2: this.wrapper.setAttribute("data-beat2-index", index+1); break;
    }
  }

}

(() => {
  
  const BPM = 120;

  new Metronome({
    BPM: BPM,     // BPM
    NUM_BEATS: 4, // 拍数
  })
  new Metronome({
    BPM: BPM,
    NUM_BEATS: 3,
  })
  new Metronome({
    BPM: BPM,
    NUM_BEATS: 2,
  })
  
})()
// .is-beat3-1 なら「3コマアニメーションの1コマ目」という意味

// 4拍子
.wrapper[data-beat4-index="1"]{
  .is-beat4-2,.is-beat4-3,.is-beat4-4{display: none !important;}
}
.wrapper[data-beat4-index="2"]{
  .is-beat4-1,.is-beat4-3,.is-beat4-4{display: none !important;}
}
.wrapper[data-beat4-index="3"]{
  .is-beat4-1,.is-beat4-2,.is-beat4-4{display: none !important;}
}
.wrapper[data-beat4-index="4"]{
  .is-beat4-1,.is-beat4-2,.is-beat4-3{display: none !important;}
}

// 3拍子
.wrapper[data-beat3-index="1"]{
  .is-beat3-2,.is-beat3-3{display: none !important;}
}
.wrapper[data-beat3-index="2"]{
  .is-beat3-1,.is-beat3-3{display: none !important;}
}
.wrapper[data-beat3-index="3"]{
  .is-beat3-1,.is-beat3-2{display: none !important;}
}

// 2拍子
.wrapper[data-beat2-index="1"]{
  .is-beat2-2{display: none !important;}
}
.wrapper[data-beat2-index="2"]{
  .is-beat2-1{display: none !important;}
}