feat: first version

This commit is contained in:
2021-10-06 22:05:53 +08:00
parent 9d81aaa4fb
commit 94d215037f
4 changed files with 157 additions and 23 deletions
+1
View File
@@ -14,6 +14,7 @@
<body> <body>
<noscript>要使用本程序,请启用JavaScript。</noscript> <noscript>要使用本程序,请启用JavaScript。</noscript>
<a href="https://github.com/mattuylee/numerical-notation-editor" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<div id="root"></div> <div id="root"></div>
</body> </body>
+39 -22
View File
@@ -21,6 +21,7 @@ import {
createParagraph, createParagraph,
createParagraphWithNotations, createParagraphWithNotations,
} from "../util/paragraph"; } from "../util/paragraph";
import { convertTone, convertToneTo } from "../util/tone-convert";
import { exportFile, loadFile, saveFile } from "../util/file"; import { exportFile, loadFile, saveFile } from "../util/file";
import { findParagraphAndNotation, resetGlobalData } from "../util/editor"; import { findParagraphAndNotation, resetGlobalData } from "../util/editor";
import { import {
@@ -74,9 +75,28 @@ const handleEditMenu = wrappedAction(({ key }) => {
break; break;
} }
}); });
const handleConvertMenu = wrappedAction(() => { const handleConvertMenu = ({ key }) => {
console.log(111); switch (true) {
}); case key.startsWith("convertTo"):
const destTone = key.split("-", 2)[1];
convertToneTo(destTone);
break;
case key === "convert-up":
convertTone(2);
break;
case key === "convert-down":
convertTone(-2);
break;
case key === "convert-up8":
convertTone(12);
break;
case key === "convert-down8":
convertTone(-12);
break;
default:
break;
}
};
// 画布上的点击事件 // 画布上的点击事件
const handleClick = wrappedAction((ev) => { const handleClick = wrappedAction((ev) => {
@@ -94,6 +114,9 @@ const handleKeyPress = wrappedAction((ev) => {
if (state.selectedNotationKey) { if (state.selectedNotationKey) {
// 仅选中符号时作用 // 仅选中符号时作用
if (state.helpDialogVisible || state.configDialogVisible) {
return;
}
const { const {
paragraph, paragraph,
notation, notation,
@@ -404,33 +427,27 @@ const editMenu = (
const convertMenu = ( const convertMenu = (
<Menu key="tone" onClick={handleConvertMenu}> <Menu key="tone" onClick={handleConvertMenu}>
<SubMenu key="convert-to" title="转到..."> <SubMenu key="convertTo" title="转到...">
<Menu.Item key="convert-to-C">1 = C</Menu.Item> <Menu.Item key="convertTo-C">1 = C</Menu.Item>
<Menu.Item key="convert-to-D">1 = D</Menu.Item> <Menu.Item key="convertTo-D">1 = D</Menu.Item>
<Menu.Item key="convert-to-E">1 = E</Menu.Item> <Menu.Item key="convertTo-E">1 = E</Menu.Item>
<Menu.Item key="convert-to-F">1 = F</Menu.Item> <Menu.Item key="convertTo-F">1 = F</Menu.Item>
<Menu.Item key="convert-to-G">1 = G</Menu.Item> <Menu.Item key="convertTo-G">1 = G</Menu.Item>
<Menu.Item key="convert-to-A">1 = A</Menu.Item> <Menu.Item key="convertTo-A">1 = A</Menu.Item>
<Menu.Item key="convert-to-B">1 = B</Menu.Item> <Menu.Item key="convertTo-B">1 = B</Menu.Item>
<Menu.Item key="convert-to-bC"> <Menu.Item key="convertTo-♭D">
1 = <sup></sup>C
</Menu.Item>
<Menu.Item key="convert-to-bD">
1 = <sup></sup>D 1 = <sup></sup>D
</Menu.Item> </Menu.Item>
<Menu.Item key="convert-to-bE"> <Menu.Item key="convertTo-E">
1 = <sup></sup>E 1 = <sup></sup>E
</Menu.Item> </Menu.Item>
<Menu.Item key="convert-to-bF"> <Menu.Item key="convertTo-♭G">
1 = <sup></sup>F
</Menu.Item>
<Menu.Item key="convert-to-bG">
1 = <sup></sup>G 1 = <sup></sup>G
</Menu.Item> </Menu.Item>
<Menu.Item key="convert-to-bA"> <Menu.Item key="convertTo-A">
1 = <sup></sup>A 1 = <sup></sup>A
</Menu.Item> </Menu.Item>
<Menu.Item key="convert-to-bB"> <Menu.Item key="convertTo-B">
1 = <sup></sup>B 1 = <sup></sup>B
</Menu.Item> </Menu.Item>
</SubMenu> </SubMenu>
+11 -1
View File
@@ -27,6 +27,9 @@ const separators = ["│", "‖"];
function isNote(notationOrNote) { function isNote(notationOrNote) {
return notes.includes(notationOrNote?.note || notationOrNote); return notes.includes(notationOrNote?.note || notationOrNote);
} }
function isPauseNote(notationOrNote) {
return notations.zero === (notationOrNote?.note || notationOrNote);
}
function isSeparator(notationOrNote) { function isSeparator(notationOrNote) {
return separators.includes(notationOrNote?.note || notationOrNote); return separators.includes(notationOrNote?.note || notationOrNote);
} }
@@ -56,4 +59,11 @@ function cloneNotation(notation) {
return n; return n;
} }
export { notations, isNote, isSeparator, createNotation, cloneNotation }; export {
notations,
isNote,
isPauseNote,
isSeparator,
createNotation,
cloneNotation,
};
+106
View File
@@ -0,0 +1,106 @@
import store from "../store/global";
import { wrappedAction } from "../store/history";
import { isNote, isPauseNote } from "./notation";
// 音符到音数
const noteToLevelMap = {
1: 0,
2: 2,
3: 4,
4: 5,
5: 7,
6: 9,
7: 11,
};
// 音数到音符
const levelToNoteMap = {
0: 1,
1: 1,
2: 2,
3: 2,
4: 3,
5: 4,
6: 4,
7: 5,
8: 5,
9: 6,
10: 7,
11: 7,
};
// 升降到音数
const bumpSharpToLevelMap = {
"♭": -1,
"♯": 1,
};
// 音数到升降
const levelToBumpSharpMap = {
1: "♯",
3: "♯",
6: "♯",
8: "♯",
10: "♭",
};
const toneToLevelMap = {
C: 0,
D: 2,
E: 4,
F: 5,
G: 7,
A: 9,
B: 11,
};
/**
* 整体转调
* @param {number} deltaVolume 要调整的音数
*/
const convertTone = wrappedAction(function (deltaVolume) {
deltaVolume = deltaVolume | 0;
store.paragraphs.forEach((p) => {
p.notations.forEach((n) => {
if (isNote(n) && !isPauseNote(n)) {
n.octave += Math.trunc(deltaVolume / 12);
let newLevel =
noteToLevelMap[n.note] +
(deltaVolume % 12) +
(n.prefixSups || []).reduce(
(prev, next) => prev + (bumpSharpToLevelMap[next] | 0),
0
);
if (newLevel >= 12) {
n.octave += 1;
newLevel -= 12;
} else if (newLevel < 0) {
n.octave -= 1;
newLevel += 12;
}
n.note = String(levelToNoteMap[newLevel]);
n.prefixSups = (n.prefixSups || []).filter(
(c) => c !== "♯" && c !== "♭"
);
if (levelToBumpSharpMap[newLevel]) {
n.prefixSups.unshift(levelToBumpSharpMap[newLevel]);
}
}
});
});
});
// 转到1 = *
const convertToneTo = wrappedAction((destTone) => {
let deltaVolume = -(
toneToLevelMap[destTone.split("").at(-1)] -
toneToLevelMap[store.tone.split("").at(-1)]
);
if (destTone.startsWith("♭") || store.tone.startsWith("♯")) {
deltaVolume -= 1;
}
if (destTone.startsWith("♯") || store.tone.startsWith("♭")) {
deltaVolume += 1;
}
convertTone(deltaVolume);
store.tone = destTone;
});
export { convertTone, convertToneTo };