solid-pianoroll 0.0.23 → 0.0.24
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/dist/cjs/index.js +82 -40
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +82 -40
- package/dist/esm/index.js.map +1 -1
- package/dist/source/PianoRoll.jsx +13 -9
- package/dist/source/PianoRollNotes.jsx +6 -8
- package/dist/source/PianoRollScale.jsx +15 -1
- package/dist/source/usePianoRollState.js +22 -2
- package/dist/source/viewport/PlayHead.jsx +3 -3
- package/dist/types/PianoRoll.d.ts +0 -1
- package/dist/types/PianoRollContext.d.ts +11 -88
- package/dist/types/index.d.ts +1 -0
- package/dist/types/types.d.ts +2 -0
- package/dist/types/usePianoRollState.d.ts +29 -19
- package/dist/types/viewport/PlayHead.d.ts +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -40,6 +40,7 @@ const defaultState = {
|
|
|
40
40
|
verticalPosition: 44,
|
|
41
41
|
verticalTrackZoom: 0.5,
|
|
42
42
|
verticalTrackPosition: 0,
|
|
43
|
+
playHeadPosition: 0,
|
|
43
44
|
gridDivision: 4,
|
|
44
45
|
snapToGrid: true,
|
|
45
46
|
duration: 0,
|
|
@@ -60,15 +61,25 @@ const defaultState = {
|
|
|
60
61
|
}
|
|
61
62
|
};
|
|
62
63
|
const propNameToHandlerName = name => `on${name[0]?.toUpperCase()}${name.slice(1)}Change`;
|
|
63
|
-
const pianoRollStatePropNames = [...Object.keys(defaultState), ...Object.keys(defaultState).map(propNameToHandlerName), "onNoteChange", "onInsertNote", "onRemoveNote", "onNoteDown", "onNoteUp", "isKeyDown"];
|
|
64
|
+
const pianoRollStatePropNames = [...Object.keys(defaultState), ...Object.keys(defaultState).map(propNameToHandlerName), "onNoteChange", "onInsertNote", "onRemoveNote", "onNoteDown", "onNoteUp", "isKeyDown", "snapValueToGridIfEnabled"];
|
|
64
65
|
const createPianoRollstate = initialState => {
|
|
65
66
|
const [state, setState] = createStore({
|
|
66
67
|
...defaultState,
|
|
67
68
|
...initialState
|
|
68
69
|
});
|
|
69
70
|
const handlers = Object.fromEntries(Object.entries(state).map(entry => {
|
|
70
|
-
|
|
71
|
+
const handlerName = propNameToHandlerName(entry[0]);
|
|
72
|
+
return [handlerName, (value, originalEvent) => {
|
|
73
|
+
const handler = initialState?.[handlerName];
|
|
74
|
+
setState(entry[0], value);
|
|
75
|
+
if (handler) {
|
|
76
|
+
handler(value, originalEvent);
|
|
77
|
+
}
|
|
78
|
+
}];
|
|
71
79
|
}));
|
|
80
|
+
const onPlayheadPositionChange = (playheadPosition, originalEvent) => {
|
|
81
|
+
handlers.onPlayHeadPositionChange(snapValueToGridIfEnabled(playheadPosition, !!originalEvent?.altKey));
|
|
82
|
+
};
|
|
72
83
|
const updateNotes = async (trackIndex, getNotes) => {
|
|
73
84
|
const track = state.tracks[trackIndex];
|
|
74
85
|
if (!track) return;
|
|
@@ -110,6 +121,10 @@ const createPianoRollstate = initialState => {
|
|
|
110
121
|
updateKeyPressedState(trackIndex, keyNumber, false);
|
|
111
122
|
};
|
|
112
123
|
const isKeyDown = (trackIndex, keyNumber) => !!state.pressedKeys[trackIndex]?.[keyNumber];
|
|
124
|
+
const snapValueToGridIfEnabled = (value, altKey) => {
|
|
125
|
+
const gridDivisionTicks = state.ppq * 4 / state.gridDivision;
|
|
126
|
+
return state.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks) * gridDivisionTicks : value;
|
|
127
|
+
};
|
|
113
128
|
return mergeProps(state, {
|
|
114
129
|
...handlers,
|
|
115
130
|
onNoteChange,
|
|
@@ -117,7 +132,9 @@ const createPianoRollstate = initialState => {
|
|
|
117
132
|
onRemoveNote,
|
|
118
133
|
onNoteDown,
|
|
119
134
|
onNoteUp,
|
|
120
|
-
isKeyDown
|
|
135
|
+
isKeyDown,
|
|
136
|
+
snapValueToGridIfEnabled,
|
|
137
|
+
onPlayheadPositionChange
|
|
121
138
|
});
|
|
122
139
|
};
|
|
123
140
|
|
|
@@ -130,7 +147,7 @@ const usePianoRollContext = () => {
|
|
|
130
147
|
};
|
|
131
148
|
const splitContextProps = allProps => splitProps(allProps, [...pianoRollStatePropNames, "showAllTracks", "showTrackList"]);
|
|
132
149
|
|
|
133
|
-
var css_248z$5 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\n border-width: 0;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-left-width: 1px;\n background: white;\n cursor: pointer;\n}\n\n.PianoRollKeys-module_Key__jybNC {\n transition-property: background-color, box-shadow;\n transition-duration: 200ms;\n transition-timing-function: ease-out;\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 120%;\n left: -20%;\n border-color: #000;\n border-style: solid;\n transform: rotateX(0deg);\n perspective: 100px;\n}\n\n.PianoRollKeys-module_black__7rncB {\n background: black;\n border-top-right-radius: 12%;\n border-bottom-right-radius: 12%;\n margin-left: -20%;\n z-index: 1;\n border: 1px black outset;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n border-top-width: 0.5px;\n border-bottom-width: 0.5px;\n border-top-right-radius: 4%;\n border-bottom-right-radius: 4%;\n}\n\n.PianoRollKeys-module_down__GcNeZ {\n transition: none;\n background: red;\n transform: rotateX(0deg) rotateY(20deg);\n}\n";
|
|
150
|
+
var css_248z$5 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\n border-width: 0;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-left-width: 1px;\n background: white;\n cursor: pointer;\n background: black;\n}\n\n.PianoRollKeys-module_Key__jybNC {\n transition-property: background-color, box-shadow;\n transition-duration: 200ms;\n transition-timing-function: ease-out;\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 120%;\n left: -20%;\n border-color: #000;\n border-style: solid;\n transform: rotateX(0deg);\n perspective: 100px;\n}\n\n.PianoRollKeys-module_black__7rncB {\n background: black;\n border-top-right-radius: 12%;\n border-bottom-right-radius: 12%;\n margin-left: -20%;\n z-index: 1;\n border: 1px black outset;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n border-top-width: 0.5px;\n border-bottom-width: 0.5px;\n border-top-right-radius: 4%;\n border-bottom-right-radius: 4%;\n}\n\n.PianoRollKeys-module_down__GcNeZ {\n transition: none;\n background: red;\n transform: rotateX(0deg) rotateY(20deg);\n}\n";
|
|
134
151
|
var styles$5 = {"PianoRollKeys":"PianoRollKeys-module_PianoRollKeys__5vnQ0","Key":"PianoRollKeys-module_Key__jybNC","black":"PianoRollKeys-module_black__7rncB","white":"PianoRollKeys-module_white__fR2Lm","down":"PianoRollKeys-module_down__GcNeZ"};
|
|
135
152
|
styleInject(css_248z$5);
|
|
136
153
|
|
|
@@ -474,7 +491,6 @@ const PianoRollNotes = props => {
|
|
|
474
491
|
const [currentNoteTrackIndex, setCurrentNoteTrackIndex] = createSignal(-1);
|
|
475
492
|
const [diffPosition, setDiffPosition] = createSignal(0);
|
|
476
493
|
const [getInitialNote, setInitialNote] = createSignal();
|
|
477
|
-
const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks() : value;
|
|
478
494
|
const calculateNoteDragValues = event => {
|
|
479
495
|
const targetTrackIndex = context.mode === "tracks" ? clamp(Math.floor(verticalViewPort().calculatePosition(event.clientY)), 0, context.tracks.length - 1) : currentNoteTrackIndex() > -1 ? currentNoteTrackIndex() : context.selectedTrackIndex;
|
|
480
496
|
const midi = context.mode === "keys" ? Math.floor(128 - verticalViewPort().calculatePosition(event.clientY)) : getInitialNote()?.midi ?? 60;
|
|
@@ -495,7 +511,7 @@ const PianoRollNotes = props => {
|
|
|
495
511
|
midi,
|
|
496
512
|
horiontalPosition
|
|
497
513
|
} = calculateNoteDragValues(mouseMoveEvent);
|
|
498
|
-
const ticks = snapValueToGridIfEnabled(horiontalPosition - diffPosition(), mouseMoveEvent.altKey);
|
|
514
|
+
const ticks = context.snapValueToGridIfEnabled(horiontalPosition - diffPosition(), mouseMoveEvent.altKey);
|
|
499
515
|
const updatedNote = {
|
|
500
516
|
...note,
|
|
501
517
|
midi,
|
|
@@ -504,11 +520,11 @@ const PianoRollNotes = props => {
|
|
|
504
520
|
}),
|
|
505
521
|
...(noteDragMode() === "trimStart" && {
|
|
506
522
|
ticks: ticks < note.ticks + note.durationTicks ? ticks : note.ticks + note.durationTicks,
|
|
507
|
-
durationTicks: ticks < note.ticks + note.durationTicks ? note.ticks + note.durationTicks - ticks : snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey)
|
|
523
|
+
durationTicks: ticks < note.ticks + note.durationTicks ? note.ticks + note.durationTicks - ticks : context.snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey)
|
|
508
524
|
}),
|
|
509
525
|
...(noteDragMode() === "trimEnd" && {
|
|
510
526
|
ticks: ticks < note.ticks ? ticks : note.ticks,
|
|
511
|
-
durationTicks: ticks < note.ticks ? note.ticks - ticks : snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey)
|
|
527
|
+
durationTicks: ticks < note.ticks ? note.ticks - ticks : context.snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey)
|
|
512
528
|
})
|
|
513
529
|
};
|
|
514
530
|
const previousTrackIndex = currentNoteTrackIndex();
|
|
@@ -548,7 +564,7 @@ const PianoRollNotes = props => {
|
|
|
548
564
|
midi,
|
|
549
565
|
horiontalPosition
|
|
550
566
|
} = calculateNoteDragValues(mouseDownEvent);
|
|
551
|
-
const ticks = snapValueToGridIfEnabled(horiontalPosition, mouseDownEvent.altKey);
|
|
567
|
+
const ticks = context.snapValueToGridIfEnabled(horiontalPosition, mouseDownEvent.altKey, context);
|
|
552
568
|
const durationTicks = gridDivisionTicks();
|
|
553
569
|
const newNote = {
|
|
554
570
|
midi,
|
|
@@ -615,17 +631,19 @@ const PianoRollNotes = props => {
|
|
|
615
631
|
setAttribute(_el$2, "draggable", false);
|
|
616
632
|
effect(_p$ => {
|
|
617
633
|
const _v$ = getClasses(noteDragMode()).join(" "),
|
|
618
|
-
_v$2 =
|
|
619
|
-
_v$3 =
|
|
620
|
-
_v$4 = `${verticalVirtualDimensions().
|
|
621
|
-
_v$5 = `${
|
|
622
|
-
_v$6 = `${horizontalDimensions().
|
|
634
|
+
_v$2 = `${track.color}`,
|
|
635
|
+
_v$3 = (note.velocity / 128 + 2) / 3,
|
|
636
|
+
_v$4 = `${verticalVirtualDimensions().offset}px`,
|
|
637
|
+
_v$5 = `${verticalVirtualDimensions().size}px`,
|
|
638
|
+
_v$6 = `${horizontalDimensions().offset}px`,
|
|
639
|
+
_v$7 = `${horizontalDimensions().size}px`;
|
|
623
640
|
_v$ !== _p$._v$ && className(_el$2, _p$._v$ = _v$);
|
|
624
641
|
_v$2 !== _p$._v$2 && _el$2.style.setProperty("background-color", _p$._v$2 = _v$2);
|
|
625
|
-
_v$3 !== _p$._v$3 && _el$2.style.setProperty("
|
|
626
|
-
_v$4 !== _p$._v$4 && _el$2.style.setProperty("
|
|
627
|
-
_v$5 !== _p$._v$5 && _el$2.style.setProperty("
|
|
628
|
-
_v$6 !== _p$._v$6 && _el$2.style.setProperty("
|
|
642
|
+
_v$3 !== _p$._v$3 && _el$2.style.setProperty("opacity", _p$._v$3 = _v$3);
|
|
643
|
+
_v$4 !== _p$._v$4 && _el$2.style.setProperty("top", _p$._v$4 = _v$4);
|
|
644
|
+
_v$5 !== _p$._v$5 && _el$2.style.setProperty("height", _p$._v$5 = _v$5);
|
|
645
|
+
_v$6 !== _p$._v$6 && _el$2.style.setProperty("left", _p$._v$6 = _v$6);
|
|
646
|
+
_v$7 !== _p$._v$7 && _el$2.style.setProperty("width", _p$._v$7 = _v$7);
|
|
629
647
|
return _p$;
|
|
630
648
|
}, {
|
|
631
649
|
_v$: undefined,
|
|
@@ -633,7 +651,8 @@ const PianoRollNotes = props => {
|
|
|
633
651
|
_v$3: undefined,
|
|
634
652
|
_v$4: undefined,
|
|
635
653
|
_v$5: undefined,
|
|
636
|
-
_v$6: undefined
|
|
654
|
+
_v$6: undefined,
|
|
655
|
+
_v$7: undefined
|
|
637
656
|
});
|
|
638
657
|
return _el$2;
|
|
639
658
|
}
|
|
@@ -1060,8 +1079,22 @@ const _tmpl$$2 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
|
1060
1079
|
const PianoRollScale = () => {
|
|
1061
1080
|
const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
|
|
1062
1081
|
const grid = usePianoRollGrid();
|
|
1082
|
+
const context = usePianoRollContext();
|
|
1083
|
+
const updatePlayheadPosition = event => {
|
|
1084
|
+
const position = horizontalViewPort().calculatePosition(event.clientX);
|
|
1085
|
+
context.onPlayHeadPositionChange(position, event);
|
|
1086
|
+
};
|
|
1063
1087
|
return (() => {
|
|
1064
1088
|
const _el$ = _tmpl$$2.cloneNode(true);
|
|
1089
|
+
_el$.$$mousedown = event => {
|
|
1090
|
+
updatePlayheadPosition(event);
|
|
1091
|
+
const handleMouseUp = () => {
|
|
1092
|
+
window.removeEventListener("mousemove", updatePlayheadPosition);
|
|
1093
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
1094
|
+
};
|
|
1095
|
+
window.addEventListener("mousemove", updatePlayheadPosition);
|
|
1096
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
1097
|
+
};
|
|
1065
1098
|
insert(_el$, createComponent(Index, {
|
|
1066
1099
|
get each() {
|
|
1067
1100
|
return grid();
|
|
@@ -1110,10 +1143,12 @@ const PianoRollScale = () => {
|
|
|
1110
1143
|
return _el$;
|
|
1111
1144
|
})();
|
|
1112
1145
|
};
|
|
1146
|
+
delegateEvents(["mousedown"]);
|
|
1113
1147
|
|
|
1114
1148
|
const _tmpl$$1 = /*#__PURE__*/template(`<div><button><div></div></button></div>`, 6),
|
|
1115
|
-
_tmpl$2 = /*#__PURE__*/template(`<div><div
|
|
1116
|
-
_tmpl$3 = /*#__PURE__*/template(`<div></div>`,
|
|
1149
|
+
_tmpl$2 = /*#__PURE__*/template(`<div><div></div><div></div></div>`, 6),
|
|
1150
|
+
_tmpl$3 = /*#__PURE__*/template(`<div><div><div></div></div></div>`, 6),
|
|
1151
|
+
_tmpl$4 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
1117
1152
|
const PianoRoll = allProps => {
|
|
1118
1153
|
const propsWithDefaults = mergeProps({
|
|
1119
1154
|
showAllTracks: false
|
|
@@ -1122,7 +1157,7 @@ const PianoRoll = allProps => {
|
|
|
1122
1157
|
return createComponent(PianoRollContextProvider, {
|
|
1123
1158
|
value: context,
|
|
1124
1159
|
get children() {
|
|
1125
|
-
const _el$ = _tmpl$
|
|
1160
|
+
const _el$ = _tmpl$4.cloneNode(true);
|
|
1126
1161
|
spread(_el$, mergeProps$1(divProps, {
|
|
1127
1162
|
get ["class"]() {
|
|
1128
1163
|
return styles$6.PianoRoll;
|
|
@@ -1131,11 +1166,9 @@ const PianoRoll = allProps => {
|
|
|
1131
1166
|
insert(_el$, createComponent(PianoRollScrollZoomViewPort, {
|
|
1132
1167
|
get children() {
|
|
1133
1168
|
return [(() => {
|
|
1134
|
-
const _el$2 = _tmpl$
|
|
1169
|
+
const _el$2 = _tmpl$3.cloneNode(true),
|
|
1135
1170
|
_el$3 = _el$2.firstChild,
|
|
1136
|
-
_el$7 = _el$3.firstChild
|
|
1137
|
-
_el$8 = _el$3.nextSibling,
|
|
1138
|
-
_el$9 = _el$8.firstChild;
|
|
1171
|
+
_el$7 = _el$3.firstChild;
|
|
1139
1172
|
insert(_el$2, createComponent(ZoomSliderControl, {
|
|
1140
1173
|
orientation: "vertical",
|
|
1141
1174
|
dimensionName: "verticalTracks"
|
|
@@ -1149,6 +1182,7 @@ const PianoRoll = allProps => {
|
|
|
1149
1182
|
_el$5 = _el$4.firstChild,
|
|
1150
1183
|
_el$6 = _el$5.firstChild;
|
|
1151
1184
|
_el$4.style.setProperty("height", "30px");
|
|
1185
|
+
_el$4.style.setProperty("border-right", "1px black solid");
|
|
1152
1186
|
_el$5.$$click = () => context.onModeChange(context.mode === "keys" ? "tracks" : "keys");
|
|
1153
1187
|
_el$5.style.setProperty("font-size", "16px");
|
|
1154
1188
|
_el$5.style.setProperty("line-height", "16px");
|
|
@@ -1182,16 +1216,26 @@ const PianoRoll = allProps => {
|
|
|
1182
1216
|
return createComponent(PianoRollKeys, {});
|
|
1183
1217
|
}
|
|
1184
1218
|
}), null);
|
|
1185
|
-
_el$
|
|
1186
|
-
_el$8.style.setProperty("display", "flex");
|
|
1187
|
-
_el$8.style.setProperty("height", "100%");
|
|
1188
|
-
_el$8.style.setProperty("flex-direction", "column");
|
|
1189
|
-
_el$8.style.setProperty("overflow", "hidden");
|
|
1190
|
-
_el$9.style.setProperty("height", "30px");
|
|
1191
|
-
insert(_el$9, createComponent(PianoRollScale, {}));
|
|
1192
|
-
insert(_el$8, createComponent(PianoRollNotesScroller, {
|
|
1219
|
+
insert(_el$2, createComponent(PianoRollNotesScroller, {
|
|
1193
1220
|
get children() {
|
|
1194
|
-
return [memo(() => allProps.children),
|
|
1221
|
+
return [memo(() => allProps.children), (() => {
|
|
1222
|
+
const _el$8 = _tmpl$2.cloneNode(true),
|
|
1223
|
+
_el$9 = _el$8.firstChild,
|
|
1224
|
+
_el$10 = _el$9.nextSibling;
|
|
1225
|
+
_el$8.style.setProperty("width", "100%");
|
|
1226
|
+
_el$8.style.setProperty("display", "flex");
|
|
1227
|
+
_el$8.style.setProperty("height", "100%");
|
|
1228
|
+
_el$8.style.setProperty("flex-direction", "column");
|
|
1229
|
+
_el$8.style.setProperty("overflow", "hidden");
|
|
1230
|
+
_el$9.style.setProperty("height", "30px");
|
|
1231
|
+
insert(_el$9, createComponent(PianoRollScale, {}));
|
|
1232
|
+
_el$10.style.setProperty("flex", "1");
|
|
1233
|
+
_el$10.style.setProperty("position", "relative");
|
|
1234
|
+
_el$10.style.setProperty("overflow", "hidden");
|
|
1235
|
+
insert(_el$10, createComponent(PianoRollGrid, {}), null);
|
|
1236
|
+
insert(_el$10, createComponent(PianoRollNotes, {}), null);
|
|
1237
|
+
return _el$8;
|
|
1238
|
+
})()];
|
|
1195
1239
|
}
|
|
1196
1240
|
}), null);
|
|
1197
1241
|
insert(_el$2, createComponent(ZoomSliderControl, {
|
|
@@ -1259,11 +1303,9 @@ const PlayHead = allProps => {
|
|
|
1259
1303
|
"onMouseDown": event => {
|
|
1260
1304
|
event.preventDefault();
|
|
1261
1305
|
event.stopPropagation();
|
|
1262
|
-
const handleMouseMove =
|
|
1263
|
-
clientX
|
|
1264
|
-
|
|
1265
|
-
const newPosition = viewPort.calculatePosition(clientX);
|
|
1266
|
-
props.onPositionChange?.(newPosition);
|
|
1306
|
+
const handleMouseMove = event => {
|
|
1307
|
+
const newPosition = viewPort.calculatePosition(event.clientX);
|
|
1308
|
+
props.onPositionChange?.(newPosition, event);
|
|
1267
1309
|
};
|
|
1268
1310
|
const handleMouseUp = () => {
|
|
1269
1311
|
window.removeEventListener("mousemove", handleMouseMove);
|