diff --git a/src/ui/pattern-player/pattern-player.vue b/src/ui/pattern-player/pattern-player.vue index cf17260c5..8a8dc428e 100644 --- a/src/ui/pattern-player/pattern-player.vue +++ b/src/ui/pattern-player/pattern-player.vue @@ -109,6 +109,53 @@ return strokeEl ? (strokeEl.offsetLeft + strokeEl.offsetWidth * (stroke - strokeIdx)) : 0; }; + + // If there is no upbeat, beatI goes from 0 to length - 1. + // If there is an upbeat, beatI goes from floor(-upbeat/time) to length - 1. + const isTernaryBeat = (instrumentKey: Instrument, beatI: number) => { + const patternForInstrument = pattern.value[instrumentKey]; + const hasNote = (j: number) => { + // pattern is an array so its indexes start at 0, not -upbeat. + const realJ = j + pattern.value.upbeat; + return patternForInstrument[realJ] !== undefined && patternForInstrument[realJ] !== null && patternForInstrument[realJ] !== " "; + } + const firstStrokeInBeat = beatI * pattern.value.time; + const lastStrokeInBeat = firstStrokeInBeat + pattern.value.time - 1; + for (let strokeNum = firstStrokeInBeat; strokeNum <= lastStrokeInBeat; strokeNum++) { + if (strokeNum%3 !==0 && hasNote(strokeNum)) { + return true; + } + } + return false; + } + const beatIFromStrokeI = (strokeI: number) => { + return Math.floor(strokeI/pattern.value.time); + } + // For each instrument, for each stroke, return the CSS class to apply to the stroke : "" or "is-triplet". + const ternaryCSSClasses = computed(() => { + const ret = {} as Record>; + for (let instrumentKey of config.instrumentKeys) { + ret[instrumentKey] = {}; + } + // We only support 12 and 24 time signatures for now. + if(![12, "12", 24, "24"].includes(pattern.value.time)) return ret; + const ternaryClassesForInstrument = (instrumentKey: Instrument) => { + const areBeatsTernary: Record = {}; + for (let beatI = beatIFromStrokeI(-pattern.value.upbeat); beatI < pattern.value.length; beatI++) { + areBeatsTernary[beatI] = isTernaryBeat(instrumentKey, beatI); + } + const ternaryCSSClassesForInstrument: Record = {}; + for (let strokeI = -pattern.value.upbeat; strokeI < pattern.value.length*pattern.value.time + pattern.value.upbeat; strokeI++) { + ternaryCSSClassesForInstrument[strokeI] = areBeatsTernary[beatIFromStrokeI(strokeI)] ? 'is-triplet' : ''; + } + return ternaryCSSClassesForInstrument; + } + for (let instrumentKey of config.instrumentKeys) { + ret[instrumentKey] = ternaryClassesForInstrument(instrumentKey); + } + return ret; + }); + const getBeatClass = (i: number) => { let positiveI = i; while(positiveI < 0) // Support negative numbers properly @@ -123,6 +170,8 @@ }; const getStrokeClass = (realI: number, instrumentKey: Instrument) => { + // realI starts at 0, even if there is an upbeat. + // i goes from -upbeat to length*time - 1. let i = realI - pattern.value.upbeat; const ret = [ @@ -233,7 +282,7 @@
- +
-
@@ -250,8 +299,8 @@ - {{config.strokes[pattern[instrumentKey][i-1]] || '\xa0'}} + + {{config.strokes[pattern[instrumentKey][i-1]]}} \ No newline at end of file +