diff --git a/angular.json b/angular.json index e013731..f0a5d9b 100644 --- a/angular.json +++ b/angular.json @@ -62,7 +62,7 @@ { "type": "anyComponentStyle", "maximumWarning": "6kb", - "maximumError": "12kb" + "maximumError": "12.5kb" } ], "serviceWorker": true, diff --git a/apps/fretonator-web/src/app/common/fretonator/fretboard-config/fretboard-config.component.html b/apps/fretonator-web/src/app/common/fretonator/fretboard-config/fretboard-config.component.html index 67e6db1..100e1cb 100644 --- a/apps/fretonator-web/src/app/common/fretonator/fretboard-config/fretboard-config.component.html +++ b/apps/fretonator-web/src/app/common/fretonator/fretboard-config/fretboard-config.component.html @@ -8,8 +8,6 @@ [class.fretboard__toggleButton--active]="fretMode === FretModes.twentyFour" (click)="setFretModeClick(FretModes.twentyFour)">24 frets - -
-
- Configure scale degrees - Highlight scale degrees - +
+
+

Highlight scale degrees

+ +
+
+

Scale degrees display

+
+ + +
-
- -
- -
- Configure fretboard +
+

Fretboard

+ +
+

Guitar tuning

+
+ + + +
+
diff --git a/apps/fretonator-web/src/app/common/fretonator/fretboard/fretboard.component.scss b/apps/fretonator-web/src/app/common/fretonator/fretboard/fretboard.component.scss index 6fd2932..9ba6cf4 100644 --- a/apps/fretonator-web/src/app/common/fretonator/fretboard/fretboard.component.scss +++ b/apps/fretonator-web/src/app/common/fretonator/fretboard/fretboard.component.scss @@ -215,32 +215,32 @@ $note-height: 36; } } - &[data-string="G"][data-fret="3"], - &[data-string="G"][data-fret="5"], - &[data-string="G"][data-fret="7"], - &[data-string="G"][data-fret="9"], - &[data-string="G"][data-fret="15"], - &[data-string="G"][data-fret="17"], - &[data-string="G"][data-fret="19"], - &[data-string="G"][data-fret="21"], - &[data-string="B"][data-fret="12"], - &[data-string="D"][data-fret="12"] { + &[data-string-number="3"][data-fret="3"], + &[data-string-number="3"][data-fret="5"], + &[data-string-number="3"][data-fret="7"], + &[data-string-number="3"][data-fret="9"], + &[data-string-number="3"][data-fret="15"], + &[data-string-number="3"][data-fret="17"], + &[data-string-number="3"][data-fret="19"], + &[data-string-number="3"][data-fret="21"], + &[data-string-number="2"][data-fret="12"], + &[data-string-number="4"][data-fret="12"] { background-image: var(--fret-marker-url); background-repeat: no-repeat; background-position: center calc(var(--string-height-base) - 15px); background-size: 30px 30px; } - &[data-string="D"][data-fret="3"], - &[data-string="D"][data-fret="5"], - &[data-string="D"][data-fret="7"], - &[data-string="D"][data-fret="9"], - &[data-string="D"][data-fret="15"], - &[data-string="D"][data-fret="17"], - &[data-string="D"][data-fret="19"], - &[data-string="D"][data-fret="21"], - &[data-string="G"][data-fret="12"], - &[data-string="A"][data-fret="12"] { + &[data-string-number="4"][data-fret="3"], + &[data-string-number="4"][data-fret="5"], + &[data-string-number="4"][data-fret="7"], + &[data-string-number="4"][data-fret="9"], + &[data-string-number="4"][data-fret="15"], + &[data-string-number="4"][data-fret="17"], + &[data-string-number="4"][data-fret="19"], + &[data-string-number="4"][data-fret="21"], + &[data-string-number="3"][data-fret="12"], + &[data-string-number="5"][data-fret="12"] { background-image: var(--fret-marker-url); background-repeat: no-repeat; background-position: center -15px; @@ -326,14 +326,6 @@ $note-height: 36; color: var(--note-color-dominant); } } - - &[data-mode="majorPentatonic"], - &[data-mode="minorPentatonic"] { - &:after { - background-color: var(--note-background) !important; - color: var(--note-color) !important; - } - } } .fretboard__cell--string { @@ -484,45 +476,41 @@ $note-height: 36; .controlPanel { @include content_wrapper(); - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: flex-start; max-width: $screen-med; margin-top: pxToRem($grid-unit * 2); - margin-bottom: pxToRem($grid-unit * 2); + margin-bottom: pxToRem($grid-unit * 8); background-color: var(--background-color-light); padding: pxToRem($grid-unit * 4); border-radius: pxToRem($grid-unit * 4); box-shadow: 0 pxToRem(1) pxToRem(3) rgba(26, 26, 26, 0.12), 0 pxToRem(1) pxToRem(2) rgba(26, 26, 26, 0.24); +} + +.controlPanel__row { + display: flex; + flex-direction: column; + margin-bottom: pxToRem($grid-unit * 4); + justify-content: center; @media screen and (min-width: $screen-med) { + justify-content: space-between; flex-direction: row; } } -.controlPanel__section { +.controlPanel__column { display: flex; flex-direction: column; - width: 100%; - margin-bottom: pxToRem($grid-unit * 4); + margin-bottom: pxToRem($grid-unit * 8); + justify-content: center; &:last-of-type { margin-bottom: 0; } - - @media screen and (min-width: $screen-med) { - margin-bottom: 0; - } } .controlPanel__title { @include info_container_title; text-align: center; - - @media screen and (min-width: $screen-med) { - text-align: left; - } } .controlPanel__title--right { @@ -547,6 +535,33 @@ $note-height: 36; } } +.button__group--right { + @media screen and (min-width: $screen-med) { + justify-content: flex-end; + } +} + +.fretboard__tuningGroup { + margin-left: auto; + margin-right: auto; + max-width: $screen-med; + text-align: center; +} + +.fretboard__changeTuning { + @include chip_button_base; + margin-left: pxToRem($grid-unit); + margin-right: pxToRem($grid-unit); + margin-bottom: pxToRem($grid-unit); + border-color: var(--fretboard-toggle-button-border-color); +} + +.fretboard__changeTuning--active { + background-color: var(--chip-background-color-active); + color: var(--chip-foreground-color-active); + border-color: var(--chip-border-color-active); +} + .fretboard__toggleButton { @include chip_button_base(); padding: pxToRem($grid-unit * 1.5); diff --git a/apps/fretonator-web/src/app/common/fretonator/fretboard/fretboard.component.ts b/apps/fretonator-web/src/app/common/fretonator/fretboard/fretboard.component.ts index 9a479e7..377cc4b 100644 --- a/apps/fretonator-web/src/app/common/fretonator/fretboard/fretboard.component.ts +++ b/apps/fretonator-web/src/app/common/fretonator/fretboard/fretboard.component.ts @@ -4,6 +4,10 @@ import { NotePlaybackService } from '../../playback/note-playback.service'; import { AbstractDataService } from '../../abstract-data/abstract-data.service'; import { ScaleDegrees } from '../../../util/constants'; +export enum FretboardConfigurations { + learn = 'learn' +} + export enum FretModes { twelve = 'twelve', twentyFour = 'twentyFour', @@ -19,6 +23,40 @@ export enum NoteDisplays { noteNames = 'noteNames' } +enum Tunings { + standard = 'standard', + dropd = 'dropd', + dadgad = 'dadgad' +} + +//strings are in reverse order +const TuningReturner = { + 'standard': [ + { name: 'e', note: 'E', frequencyMarker: 'e' }, + { name: 'B', note: 'B', frequencyMarker: 'B' }, + { name: 'G', note: 'G', frequencyMarker: 'G' }, + { name: 'D', note: 'D', frequencyMarker: 'D' }, + { name: 'A', note: 'A', frequencyMarker: 'A' }, + { name: 'E', note: 'E', frequencyMarker: 'E' } + ], + 'dropd': [ + { name: 'e', note: 'E', frequencyMarker: 'e' }, + { name: 'B', note: 'B', frequencyMarker: 'B' }, + { name: 'G', note: 'G', frequencyMarker: 'G' }, + { name: 'D', note: 'D', frequencyMarker: 'D' }, + { name: 'A', note: 'A', frequencyMarker: 'A' }, + { name: 'D', note: 'D', frequencyMarker: 'D_' } + ], + 'dadgad': [ + { name: 'd', note: 'D', frequencyMarker: 'd' }, + { name: 'A', note: 'A', frequencyMarker: 'A' }, + { name: 'G', note: 'G', frequencyMarker: 'G' }, + { name: 'D', note: 'D', frequencyMarker: 'D' }, + { name: 'A', note: 'A', frequencyMarker: 'A' }, + { name: 'D', note: 'D', frequencyMarker: 'D_' } + ] +}; + const FretReturner = { 'twelve': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 'twentyFour': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] @@ -27,7 +65,8 @@ const FretReturner = { const StorageKeys = { fretMode: 'fretonator_fretMode', orientation: 'fretonator_orientation', - noteNameDisplay: 'fretonator_noteNameDisplay' + noteNameDisplay: 'fretonator_noteNameDisplay', + tuning: 'fretonator_tuning' }; @Component({ @@ -43,11 +82,14 @@ export class FretboardComponent implements OnChanges, OnInit { @Input() stringNamesAreCaseSensitive = false; @Input() loadExpanded = false; @Input() configuration; + @Input() standardTuningOnly; orientation; fretMode; frets; + tuning = Tunings.standard; highlightedDegrees = new Set(); noteNameDisplay = NoteDisplays.noteNames; + strings = TuningReturner[Tunings.standard]; constructor(public playbackService: NotePlaybackService, private localStorage: AbstractDataService) { @@ -58,7 +100,12 @@ export class FretboardComponent implements OnChanges, OnInit { this.loadPropFromStorage(StorageKeys.orientation, 'orientation', Orientations.right); this.loadPropFromStorage(StorageKeys.noteNameDisplay, 'noteNameDisplay', NoteDisplays.noteNames); + if (this.configuration !== FretboardConfigurations.learn) { + this.loadPropFromStorage(StorageKeys.tuning, 'tuning', Tunings.standard); + } + this.toggleHighlight(ScaleDegrees.tonic); + this.configureStrings(); this.configureFretboard(); } @@ -68,6 +115,10 @@ export class FretboardComponent implements OnChanges, OnInit { } } + get FretboardConfigurations() { + return FretboardConfigurations; + } + get FretModes() { return FretModes; } @@ -84,6 +135,14 @@ export class FretboardComponent implements OnChanges, OnInit { return NoteDisplays; } + get Tunings() { + return Tunings; + } + + configureStrings() { + this.strings = TuningReturner[this.tuning]; + } + configureFretboard() { this.frets = FretReturner[this.fretMode]; this.loadExpandedChange.emit(this.fretMode === FretModes.twentyFour); @@ -101,6 +160,12 @@ export class FretboardComponent implements OnChanges, OnInit { this.configureFretboard(); } + setTuning(tuning: Tunings) { + this.tuning = tuning; + this.localStorage.setItem(StorageKeys.tuning, this.tuning); + this.configureStrings(); + } + toggleHighlight(degree: ScaleDegrees) { this.highlightedDegrees.has(degree) ? this.highlightedDegrees.delete(degree) : this.highlightedDegrees.add(degree); } diff --git a/apps/fretonator-web/src/app/common/fretonator/scale-map/display-scale-degrees.pipe.spec.ts b/apps/fretonator-web/src/app/common/fretonator/scale-map/display-scale-degrees.pipe.spec.ts deleted file mode 100644 index 5d226ff..0000000 --- a/apps/fretonator-web/src/app/common/fretonator/scale-map/display-scale-degrees.pipe.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { DisplayScaleDegreesPipe } from './display-scale-degrees.pipe'; - -describe('DisplayScaleDegreesPipe', () => { - let pipe; - beforeEach(() => { - pipe = new DisplayScaleDegreesPipe(); - }); - it('create an instance', () => { - expect(pipe).toBeTruthy(); - }); - - it('returns true for ionian', () => { - const result = pipe.transform('ionian'); - expect(result).toBe(true); - }); - - it('returns false for minorPentatonic', () => { - const result = pipe.transform('minorPentatonic'); - expect(result).toBe(false); - }); - - it('returns false for majorPentatonic', () => { - const result = pipe.transform('majorPentatonic'); - expect(result).toBe(false); - }); -}); - diff --git a/apps/fretonator-web/src/app/common/fretonator/scale-map/display-scale-degrees.pipe.ts b/apps/fretonator-web/src/app/common/fretonator/scale-map/display-scale-degrees.pipe.ts deleted file mode 100644 index 062b461..0000000 --- a/apps/fretonator-web/src/app/common/fretonator/scale-map/display-scale-degrees.pipe.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core'; -import { Mode } from '../../../util/types'; - -@Pipe({ - name: 'displayScaleDegrees' -}) -export class DisplayScaleDegreesPipe implements PipeTransform { - - transform(mode: Mode): boolean { - return (!(mode === Mode.majorPentatonic || mode === Mode.minorPentatonic)); - } -} diff --git a/apps/fretonator-web/src/app/common/fretonator/scale-map/scale-map.module.ts b/apps/fretonator-web/src/app/common/fretonator/scale-map/scale-map.module.ts index 2c35166..7d30cb0 100644 --- a/apps/fretonator-web/src/app/common/fretonator/scale-map/scale-map.module.ts +++ b/apps/fretonator-web/src/app/common/fretonator/scale-map/scale-map.module.ts @@ -1,10 +1,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ScaleMapComponent } from './scale-map.component'; -import { DisplayScaleDegreesPipe } from './display-scale-degrees.pipe'; -import { GetEnharmonicEquivalentPipe } from '../get-enharmonic-equivalent.pipe'; import { RouterModule } from '@angular/router'; -import { GetEnharmonicRouterLinkPipe } from '../get-enharmonic-router-link.pipe'; import { CrossModule } from '../../svgs/cross/cross.module'; import { PlayModule } from '../../svgs/play/play.module'; import { ScaleDegreesModule } from '../scale-degrees/scale-degrees.module'; @@ -13,11 +10,9 @@ import { ScaleDegreesModule } from '../scale-degrees/scale-degrees.module'; @NgModule({ declarations: [ ScaleMapComponent, - DisplayScaleDegreesPipe ], exports: [ ScaleMapComponent, - DisplayScaleDegreesPipe ], imports: [ CommonModule, diff --git a/apps/fretonator-web/src/app/common/playback/note-playback.service.ts b/apps/fretonator-web/src/app/common/playback/note-playback.service.ts index 5058d9f..3f7921b 100644 --- a/apps/fretonator-web/src/app/common/playback/note-playback.service.ts +++ b/apps/fretonator-web/src/app/common/playback/note-playback.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core'; import { StringFrequencies } from '../../util/constants'; -import { ModeMap } from '../../util/types'; const SYNTH_BUFFER_SIZE = 4096; const SYNTH_PLAY_DURATION = 2000; @@ -14,7 +13,7 @@ export class NotePlaybackService { constructor() { } - playNote(stringName, fret) { + playNote(stringFrequencyMarker, fret) { if (!this.context) { try { // Feature sniff for web audio API @@ -24,19 +23,14 @@ export class NotePlaybackService { } } if (this.context) { - const noteFrequency = this.getFrequency(stringName, fret); + const noteFrequency = this.getFrequency(stringFrequencyMarker, fret); this.pluckString(noteFrequency); } } - playMode(modeMap: ModeMap) { - console.log('playMode called!'); - console.log(modeMap); - } - - private getFrequency(stringName, fret) { - // We're using stringName here, the case sensitive alt to string, to differentiate E/e strings. - const stringFrequency = StringFrequencies[stringName]; + private getFrequency(stringFrequencyMarker, fret) { + // We're using stringFrequencyMarker here, the case sensitive alt to string, to differentiate E/e strings. + const stringFrequency = StringFrequencies[stringFrequencyMarker]; const fretCents = fret * 100; return stringFrequency * Math.pow(2, (fretCents / 1200)); } diff --git a/apps/fretonator-web/src/app/common/svgs/chevron-right/chevron-right.module.ts b/apps/fretonator-web/src/app/common/svgs/chevron-right/chevron-right.module.ts index c29d31f..c0170bf 100644 --- a/apps/fretonator-web/src/app/common/svgs/chevron-right/chevron-right.module.ts +++ b/apps/fretonator-web/src/app/common/svgs/chevron-right/chevron-right.module.ts @@ -3,7 +3,6 @@ import { CommonModule } from '@angular/common'; import { ChevronRightComponent } from './chevron-right.component'; - @NgModule({ declarations: [ChevronRightComponent], exports: [ diff --git a/apps/fretonator-web/src/app/pages/home/home-index/__snapshots__/home-index.component.spec.ts.snap b/apps/fretonator-web/src/app/pages/home/home-index/__snapshots__/home-index.component.spec.ts.snap index e4fda79..bdf91ce 100644 --- a/apps/fretonator-web/src/app/pages/home/home-index/__snapshots__/home-index.component.spec.ts.snap +++ b/apps/fretonator-web/src/app/pages/home/home-index/__snapshots__/home-index.component.spec.ts.snap @@ -291,8 +291,6 @@ exports[`HomeIndexComponent should create 1`] = ` Check out the fretboard - -
@@ -309,6 +307,7 @@ exports[`HomeIndexComponent should create 1`] = ` +
@@ -442,6 +454,7 @@ exports[`HomeIndexComponent should create 1`] = ` data-mode="ionian" data-string="B" data-string-name="B" + data-string-number="2" />
@@ -566,6 +591,7 @@ exports[`HomeIndexComponent should create 1`] = ` data-mode="ionian" data-string="G" data-string-name="G" + data-string-number="3" />
@@ -690,6 +728,7 @@ exports[`HomeIndexComponent should create 1`] = ` data-mode="ionian" data-string="D" data-string-name="D" + data-string-number="4" />
@@ -814,6 +865,7 @@ exports[`HomeIndexComponent should create 1`] = ` data-mode="ionian" data-string="A" data-string-name="A" + data-string-number="5" />
@@ -938,6 +1002,7 @@ exports[`HomeIndexComponent should create 1`] = ` data-mode="ionian" data-string="E" data-string-name="E" + data-string-number="6" />
@@ -1056,7 +1133,6 @@ exports[`HomeIndexComponent should create 1`] = ` > - -
+
- - - - Highlight scale degrees - - - -
- + + + +
+
+
+
+

+ Scale degrees display +

+
- -
- -
- - Configure fretboard - + Fretboard +
24 frets -
-
+ +
+

+ Guitar tuning +

+
+ + + +
+
diff --git a/apps/fretonator-web/src/app/pages/home/home-index/home-index.component.spec.ts b/apps/fretonator-web/src/app/pages/home/home-index/home-index.component.spec.ts index 63c88e2..6946584 100644 --- a/apps/fretonator-web/src/app/pages/home/home-index/home-index.component.spec.ts +++ b/apps/fretonator-web/src/app/pages/home/home-index/home-index.component.spec.ts @@ -2,7 +2,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { HomeIndexComponent } from './home-index.component'; import { Component } from '@angular/core'; import { HomeModule } from '../home.module'; -import { By } from '@angular/platform-browser'; import { BrowserTestingModule } from '@angular/platform-browser/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; diff --git a/apps/fretonator-web/src/app/pages/learn/patterns-index/patterns-index.component.html b/apps/fretonator-web/src/app/pages/learn/patterns-index/patterns-index.component.html index f7fa1bf..81de3a5 100644 --- a/apps/fretonator-web/src/app/pages/learn/patterns-index/patterns-index.component.html +++ b/apps/fretonator-web/src/app/pages/learn/patterns-index/patterns-index.component.html @@ -36,7 +36,7 @@
Choose a pattern
diff --git a/apps/fretonator-web/src/app/pages/learn/patterns-index/patterns-index.component.ts b/apps/fretonator-web/src/app/pages/learn/patterns-index/patterns-index.component.ts index b030f83..b7b718b 100644 --- a/apps/fretonator-web/src/app/pages/learn/patterns-index/patterns-index.component.ts +++ b/apps/fretonator-web/src/app/pages/learn/patterns-index/patterns-index.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { PatternFretMaps, PatternModeSelectors } from '../../../util/constants'; import { Mode } from '../../../util/types'; import { MetaService } from '../../../common/meta/meta.service'; +import { FretboardConfigurations } from '../../../common/fretonator/fretboard/fretboard.component'; @Component({ selector: 'app-patterns-index', @@ -29,6 +30,10 @@ export class PatternsIndexComponent implements OnInit { this.metaService.updateAllGenericMeta(this.pageUrl, this.pageTitle, this.pageDescription); } + get FretboardConfigurations() { + return FretboardConfigurations; + } + setPattern(mode: Mode) { this.selectedMode = mode; this.selectedFretMap = PatternFretMaps[mode]; diff --git a/apps/fretonator-web/src/app/util/constants.ts b/apps/fretonator-web/src/app/util/constants.ts index 4a69c6a..91acced 100644 --- a/apps/fretonator-web/src/app/util/constants.ts +++ b/apps/fretonator-web/src/app/util/constants.ts @@ -640,11 +640,13 @@ export const Enharmonics = [ export const StringFrequencies = { 'e': 329.63, + 'd': 293.66, 'B': 246.94, 'G': 196.00, 'D': 146.83, 'A': 110.00, - 'E': 82.41 + 'E': 82.41, + 'D_': 73.42, }; export const StandardModePatterns = [