text-guitar-chart 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FORMAT.md +10 -4
- package/docs/bundle.js +157 -91
- package/docs/bundle.js.map +2 -2
- package/lib/editableSVGuitar.js +184 -127
- package/lib/fingeringToString.js +25 -2
- package/lib/stringToFingering.js +23 -2
- package/package.json +1 -1
- package/test/editableSVGuitar.test.js +15 -6
- package/test/fingeringToString.test.js +221 -0
- package/test/stringToFingering.test.js +176 -0
- package/types/editableSVGuitar.d.ts +22 -1
- package/types/stringToFingering.d.ts +3 -1
package/FORMAT.md
CHANGED
|
@@ -14,11 +14,13 @@ Strings are numbered 1-6 from right to left in the diagram. In standard guitar t
|
|
|
14
14
|
- String 1 (rightmost) is the highest pitch (E4)
|
|
15
15
|
|
|
16
16
|
### Color values
|
|
17
|
-
The format supports
|
|
17
|
+
The format supports four colors for fingering markers:
|
|
18
18
|
- `#000000` (black) for regular fingering positions
|
|
19
19
|
- `#e74c3c` (red/root marker color) for special positions (typically root notes)
|
|
20
|
+
- `#9B9B9B` (grey) for grey marker positions
|
|
21
|
+
- `#4A90E2` (blue) for blue marker positions
|
|
20
22
|
|
|
21
|
-
Any color value
|
|
23
|
+
Any color value not matching one of the four known colors is treated as a root marker (red) and rendered with the root marker symbol.
|
|
22
24
|
|
|
23
25
|
## ascii format
|
|
24
26
|
|
|
@@ -47,7 +49,9 @@ The first line can optionally have an indication of the starting fret on the lef
|
|
|
47
49
|
These different characters are used:
|
|
48
50
|
- "|" indicates that there is no fingering in this position
|
|
49
51
|
- "o" indicates that this position is fingered with a regular dot (color #000000)
|
|
50
|
-
- "*" indicates that this position is fingered with a root marker (
|
|
52
|
+
- "*" indicates that this position is fingered with a root marker (color #e74c3c or any unrecognized color)
|
|
53
|
+
- "O" (uppercase) indicates that this position is fingered with a grey marker (color #9B9B9B)
|
|
54
|
+
- "+" indicates that this position is fingered with a blue marker (color #4A90E2)
|
|
51
55
|
- any other character is displayed as text on the fretboard at that position (commonly used for finger numbers or note names)
|
|
52
56
|
|
|
53
57
|
Examples:
|
|
@@ -139,7 +143,9 @@ The second line can optionally have an indication of the starting fret on the le
|
|
|
139
143
|
The even rows contain characters representing the fingering:
|
|
140
144
|
- "│" indicates that there is no fingering in this position
|
|
141
145
|
- "○" indicates that this position is fingered with a regular dot (color #000000)
|
|
142
|
-
- "●" indicates that this position is fingered with a root marker (
|
|
146
|
+
- "●" indicates that this position is fingered with a root marker (color #e74c3c or any unrecognized color)
|
|
147
|
+
- "□" indicates that this position is fingered with a grey marker (color #9B9B9B)
|
|
148
|
+
- "■" indicates that this position is fingered with a blue marker (color #4A90E2)
|
|
143
149
|
- any other character is displayed as text on the fretboard at that position (commonly used for finger numbers or note names)
|
|
144
150
|
|
|
145
151
|
Example:
|
package/docs/bundle.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
// lib/fingeringToString.js
|
|
2
|
+
var COLOR_GREY = "#9B9B9B";
|
|
3
|
+
var COLOR_BLUE = "#4A90E2";
|
|
4
|
+
function getMarkerChar(color, isUnicode) {
|
|
5
|
+
if (color === COLOR_GREY) {
|
|
6
|
+
return isUnicode ? "\u25A1" : "O";
|
|
7
|
+
}
|
|
8
|
+
if (color === COLOR_BLUE) {
|
|
9
|
+
return isUnicode ? "\u25A0" : "+";
|
|
10
|
+
}
|
|
11
|
+
return isUnicode ? "\u25CF" : "*";
|
|
12
|
+
}
|
|
2
13
|
function fingeringToString(chord, options = {}) {
|
|
3
14
|
const { useUnicode = false } = options;
|
|
4
15
|
const { fingers = [], title = "", position: position2 } = chord;
|
|
@@ -84,7 +95,7 @@ function buildAsciiOutput(title, stringData, openStrings, mutedStrings, numFrets
|
|
|
84
95
|
const fingerInfo = (_a12 = stringData.get(str)) == null ? void 0 : _a12.get(fret);
|
|
85
96
|
if (fingerInfo) {
|
|
86
97
|
if (fingerInfo.color !== "#000000") {
|
|
87
|
-
line +=
|
|
98
|
+
line += getMarkerChar(fingerInfo.color, false);
|
|
88
99
|
} else if (fingerInfo.text) {
|
|
89
100
|
line += fingerInfo.text[0];
|
|
90
101
|
} else {
|
|
@@ -141,7 +152,7 @@ function buildUnicodeOutput(title, stringData, openStrings, mutedStrings, numFre
|
|
|
141
152
|
const fingerInfo = (_a12 = stringData.get(str)) == null ? void 0 : _a12.get(fret);
|
|
142
153
|
if (fingerInfo) {
|
|
143
154
|
if (fingerInfo.color !== "#000000") {
|
|
144
|
-
line +=
|
|
155
|
+
line += getMarkerChar(fingerInfo.color, true);
|
|
145
156
|
} else if (fingerInfo.text) {
|
|
146
157
|
line += fingerInfo.text[0];
|
|
147
158
|
} else {
|
|
@@ -7420,7 +7431,9 @@ var SVGuitarChord = (
|
|
|
7420
7431
|
// lib/editableSVGuitar.js
|
|
7421
7432
|
var DOT_COLORS = {
|
|
7422
7433
|
RED: "#e74c3c",
|
|
7423
|
-
BLACK: "#000000"
|
|
7434
|
+
BLACK: "#000000",
|
|
7435
|
+
GREY: "#9B9B9B",
|
|
7436
|
+
BLUE: "#4A90E2"
|
|
7424
7437
|
};
|
|
7425
7438
|
var EditableSVGuitarChord = class {
|
|
7426
7439
|
/**
|
|
@@ -7491,7 +7504,7 @@ var EditableSVGuitarChord = class {
|
|
|
7491
7504
|
padding: 20px;
|
|
7492
7505
|
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
|
|
7493
7506
|
z-index: 1000;
|
|
7494
|
-
min-width:
|
|
7507
|
+
min-width: 220px;
|
|
7495
7508
|
`;
|
|
7496
7509
|
const title = document.createElement("h3");
|
|
7497
7510
|
title.textContent = "Chord Settings";
|
|
@@ -7499,28 +7512,32 @@ var EditableSVGuitarChord = class {
|
|
|
7499
7512
|
const titleSection = document.createElement("div");
|
|
7500
7513
|
titleSection.style.cssText = "margin-bottom: 15px;";
|
|
7501
7514
|
const titleLabel = document.createElement("label");
|
|
7502
|
-
titleLabel.textContent = "Title
|
|
7503
|
-
titleLabel.
|
|
7515
|
+
titleLabel.textContent = "Title: ";
|
|
7516
|
+
titleLabel.htmlFor = "editable-svguitar-title-input";
|
|
7517
|
+
titleLabel.style.cssText = "display: inline-block; margin-bottom: 5px; font-weight: bold; width: 80px;";
|
|
7504
7518
|
this.titleInput = document.createElement("input");
|
|
7519
|
+
this.titleInput.id = "editable-svguitar-title-input";
|
|
7505
7520
|
this.titleInput.type = "text";
|
|
7506
7521
|
this.titleInput.placeholder = "e.g. A min";
|
|
7507
7522
|
this.titleInput.maxLength = 10;
|
|
7508
7523
|
this.titleInput.style.cssText = "width: 10em; padding: 6px; border: 1px solid #ccc; border-radius: 3px; box-sizing: border-box;";
|
|
7509
|
-
titleLabel.appendChild(this.titleInput);
|
|
7510
7524
|
titleSection.appendChild(titleLabel);
|
|
7525
|
+
titleSection.appendChild(this.titleInput);
|
|
7511
7526
|
const positionSection = document.createElement("div");
|
|
7512
7527
|
positionSection.style.cssText = "margin-bottom: 15px;";
|
|
7513
7528
|
const positionLabel = document.createElement("label");
|
|
7514
|
-
positionLabel.textContent = "Position
|
|
7515
|
-
positionLabel.
|
|
7529
|
+
positionLabel.textContent = "Position: ";
|
|
7530
|
+
positionLabel.htmlFor = "editable-svguitar-position-input";
|
|
7531
|
+
positionLabel.style.cssText = "display: inline-block; margin-bottom: 5px; font-weight: bold; width: 80px;";
|
|
7516
7532
|
this.positionInput = document.createElement("input");
|
|
7533
|
+
this.positionInput.id = "editable-svguitar-position-input";
|
|
7517
7534
|
this.positionInput.type = "number";
|
|
7518
7535
|
this.positionInput.min = "1";
|
|
7519
7536
|
this.positionInput.max = "30";
|
|
7520
7537
|
this.positionInput.placeholder = "1-30";
|
|
7521
7538
|
this.positionInput.style.cssText = "width: 5em; padding: 6px; border: 1px solid #ccc; border-radius: 3px; box-sizing: border-box;";
|
|
7522
|
-
positionLabel.appendChild(this.positionInput);
|
|
7523
7539
|
positionSection.appendChild(positionLabel);
|
|
7540
|
+
positionSection.appendChild(this.positionInput);
|
|
7524
7541
|
const buttonDiv = document.createElement("div");
|
|
7525
7542
|
buttonDiv.style.cssText = "display: flex; gap: 10px; justify-content: flex-end;";
|
|
7526
7543
|
const cancelBtn = document.createElement("button");
|
|
@@ -7568,60 +7585,82 @@ var EditableSVGuitarChord = class {
|
|
|
7568
7585
|
padding: 20px;
|
|
7569
7586
|
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
|
|
7570
7587
|
z-index: 1000;
|
|
7571
|
-
min-width:
|
|
7588
|
+
min-width: 200px;
|
|
7572
7589
|
`;
|
|
7573
7590
|
const title = document.createElement("h3");
|
|
7574
7591
|
title.textContent = "Edit Dot";
|
|
7575
7592
|
title.style.cssText = "margin: 0 0 15px 0; font-size: 16px;";
|
|
7576
7593
|
const colorSection = document.createElement("div");
|
|
7577
7594
|
colorSection.style.cssText = "margin-bottom: 15px;";
|
|
7578
|
-
const colorLabel = document.createElement("div");
|
|
7579
|
-
colorLabel.textContent = "Color:";
|
|
7580
|
-
colorLabel.style.cssText = "font-weight: bold; margin-bottom: 8px;";
|
|
7581
|
-
colorSection.appendChild(colorLabel);
|
|
7582
7595
|
const colorOptions = document.createElement("div");
|
|
7583
|
-
colorOptions.style.cssText = "display: flex; gap:
|
|
7596
|
+
colorOptions.style.cssText = "display: flex; gap: 8px; align-items: center;";
|
|
7597
|
+
const hiddenRadioStyle = "position:absolute;opacity:0;width:0;height:0;";
|
|
7598
|
+
const swatchStyle = (color) => `width:28px;height:28px;display:block;background:${color};border-radius:3px;cursor:pointer;box-sizing:border-box;`;
|
|
7584
7599
|
const redOption = document.createElement("label");
|
|
7585
|
-
redOption.style.cssText = "display:
|
|
7600
|
+
redOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
|
|
7586
7601
|
this.redRadio = document.createElement("input");
|
|
7587
7602
|
this.redRadio.type = "radio";
|
|
7588
7603
|
this.redRadio.name = "dotColor";
|
|
7589
7604
|
this.redRadio.value = DOT_COLORS.RED;
|
|
7605
|
+
this.redRadio.style.cssText = hiddenRadioStyle;
|
|
7590
7606
|
this.redRadio.addEventListener("change", () => this.updateDotColor());
|
|
7591
|
-
const
|
|
7592
|
-
|
|
7593
|
-
|
|
7607
|
+
const redSwatch = document.createElement("span");
|
|
7608
|
+
redSwatch.className = "color-swatch";
|
|
7609
|
+
redSwatch.style.cssText = swatchStyle(DOT_COLORS.RED);
|
|
7594
7610
|
redOption.appendChild(this.redRadio);
|
|
7595
|
-
redOption.appendChild(
|
|
7611
|
+
redOption.appendChild(redSwatch);
|
|
7612
|
+
const greyOption = document.createElement("label");
|
|
7613
|
+
greyOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
|
|
7614
|
+
this.greyRadio = document.createElement("input");
|
|
7615
|
+
this.greyRadio.type = "radio";
|
|
7616
|
+
this.greyRadio.name = "dotColor";
|
|
7617
|
+
this.greyRadio.value = DOT_COLORS.GREY;
|
|
7618
|
+
this.greyRadio.style.cssText = hiddenRadioStyle;
|
|
7619
|
+
this.greyRadio.addEventListener("change", () => this.updateDotColor());
|
|
7620
|
+
const greySwatch = document.createElement("span");
|
|
7621
|
+
greySwatch.className = "color-swatch";
|
|
7622
|
+
greySwatch.style.cssText = swatchStyle(DOT_COLORS.GREY);
|
|
7623
|
+
greyOption.appendChild(this.greyRadio);
|
|
7624
|
+
greyOption.appendChild(greySwatch);
|
|
7625
|
+
const blueOption = document.createElement("label");
|
|
7626
|
+
blueOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
|
|
7627
|
+
this.blueRadio = document.createElement("input");
|
|
7628
|
+
this.blueRadio.type = "radio";
|
|
7629
|
+
this.blueRadio.name = "dotColor";
|
|
7630
|
+
this.blueRadio.value = DOT_COLORS.BLUE;
|
|
7631
|
+
this.blueRadio.style.cssText = hiddenRadioStyle;
|
|
7632
|
+
this.blueRadio.addEventListener("change", () => this.updateDotColor());
|
|
7633
|
+
const blueSwatch = document.createElement("span");
|
|
7634
|
+
blueSwatch.className = "color-swatch";
|
|
7635
|
+
blueSwatch.style.cssText = swatchStyle(DOT_COLORS.BLUE);
|
|
7636
|
+
blueOption.appendChild(this.blueRadio);
|
|
7637
|
+
blueOption.appendChild(blueSwatch);
|
|
7596
7638
|
const blackOption = document.createElement("label");
|
|
7597
|
-
blackOption.style.cssText = "display:
|
|
7639
|
+
blackOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
|
|
7598
7640
|
this.blackRadio = document.createElement("input");
|
|
7599
7641
|
this.blackRadio.type = "radio";
|
|
7600
7642
|
this.blackRadio.name = "dotColor";
|
|
7601
7643
|
this.blackRadio.value = DOT_COLORS.BLACK;
|
|
7602
7644
|
this.blackRadio.checked = true;
|
|
7645
|
+
this.blackRadio.style.cssText = hiddenRadioStyle;
|
|
7603
7646
|
this.blackRadio.addEventListener("change", () => this.updateDotColor());
|
|
7604
|
-
const
|
|
7605
|
-
|
|
7606
|
-
|
|
7647
|
+
const blackSwatch = document.createElement("span");
|
|
7648
|
+
blackSwatch.className = "color-swatch";
|
|
7649
|
+
blackSwatch.style.cssText = swatchStyle(DOT_COLORS.BLACK);
|
|
7607
7650
|
blackOption.appendChild(this.blackRadio);
|
|
7608
|
-
blackOption.appendChild(
|
|
7651
|
+
blackOption.appendChild(blackSwatch);
|
|
7609
7652
|
colorOptions.appendChild(redOption);
|
|
7653
|
+
colorOptions.appendChild(greyOption);
|
|
7654
|
+
colorOptions.appendChild(blueOption);
|
|
7610
7655
|
colorOptions.appendChild(blackOption);
|
|
7611
|
-
colorSection.appendChild(colorOptions);
|
|
7612
|
-
this.textSection = document.createElement("div");
|
|
7613
|
-
this.textSection.style.cssText = "margin-bottom: 15px;";
|
|
7614
|
-
const textLabel = document.createElement("label");
|
|
7615
|
-
textLabel.textContent = "Text (optional): ";
|
|
7616
|
-
textLabel.style.cssText = "display: block; margin-bottom: 5px; font-weight: bold;";
|
|
7617
7656
|
this.textInput = document.createElement("input");
|
|
7618
7657
|
this.textInput.type = "text";
|
|
7619
|
-
this.textInput.maxLength =
|
|
7620
|
-
this.textInput.placeholder = "
|
|
7621
|
-
this.textInput.style.cssText = "width:
|
|
7658
|
+
this.textInput.maxLength = 1;
|
|
7659
|
+
this.textInput.placeholder = "Aa";
|
|
7660
|
+
this.textInput.style.cssText = "width:32px;height:28px;padding:0 4px;margin-left:4px;border:1px solid #ccc;border-radius:3px;box-sizing:border-box;";
|
|
7622
7661
|
this.textInput.addEventListener("input", () => this.updateDotText());
|
|
7623
|
-
|
|
7624
|
-
|
|
7662
|
+
colorOptions.appendChild(this.textInput);
|
|
7663
|
+
colorSection.appendChild(colorOptions);
|
|
7625
7664
|
const buttonDiv = document.createElement("div");
|
|
7626
7665
|
buttonDiv.style.cssText = "display: flex; gap: 10px; justify-content: flex-end;";
|
|
7627
7666
|
const removeBtn = document.createElement("button");
|
|
@@ -7636,7 +7675,6 @@ var EditableSVGuitarChord = class {
|
|
|
7636
7675
|
buttonDiv.appendChild(doneBtn);
|
|
7637
7676
|
this.dialog.appendChild(title);
|
|
7638
7677
|
this.dialog.appendChild(colorSection);
|
|
7639
|
-
this.dialog.appendChild(this.textSection);
|
|
7640
7678
|
this.dialog.appendChild(buttonDiv);
|
|
7641
7679
|
document.body.appendChild(this.dialog);
|
|
7642
7680
|
this.backdrop = document.createElement("div");
|
|
@@ -7670,60 +7708,59 @@ var EditableSVGuitarChord = class {
|
|
|
7670
7708
|
padding: 20px;
|
|
7671
7709
|
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
|
|
7672
7710
|
z-index: 1000;
|
|
7673
|
-
min-width:
|
|
7711
|
+
min-width: 165px;
|
|
7674
7712
|
`;
|
|
7675
7713
|
const title = document.createElement("h3");
|
|
7676
7714
|
title.textContent = "Edit Open String";
|
|
7677
7715
|
title.style.cssText = "margin: 0 0 15px 0; font-size: 16px;";
|
|
7678
7716
|
const typeSection = document.createElement("div");
|
|
7679
7717
|
typeSection.style.cssText = "margin-bottom: 15px;";
|
|
7680
|
-
const typeLabel = document.createElement("div");
|
|
7681
|
-
typeLabel.textContent = "Type:";
|
|
7682
|
-
typeLabel.style.cssText = "font-weight: bold; margin-bottom: 8px;";
|
|
7683
|
-
typeSection.appendChild(typeLabel);
|
|
7684
7718
|
const typeOptions = document.createElement("div");
|
|
7685
|
-
typeOptions.style.cssText = "display: flex; gap:
|
|
7719
|
+
typeOptions.style.cssText = "display: flex; gap: 8px; align-items: center;";
|
|
7720
|
+
const hiddenRadioStyle = "position:absolute;opacity:0;width:0;height:0;";
|
|
7721
|
+
const openStringSwatchStyle = "width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:#fff;border:1px solid #ccc;border-radius:3px;cursor:pointer;box-sizing:border-box;font-size:16px;font-weight:bold;user-select:none;";
|
|
7722
|
+
const mutedOption = document.createElement("label");
|
|
7723
|
+
mutedOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
|
|
7724
|
+
this.mutedRadio = document.createElement("input");
|
|
7725
|
+
this.mutedRadio.type = "radio";
|
|
7726
|
+
this.mutedRadio.name = "openStringType";
|
|
7727
|
+
this.mutedRadio.value = "x";
|
|
7728
|
+
this.mutedRadio.style.cssText = hiddenRadioStyle;
|
|
7729
|
+
this.mutedRadio.addEventListener("change", () => this.updateOpenStringType());
|
|
7730
|
+
const mutedSwatch = document.createElement("span");
|
|
7731
|
+
mutedSwatch.className = "open-string-swatch";
|
|
7732
|
+
mutedSwatch.textContent = "\xD7";
|
|
7733
|
+
mutedSwatch.style.cssText = openStringSwatchStyle;
|
|
7734
|
+
mutedOption.appendChild(this.mutedRadio);
|
|
7735
|
+
mutedOption.appendChild(mutedSwatch);
|
|
7686
7736
|
const openOption = document.createElement("label");
|
|
7687
|
-
openOption.style.cssText = "display:
|
|
7737
|
+
openOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
|
|
7688
7738
|
this.openRadio = document.createElement("input");
|
|
7689
7739
|
this.openRadio.type = "radio";
|
|
7690
7740
|
this.openRadio.name = "openStringType";
|
|
7691
7741
|
this.openRadio.value = "0";
|
|
7692
7742
|
this.openRadio.checked = true;
|
|
7743
|
+
this.openRadio.style.cssText = hiddenRadioStyle;
|
|
7693
7744
|
this.openRadio.addEventListener("change", () => this.updateOpenStringType());
|
|
7694
|
-
const
|
|
7695
|
-
|
|
7696
|
-
|
|
7745
|
+
const openSwatch = document.createElement("span");
|
|
7746
|
+
openSwatch.className = "open-string-swatch";
|
|
7747
|
+
openSwatch.textContent = "\u25CB";
|
|
7748
|
+
openSwatch.style.cssText = openStringSwatchStyle;
|
|
7697
7749
|
openOption.appendChild(this.openRadio);
|
|
7698
|
-
openOption.appendChild(
|
|
7699
|
-
const mutedOption = document.createElement("label");
|
|
7700
|
-
mutedOption.style.cssText = "display: flex; align-items: center; cursor: pointer;";
|
|
7701
|
-
this.mutedRadio = document.createElement("input");
|
|
7702
|
-
this.mutedRadio.type = "radio";
|
|
7703
|
-
this.mutedRadio.name = "openStringType";
|
|
7704
|
-
this.mutedRadio.value = "x";
|
|
7705
|
-
this.mutedRadio.addEventListener("change", () => this.updateOpenStringType());
|
|
7706
|
-
const mutedLabel = document.createElement("span");
|
|
7707
|
-
mutedLabel.textContent = "Muted";
|
|
7708
|
-
mutedLabel.style.cssText = "margin-left: 5px; font-weight: bold;";
|
|
7709
|
-
mutedOption.appendChild(this.mutedRadio);
|
|
7710
|
-
mutedOption.appendChild(mutedLabel);
|
|
7711
|
-
typeOptions.appendChild(openOption);
|
|
7750
|
+
openOption.appendChild(openSwatch);
|
|
7712
7751
|
typeOptions.appendChild(mutedOption);
|
|
7713
|
-
|
|
7714
|
-
this.openStringTextSection = document.createElement("div");
|
|
7715
|
-
this.openStringTextSection.style.cssText = "margin-bottom: 15px;";
|
|
7716
|
-
const textLabel = document.createElement("label");
|
|
7717
|
-
textLabel.textContent = "Text (optional): ";
|
|
7718
|
-
textLabel.style.cssText = "display: block; margin-bottom: 5px; font-weight: bold;";
|
|
7752
|
+
typeOptions.appendChild(openOption);
|
|
7719
7753
|
this.openStringTextInput = document.createElement("input");
|
|
7720
7754
|
this.openStringTextInput.type = "text";
|
|
7721
|
-
this.openStringTextInput.maxLength =
|
|
7722
|
-
this.openStringTextInput.placeholder = "
|
|
7723
|
-
this.openStringTextInput.style.cssText = "width:
|
|
7724
|
-
this.openStringTextInput.addEventListener(
|
|
7725
|
-
|
|
7726
|
-
|
|
7755
|
+
this.openStringTextInput.maxLength = 1;
|
|
7756
|
+
this.openStringTextInput.placeholder = "Aa";
|
|
7757
|
+
this.openStringTextInput.style.cssText = "width:32px;height:28px;padding:0 4px;margin-left:4px;border:1px solid #ccc;border-radius:3px;box-sizing:border-box;";
|
|
7758
|
+
this.openStringTextInput.addEventListener(
|
|
7759
|
+
"input",
|
|
7760
|
+
() => this.updateOpenStringText()
|
|
7761
|
+
);
|
|
7762
|
+
typeOptions.appendChild(this.openStringTextInput);
|
|
7763
|
+
typeSection.appendChild(typeOptions);
|
|
7727
7764
|
const buttonDiv = document.createElement("div");
|
|
7728
7765
|
buttonDiv.style.cssText = "display: flex; gap: 10px; justify-content: flex-end;";
|
|
7729
7766
|
const removeBtn = document.createElement("button");
|
|
@@ -7738,7 +7775,6 @@ var EditableSVGuitarChord = class {
|
|
|
7738
7775
|
buttonDiv.appendChild(doneBtn);
|
|
7739
7776
|
this.openStringDialog.appendChild(title);
|
|
7740
7777
|
this.openStringDialog.appendChild(typeSection);
|
|
7741
|
-
this.openStringDialog.appendChild(this.openStringTextSection);
|
|
7742
7778
|
this.openStringDialog.appendChild(buttonDiv);
|
|
7743
7779
|
document.body.appendChild(this.openStringDialog);
|
|
7744
7780
|
this.openStringBackdrop = document.createElement("div");
|
|
@@ -7983,9 +8019,14 @@ var EditableSVGuitarChord = class {
|
|
|
7983
8019
|
this.currentEditFret = fret;
|
|
7984
8020
|
const currentColor = typeof finger[2] === "object" && ((_a12 = finger[2]) == null ? void 0 : _a12.color) || DOT_COLORS.BLACK;
|
|
7985
8021
|
const currentText = typeof finger[2] === "object" && ((_b = finger[2]) == null ? void 0 : _b.text) || "";
|
|
7986
|
-
|
|
8022
|
+
let normalizedColor = DOT_COLORS.BLACK;
|
|
8023
|
+
if (currentColor === DOT_COLORS.RED) normalizedColor = DOT_COLORS.RED;
|
|
8024
|
+
else if (currentColor === DOT_COLORS.GREY) normalizedColor = DOT_COLORS.GREY;
|
|
8025
|
+
else if (currentColor === DOT_COLORS.BLUE) normalizedColor = DOT_COLORS.BLUE;
|
|
7987
8026
|
this.redRadio.checked = normalizedColor === DOT_COLORS.RED;
|
|
7988
8027
|
this.blackRadio.checked = normalizedColor === DOT_COLORS.BLACK;
|
|
8028
|
+
this.greyRadio.checked = normalizedColor === DOT_COLORS.GREY;
|
|
8029
|
+
this.blueRadio.checked = normalizedColor === DOT_COLORS.BLUE;
|
|
7989
8030
|
this.textInput.value = currentText;
|
|
7990
8031
|
this.updateTextSectionVisibility();
|
|
7991
8032
|
this.openDialog();
|
|
@@ -8207,6 +8248,14 @@ var EditableSVGuitarChord = class {
|
|
|
8207
8248
|
.editable-svguitar-settings-btn:hover {
|
|
8208
8249
|
background: #f0f0f0;
|
|
8209
8250
|
}
|
|
8251
|
+
|
|
8252
|
+
.editable-svguitar-dialog input[name="dotColor"]:checked + .color-swatch {
|
|
8253
|
+
box-shadow: 0 0 0 2px white, 0 0 0 4px grey;
|
|
8254
|
+
}
|
|
8255
|
+
|
|
8256
|
+
.editable-svguitar-open-string-dialog input[name="openStringType"]:checked + .open-string-swatch {
|
|
8257
|
+
box-shadow: 0 0 0 2px white, 0 0 0 4px grey;
|
|
8258
|
+
}
|
|
8210
8259
|
`;
|
|
8211
8260
|
document.head.appendChild(style);
|
|
8212
8261
|
}
|
|
@@ -8238,23 +8287,19 @@ var EditableSVGuitarChord = class {
|
|
|
8238
8287
|
* Update text section visibility based on color selection
|
|
8239
8288
|
*/
|
|
8240
8289
|
updateTextSectionVisibility() {
|
|
8241
|
-
if (!this.
|
|
8290
|
+
if (!this.textInput) return;
|
|
8242
8291
|
const isBlack = this.blackRadio && this.blackRadio.checked;
|
|
8243
|
-
this.
|
|
8244
|
-
|
|
8245
|
-
this.textInput.disabled = !isBlack;
|
|
8246
|
-
}
|
|
8292
|
+
this.textInput.style.display = isBlack ? "inline-block" : "none";
|
|
8293
|
+
this.textInput.disabled = !isBlack;
|
|
8247
8294
|
}
|
|
8248
8295
|
/**
|
|
8249
8296
|
* Update text section visibility for open string dialog based on type selection
|
|
8250
8297
|
*/
|
|
8251
8298
|
updateOpenStringTextSectionVisibility() {
|
|
8252
|
-
if (!this.
|
|
8299
|
+
if (!this.openStringTextInput) return;
|
|
8253
8300
|
const isOpen = this.openRadio && this.openRadio.checked;
|
|
8254
|
-
this.
|
|
8255
|
-
|
|
8256
|
-
this.openStringTextInput.disabled = !isOpen;
|
|
8257
|
-
}
|
|
8301
|
+
this.openStringTextInput.style.display = isOpen ? "inline-block" : "none";
|
|
8302
|
+
this.openStringTextInput.disabled = !isOpen;
|
|
8258
8303
|
}
|
|
8259
8304
|
/**
|
|
8260
8305
|
* Update dot text in real-time
|
|
@@ -8308,10 +8353,13 @@ var EditableSVGuitarChord = class {
|
|
|
8308
8353
|
if (!this.currentEditFinger[2]) {
|
|
8309
8354
|
this.currentEditFinger[2] = {};
|
|
8310
8355
|
}
|
|
8311
|
-
|
|
8356
|
+
let selectedColor = DOT_COLORS.BLACK;
|
|
8357
|
+
if (this.redRadio.checked) selectedColor = DOT_COLORS.RED;
|
|
8358
|
+
else if (this.greyRadio.checked) selectedColor = DOT_COLORS.GREY;
|
|
8359
|
+
else if (this.blueRadio.checked) selectedColor = DOT_COLORS.BLUE;
|
|
8312
8360
|
const fingerOptions = typeof this.currentEditFinger[2] === "object" ? this.currentEditFinger[2] : {};
|
|
8313
8361
|
this.currentEditFinger[2] = { ...fingerOptions, color: selectedColor };
|
|
8314
|
-
if (selectedColor
|
|
8362
|
+
if (selectedColor !== DOT_COLORS.BLACK) {
|
|
8315
8363
|
this.currentEditFinger[2].text = "";
|
|
8316
8364
|
this.textInput.value = "";
|
|
8317
8365
|
}
|
|
@@ -8327,7 +8375,10 @@ var EditableSVGuitarChord = class {
|
|
|
8327
8375
|
if (!this.currentEditFinger[2]) {
|
|
8328
8376
|
this.currentEditFinger[2] = {};
|
|
8329
8377
|
}
|
|
8330
|
-
|
|
8378
|
+
let selectedColor = DOT_COLORS.BLACK;
|
|
8379
|
+
if (this.redRadio.checked) selectedColor = DOT_COLORS.RED;
|
|
8380
|
+
else if (this.greyRadio.checked) selectedColor = DOT_COLORS.GREY;
|
|
8381
|
+
else if (this.blueRadio.checked) selectedColor = DOT_COLORS.BLUE;
|
|
8331
8382
|
this.currentEditFinger[2] = { text: this.textInput.value, color: selectedColor };
|
|
8332
8383
|
this.closeDialog();
|
|
8333
8384
|
this.redraw();
|
|
@@ -8543,13 +8594,17 @@ var ASCII_EQUALS = "=";
|
|
|
8543
8594
|
var ASCII_OPEN = "o";
|
|
8544
8595
|
var ASCII_MUTED = "x";
|
|
8545
8596
|
var ASCII_ROOT = "*";
|
|
8597
|
+
var ASCII_GREY = "O";
|
|
8598
|
+
var ASCII_BLUE = "+";
|
|
8546
8599
|
var UNICODE_VERTICAL = "\u2502";
|
|
8547
8600
|
var UNICODE_OPEN = "\u25CB";
|
|
8548
8601
|
var UNICODE_MUTED = "\xD7";
|
|
8549
8602
|
var UNICODE_ROOT = "\u25CF";
|
|
8603
|
+
var UNICODE_GREY = "\u25A1";
|
|
8604
|
+
var UNICODE_BLUE = "\u25A0";
|
|
8550
8605
|
var UNICODE_BOX_CHARS = "\u2552\u2550\u2564\u2555\u251C\u2500\u253C\u2524\u2514\u2534\u2518\u250C\u252C\u2510";
|
|
8551
8606
|
function isUnicodeFormat(str) {
|
|
8552
|
-
return str.includes(UNICODE_VERTICAL) || str.includes(UNICODE_OPEN) || str.includes(UNICODE_ROOT) || str.includes(UNICODE_MUTED) || [...UNICODE_BOX_CHARS].some((c2) => str.includes(c2));
|
|
8607
|
+
return str.includes(UNICODE_VERTICAL) || str.includes(UNICODE_OPEN) || str.includes(UNICODE_ROOT) || str.includes(UNICODE_MUTED) || str.includes(UNICODE_GREY) || str.includes(UNICODE_BLUE) || [...UNICODE_BOX_CHARS].some((c2) => str.includes(c2));
|
|
8553
8608
|
}
|
|
8554
8609
|
function findUnicodeGridBoundaries(lines, firstGridRowIdx) {
|
|
8555
8610
|
const firstLine = lines[firstGridRowIdx];
|
|
@@ -8626,7 +8681,12 @@ function isGridRow(line, isUnicode) {
|
|
|
8626
8681
|
}
|
|
8627
8682
|
}
|
|
8628
8683
|
function stringToFingering(fingeringStr, options = {}) {
|
|
8629
|
-
const {
|
|
8684
|
+
const {
|
|
8685
|
+
redColor = "#e74c3c",
|
|
8686
|
+
blackColor = "#000000",
|
|
8687
|
+
greyColor = "#9B9B9B",
|
|
8688
|
+
blueColor = "#4A90E2"
|
|
8689
|
+
} = options;
|
|
8630
8690
|
if (!fingeringStr || fingeringStr.trim() === "") {
|
|
8631
8691
|
return null;
|
|
8632
8692
|
}
|
|
@@ -8635,6 +8695,8 @@ function stringToFingering(fingeringStr, options = {}) {
|
|
|
8635
8695
|
const openChar = isUnicode ? UNICODE_OPEN : ASCII_OPEN;
|
|
8636
8696
|
const mutedChar = isUnicode ? UNICODE_MUTED : ASCII_MUTED;
|
|
8637
8697
|
const rootChar = isUnicode ? UNICODE_ROOT : ASCII_ROOT;
|
|
8698
|
+
const greyChar = isUnicode ? UNICODE_GREY : ASCII_GREY;
|
|
8699
|
+
const blueChar = isUnicode ? UNICODE_BLUE : ASCII_BLUE;
|
|
8638
8700
|
const fingers = [];
|
|
8639
8701
|
let title;
|
|
8640
8702
|
let position2;
|
|
@@ -8746,6 +8808,10 @@ function stringToFingering(fingeringStr, options = {}) {
|
|
|
8746
8808
|
}
|
|
8747
8809
|
if (char === rootChar) {
|
|
8748
8810
|
fingers.push([stringNum, fretNumber, { text: "", color: redColor }]);
|
|
8811
|
+
} else if (char === greyChar) {
|
|
8812
|
+
fingers.push([stringNum, fretNumber, { text: "", color: greyColor }]);
|
|
8813
|
+
} else if (char === blueChar) {
|
|
8814
|
+
fingers.push([stringNum, fretNumber, { text: "", color: blueColor }]);
|
|
8749
8815
|
} else if (char === UNICODE_OPEN || char === ASCII_OPEN) {
|
|
8750
8816
|
fingers.push([stringNum, fretNumber, { text: "", color: blackColor }]);
|
|
8751
8817
|
} else if (/\S/.test(char)) {
|