+
+
Highlight scale degrees
+
+
+
+
Scale degrees display
+
+
+
+
-
-
-
-
-
-
Configure 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`] = `
>
-
-