aboutsummaryrefslogtreecommitdiff
path: root/src/view/play.ts
blob: b85e505f4b2e84249146458c109278654e8d61ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { h, withVar, Html } from 'lib/rx'
import * as Options from 'view/options'
import * as Chord from 'chord'

interface ViewParams {
  options: Options.Model
}

export function view({ options }: ViewParams): Html {
  const initChords: Array<[string, string]> = [['', ''], Chord.generate(options), Chord.generate(options)]

  return withVar(initChords, (chords, updateChords) =>
    withVar(undefined, (beat, updateBeat) => {
      let chordBeat = 1
      const interval = setInterval(() => {
        if (chordBeat === options.beatsPerChord) {
          updateChords(xs => {
            xs.shift()
            xs.push(Chord.generate(options))
            return xs
          })
          chordBeat = 1
        } else {
          updateBeat(_ => undefined)
          chordBeat += 1
        }
      }, 60 / options.bpm * 1000)

      return h('div',
        { className: 'g-Play',
          onunmount: () => clearInterval(interval)
        },
        chords.map(xs =>
          h('div',
            { className: 'g-Chords' },
            xs.map((chord, i) => {
              if (i == 0) {
                return viewChord(chord, 'g-Chord--Disappear')
              } else if (i == 1) {
                return beat.map(_ => viewChord(chord))
              } else {
                return viewChord(chord)
              }
            })
          )
        )
      )
    })
  )
}

function viewChord([base, alteration]: [string, string], className: string = ''): Html {
  return h('div',
    { className: `g-Chord ${className}` },
    base,
    h('sup', alteration)
  )
}