Drag Baroque charts onto a line, reorder them, set a duration, or remove a note. The AppImage no longer packages oemer, ONNX, or the models. Version 0.2.0. Co-authored-by: catpersonisme <catpersonisme@gmail.com>
This commit is contained in:
22 files changed
+569
-2231
No files matched your search
@@ -0,0 +1,99 @@
|
||||
import { DURATION_PRESETS, type DurationPreset } from "@/lib/duration";
|
||||
import { newId } from "@/lib/score";
|
||||
|
||||
export type LineNote = {
|
||||
id: string;
|
||||
pitch: string;
|
||||
quarters: number;
|
||||
label: string;
|
||||
};
|
||||
|
||||
const QUARTER = DURATION_PRESETS.find((preset) => preset.quarters === 1) ?? DURATION_PRESETS[3];
|
||||
|
||||
export function createNote(pitch: string, preset: DurationPreset = QUARTER, id = newId("n")): LineNote {
|
||||
return { id, pitch, quarters: preset.quarters, label: preset.label };
|
||||
}
|
||||
|
||||
export function insertNote(notes: LineNote[], index: number, note: LineNote): LineNote[] {
|
||||
const next = notes.slice();
|
||||
const at = Math.max(0, Math.min(index, next.length));
|
||||
next.splice(at, 0, note);
|
||||
return next;
|
||||
}
|
||||
|
||||
/** `toIndex` is the slot in the current list, counting the note that is moving. */
|
||||
export function moveNote(notes: LineNote[], id: string, toIndex: number): LineNote[] {
|
||||
const from = notes.findIndex((note) => note.id === id);
|
||||
if (from < 0) return notes;
|
||||
const next = notes.filter((note) => note.id !== id);
|
||||
const adjusted = toIndex > from ? toIndex - 1 : toIndex;
|
||||
const at = Math.max(0, Math.min(adjusted, next.length));
|
||||
next.splice(at, 0, notes[from]);
|
||||
return next;
|
||||
}
|
||||
|
||||
export function removeNote(notes: LineNote[], id: string): LineNote[] {
|
||||
return notes.filter((note) => note.id !== id);
|
||||
}
|
||||
|
||||
export function setDuration(notes: LineNote[], id: string, preset: DurationPreset): LineNote[] {
|
||||
return notes.map((note) =>
|
||||
note.id === id ? { ...note, quarters: preset.quarters, label: preset.label } : note,
|
||||
);
|
||||
}
|
||||
|
||||
export function cloneLine(notes: LineNote[]): LineNote[] {
|
||||
return notes.map((note) => ({ ...note, id: newId("n") }));
|
||||
}
|
||||
|
||||
/** -1 when the pointer is outside the line. Otherwise the insertion slot from left to right. */
|
||||
export function dropIndexFromPoint(
|
||||
pointerX: number,
|
||||
pointerY: number,
|
||||
line: { left: number; right: number; top: number; bottom: number },
|
||||
noteCenters: number[],
|
||||
slack = 36,
|
||||
): number {
|
||||
const inside =
|
||||
pointerX >= line.left - slack &&
|
||||
pointerX <= line.right + slack &&
|
||||
pointerY >= line.top - slack &&
|
||||
pointerY <= line.bottom + slack;
|
||||
if (!inside) return -1;
|
||||
for (let index = 0; index < noteCenters.length; index += 1) {
|
||||
if (pointerX < noteCenters[index]) return index;
|
||||
}
|
||||
return noteCenters.length;
|
||||
}
|
||||
|
||||
function preset(quarters: number, label: string): DurationPreset {
|
||||
return { quarters, label };
|
||||
}
|
||||
|
||||
/** Two short lines to edit. They are not a full tune. */
|
||||
export const LINE_EXAMPLES = [
|
||||
{
|
||||
id: "twinkle",
|
||||
title: "Twinkle, opening",
|
||||
blurb: "Seven notes. The last one is held.",
|
||||
notes: [
|
||||
createNote("C5", preset(1, "quarter"), "twinkle-1"),
|
||||
createNote("C5", preset(1, "quarter"), "twinkle-2"),
|
||||
createNote("G5", preset(1, "quarter"), "twinkle-3"),
|
||||
createNote("G5", preset(1, "quarter"), "twinkle-4"),
|
||||
createNote("A5", preset(1, "quarter"), "twinkle-5"),
|
||||
createNote("A5", preset(1, "quarter"), "twinkle-6"),
|
||||
createNote("G5", preset(2, "half"), "twinkle-7"),
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "ode",
|
||||
title: "Ode, held note",
|
||||
blurb: "A dotted quarter, an eighth, and a half note.",
|
||||
notes: [
|
||||
createNote("E5", preset(1.5, "dotted quarter"), "ode-1"),
|
||||
createNote("D5", preset(0.5, "eighth"), "ode-2"),
|
||||
createNote("D5", preset(2, "half"), "ode-3"),
|
||||
],
|
||||
},
|
||||
] as const;
|
||||
Reference in new issue
Block a user