solid-pianoroll 0.0.15 → 0.0.17
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 +423 -236
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +430 -243
- package/dist/esm/index.js.map +1 -1
- package/dist/source/PianoRoll.jsx +49 -25
- package/dist/source/PianoRollContext.jsx +27 -14
- package/dist/source/PianoRollGrid.jsx +1 -1
- package/dist/source/PianoRollKeys.jsx +59 -6
- package/dist/source/PianoRollNotes.jsx +4 -3
- package/dist/source/PianoRollTrackList.jsx +2 -2
- package/dist/source/index.jsx +2 -2
- package/dist/source/usePianoRollState.js +92 -0
- package/dist/source/viewport/HorizontalZoomControl.jsx +4 -3
- package/dist/source/viewport/ScrollContainer.jsx +27 -10
- package/dist/source/viewport/VerticalZoomControl.jsx +5 -3
- package/dist/types/PianoRoll.d.ts +3 -22
- package/dist/types/PianoRollContext.d.ts +73 -4
- package/dist/types/index.d.ts +2 -2
- package/dist/types/usePianoRollState.d.ts +52 -0
- package/dist/types/viewport/HorizontalZoomControl.d.ts +3 -1
- package/dist/types/viewport/ScrollContainer.d.ts +5 -2
- package/dist/types/viewport/ScrollZoomViewPort.d.ts +1 -1
- package/dist/types/viewport/VerticalZoomControl.d.ts +3 -1
- package/dist/types/viewport/createViewPortDimension.d.ts +2 -2
- package/package.json +1 -1
- package/dist/source/usePianoRoll.js +0 -33
- package/dist/types/usePianoRoll.d.ts +0 -22
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createComponent,
|
|
2
|
-
import { createContext, splitProps, useContext, createEffect, createMemo, Index, Show,
|
|
1
|
+
import { createComponent, use, spread, mergeProps as mergeProps$1, insert, effect, template, delegateEvents, className, classList, setAttribute, memo } from 'solid-js/web';
|
|
2
|
+
import { createContext, splitProps, useContext, createEffect, mergeProps, createMemo, createSignal, Index, Show, batch, For } from 'solid-js';
|
|
3
3
|
import { createStore } from 'solid-js/store';
|
|
4
4
|
|
|
5
5
|
function styleInject(css, ref) {
|
|
@@ -27,9 +27,9 @@ function styleInject(css, ref) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
var css_248z$
|
|
31
|
-
var styles$
|
|
32
|
-
styleInject(css_248z$
|
|
30
|
+
var css_248z$5 = ".PianoRoll-module_PianoRoll__rkRYx {\n box-sizing: border-box;\n display: flex;\n overflow: hidden;\n flex-direction: column;\n height: 100%;\n}\n\n.PianoRoll-module_PianoRollContainer__Oyxr7 {\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: row;\n}\n";
|
|
31
|
+
var styles$5 = {"PianoRoll":"PianoRoll-module_PianoRoll__rkRYx","PianoRollContainer":"PianoRoll-module_PianoRollContainer__Oyxr7"};
|
|
32
|
+
styleInject(css_248z$5);
|
|
33
33
|
|
|
34
34
|
const PianoRollContext = createContext();
|
|
35
35
|
const PianoRollContextProvider = PianoRollContext.Provider;
|
|
@@ -38,11 +38,11 @@ const usePianoRollContext = () => {
|
|
|
38
38
|
if (!context) throw new Error("No PianoRollContext found");
|
|
39
39
|
return context;
|
|
40
40
|
};
|
|
41
|
-
const splitContextProps = allProps => splitProps(allProps, ["mode", "
|
|
41
|
+
const splitContextProps = allProps => splitProps(allProps, ["ppq", "mode", "position", "zoom", "verticalZoom", "verticalPosition", "verticalTrackZoom", "verticalTrackPosition", "gridDivision", "snapToGrid", "duration", "tracks", "selectedTrackIndex", "pressedKeys", "onPpqChange", "onModeChange", "onPositionChange", "onZoomChange", "onVerticalZoomChange", "onVerticalPositionChange", "onVerticalTrackZoomChange", "onVerticalTrackPositionChange", "onGridDivisionChange", "onSnapToGridChange", "onDurationChange", "onTracksChange", "onNoteChange", "onInsertNote", "onRemoveNote", "onSelectedTrackIndexChange", "onPressedKeysChange", "showAllTracks", "showTrackList"]);
|
|
42
42
|
|
|
43
|
-
var css_248z$
|
|
44
|
-
var styles$
|
|
45
|
-
styleInject(css_248z$
|
|
43
|
+
var css_248z$4 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\n width: 50px;\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 overflow: hidden;\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}\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}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n border-top-width: 0.5px;\n border-bottom-width: 0.5px;\n}\n\n.PianoRollKeys-module_down__GcNeZ {\n transition: none;\n background: red;\n}\n";
|
|
44
|
+
var styles$4 = {"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"};
|
|
45
|
+
styleInject(css_248z$4);
|
|
46
46
|
|
|
47
47
|
function createViewPortDimension(getState) {
|
|
48
48
|
const getStateWithFunctions = () => ({
|
|
@@ -116,55 +116,248 @@ const useViewPortDimension = name => {
|
|
|
116
116
|
return viewPort;
|
|
117
117
|
};
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
var css_248z$3 = ".ScrollContainer-module_ScrollContainer__As0vK {\n height: 100%;\n width: 100%;\n z-index: 4;\n pointer-events: auto;\n}\n";
|
|
120
|
+
var styles$3 = {"ScrollContainer":"ScrollContainer-module_ScrollContainer__As0vK"};
|
|
121
|
+
styleInject(css_248z$3);
|
|
122
|
+
|
|
123
|
+
const _tmpl$$8 = /*#__PURE__*/template(`<div><div><div><div></div></div></div></div>`, 8);
|
|
124
|
+
const ScrollContainer = props => {
|
|
125
|
+
let scrollContentRef;
|
|
126
|
+
const [ownProps, divProps] = splitProps(props, ["ref", "verticalDimensionName", "horizontalDimensionName", "showScrollbar"]);
|
|
127
|
+
const propsWithDefaults = mergeProps({
|
|
128
|
+
verticalDimensionName: "vertical",
|
|
129
|
+
horizontalDimensionName: "horizontal",
|
|
130
|
+
showScrollbar: true
|
|
131
|
+
}, ownProps);
|
|
132
|
+
const verticalViewPort = createMemo(() => useViewPortDimension(propsWithDefaults.verticalDimensionName));
|
|
133
|
+
const horizontalViewPort = createMemo(() => useViewPortDimension(propsWithDefaults.horizontalDimensionName));
|
|
134
|
+
const handleScroll = event => {
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
if (didUpdateScroll) {
|
|
137
|
+
didUpdateScroll = false;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
141
|
+
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
142
|
+
const height = verticalViewPort().pixelSize;
|
|
143
|
+
const width = horizontalViewPort().pixelSize;
|
|
144
|
+
const {
|
|
145
|
+
scrollTop,
|
|
146
|
+
scrollLeft,
|
|
147
|
+
scrollWidth,
|
|
148
|
+
scrollHeight
|
|
149
|
+
} = event.currentTarget;
|
|
150
|
+
const scrollTopAmount = scrollTop / (scrollHeight - height);
|
|
151
|
+
const scrollLeftAmount = scrollLeft / (scrollWidth - width);
|
|
152
|
+
verticalViewPort().onPositionChange?.(maxVerticalPosition * scrollTopAmount);
|
|
153
|
+
horizontalViewPort().onPositionChange?.(maxPosition * scrollLeftAmount);
|
|
154
|
+
};
|
|
155
|
+
const handleWheel = event => {
|
|
156
|
+
if (event.altKey) {
|
|
157
|
+
event.preventDefault();
|
|
158
|
+
if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
|
|
159
|
+
horizontalViewPort()?.onZoomChange?.(horizontalViewPort().zoom * (1 + event.deltaX / horizontalViewPort().pixelSize));
|
|
160
|
+
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
161
|
+
horizontalViewPort()?.onPositionChange?.(Math.min(maxPosition, horizontalViewPort()?.position));
|
|
162
|
+
} else {
|
|
163
|
+
verticalViewPort()?.onZoomChange?.(verticalViewPort().zoom * (1 + event.deltaY / verticalViewPort().pixelSize));
|
|
164
|
+
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
165
|
+
verticalViewPort()?.onPositionChange?.(Math.min(maxVerticalPosition, verticalViewPort()?.position));
|
|
166
|
+
}
|
|
167
|
+
} else if (!props.showScrollbar) {
|
|
168
|
+
event.preventDefault();
|
|
169
|
+
event.currentTarget.scrollLeft += event.deltaX;
|
|
170
|
+
event.currentTarget.scrollTop += event.deltaY;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
let didUpdateScroll = false;
|
|
174
|
+
createEffect(() => {
|
|
175
|
+
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
176
|
+
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
177
|
+
const scrollTopAmount = maxVerticalPosition > 0 ? verticalViewPort().position / maxVerticalPosition : 0;
|
|
178
|
+
const scrollLeftAmount = maxPosition > 0 ? horizontalViewPort().position / maxPosition : 0;
|
|
179
|
+
const height = verticalViewPort().pixelSize;
|
|
180
|
+
const width = horizontalViewPort().pixelSize;
|
|
181
|
+
if (!scrollContentRef?.parentElement) return;
|
|
182
|
+
const scrollDivHeight = verticalViewPort().zoom * verticalViewPort().pixelSize;
|
|
183
|
+
const scrollTop = scrollTopAmount * (scrollDivHeight - height);
|
|
184
|
+
const scrollDivWidth = horizontalViewPort().zoom * horizontalViewPort().pixelSize;
|
|
185
|
+
const scrollLeft = scrollLeftAmount * (scrollDivWidth - width);
|
|
186
|
+
didUpdateScroll = true;
|
|
187
|
+
scrollContentRef.style.height = `${scrollDivHeight}px`;
|
|
188
|
+
scrollContentRef.style.width = `${scrollDivWidth}px`;
|
|
189
|
+
scrollContentRef.parentElement.scrollTo({
|
|
190
|
+
left: scrollLeft,
|
|
191
|
+
top: scrollTop
|
|
192
|
+
});
|
|
193
|
+
});
|
|
122
194
|
return (() => {
|
|
123
|
-
const _el$ = _tmpl$$8.cloneNode(true)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
_v$3 = key().number % 12,
|
|
144
|
-
_v$4 = `${virtualDimensions().offset}px`,
|
|
145
|
-
_v$5 = `${virtualDimensions().size}px`;
|
|
146
|
-
_p$._v$ = classList(_el$2, _v$, _p$._v$);
|
|
147
|
-
_v$2 !== _p$._v$2 && setAttribute(_el$2, "title", _p$._v$2 = _v$2);
|
|
148
|
-
_v$3 !== _p$._v$3 && setAttribute(_el$2, "data-index", _p$._v$3 = _v$3);
|
|
149
|
-
_v$4 !== _p$._v$4 && _el$2.style.setProperty("top", _p$._v$4 = _v$4);
|
|
150
|
-
_v$5 !== _p$._v$5 && _el$2.style.setProperty("height", _p$._v$5 = _v$5);
|
|
151
|
-
return _p$;
|
|
152
|
-
}, {
|
|
153
|
-
_v$: undefined,
|
|
154
|
-
_v$2: undefined,
|
|
155
|
-
_v$3: undefined,
|
|
156
|
-
_v$4: undefined,
|
|
157
|
-
_v$5: undefined
|
|
158
|
-
});
|
|
159
|
-
return _el$2;
|
|
160
|
-
}
|
|
161
|
-
});
|
|
195
|
+
const _el$ = _tmpl$$8.cloneNode(true),
|
|
196
|
+
_el$2 = _el$.firstChild,
|
|
197
|
+
_el$3 = _el$2.firstChild,
|
|
198
|
+
_el$4 = _el$3.firstChild;
|
|
199
|
+
_el$.addEventListener("wheel", handleWheel);
|
|
200
|
+
_el$.addEventListener("scroll", handleScroll);
|
|
201
|
+
const _ref$ = props.ref;
|
|
202
|
+
typeof _ref$ === "function" ? use(_ref$, _el$) : props.ref = _el$;
|
|
203
|
+
spread(_el$, mergeProps$1({
|
|
204
|
+
get style() {
|
|
205
|
+
return {
|
|
206
|
+
overflow: propsWithDefaults.showScrollbar ? "scroll" : "hidden",
|
|
207
|
+
...(typeof divProps.style === "object" && divProps.style)
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
get classList() {
|
|
211
|
+
return {
|
|
212
|
+
[styles$3.ScrollContainer]: true,
|
|
213
|
+
...divProps.classList
|
|
214
|
+
};
|
|
162
215
|
}
|
|
163
|
-
}));
|
|
164
|
-
|
|
216
|
+
}, divProps), false, true);
|
|
217
|
+
const _ref$2 = scrollContentRef;
|
|
218
|
+
typeof _ref$2 === "function" ? use(_ref$2, _el$2) : scrollContentRef = _el$2;
|
|
219
|
+
_el$3.style.setProperty("top", "0");
|
|
220
|
+
_el$3.style.setProperty("left", "0");
|
|
221
|
+
_el$3.style.setProperty("position", "sticky");
|
|
222
|
+
_el$3.style.setProperty("display", "flex");
|
|
223
|
+
_el$4.style.setProperty("position", "relative");
|
|
224
|
+
insert(_el$4, () => props.children);
|
|
225
|
+
effect(_p$ => {
|
|
226
|
+
const _v$ = `${verticalViewPort().pixelSize}px`,
|
|
227
|
+
_v$2 = `${horizontalViewPort().pixelSize}px`,
|
|
228
|
+
_v$3 = `${verticalViewPort().pixelSize}px`,
|
|
229
|
+
_v$4 = `${horizontalViewPort().pixelSize}px`;
|
|
230
|
+
_v$ !== _p$._v$ && _el$3.style.setProperty("height", _p$._v$ = _v$);
|
|
231
|
+
_v$2 !== _p$._v$2 && _el$3.style.setProperty("width", _p$._v$2 = _v$2);
|
|
232
|
+
_v$3 !== _p$._v$3 && _el$4.style.setProperty("height", _p$._v$3 = _v$3);
|
|
233
|
+
_v$4 !== _p$._v$4 && _el$4.style.setProperty("width", _p$._v$4 = _v$4);
|
|
234
|
+
return _p$;
|
|
235
|
+
}, {
|
|
236
|
+
_v$: undefined,
|
|
237
|
+
_v$2: undefined,
|
|
238
|
+
_v$3: undefined,
|
|
239
|
+
_v$4: undefined
|
|
240
|
+
});
|
|
165
241
|
return _el$;
|
|
166
242
|
})();
|
|
167
243
|
};
|
|
244
|
+
|
|
245
|
+
const _tmpl$$7 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
246
|
+
const PianoRollKeys = () => {
|
|
247
|
+
const viewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
248
|
+
const [isMouseDown, setIsMouseDown] = createSignal(false);
|
|
249
|
+
const context = usePianoRollContext();
|
|
250
|
+
const handleMouseUp = () => {
|
|
251
|
+
setIsMouseDown(false);
|
|
252
|
+
};
|
|
253
|
+
createEffect(() => {
|
|
254
|
+
if (isMouseDown()) {
|
|
255
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
256
|
+
} else {
|
|
257
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
return createComponent(ScrollContainer, {
|
|
261
|
+
get classList() {
|
|
262
|
+
return {
|
|
263
|
+
[styles$4.PianoRollKeys]: true
|
|
264
|
+
};
|
|
265
|
+
},
|
|
266
|
+
showScrollbar: false,
|
|
267
|
+
get children() {
|
|
268
|
+
return createComponent(Index, {
|
|
269
|
+
each: keys,
|
|
270
|
+
children: key => {
|
|
271
|
+
const isDown = createMemo(() => context.pressedKeys.includes(key().number));
|
|
272
|
+
const handleKeyDown = () => {
|
|
273
|
+
context.onPressedKeysChange?.([...context.pressedKeys, key().number]);
|
|
274
|
+
};
|
|
275
|
+
const handleKeyUp = () => {
|
|
276
|
+
context.onPressedKeysChange?.([...context.pressedKeys].filter(number => number !== key().number));
|
|
277
|
+
};
|
|
278
|
+
const virtualDimensions = createMemo(() => viewPort().calculatePixelDimensions(127 - key().number, 1));
|
|
279
|
+
const previousIsBlack = blackKeys.includes((key().number - 1) % 12);
|
|
280
|
+
const nextIsBlack = blackKeys.includes((key().number + 1) % 12);
|
|
281
|
+
return createComponent(Show, {
|
|
282
|
+
get when() {
|
|
283
|
+
return virtualDimensions().size > 0;
|
|
284
|
+
},
|
|
285
|
+
get children() {
|
|
286
|
+
const _el$ = _tmpl$$7.cloneNode(true);
|
|
287
|
+
_el$.addEventListener("mouseleave", () => {
|
|
288
|
+
if (isMouseDown()) {
|
|
289
|
+
handleKeyUp();
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
_el$.addEventListener("mouseenter", () => {
|
|
293
|
+
if (isMouseDown()) {
|
|
294
|
+
handleKeyDown();
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
_el$.$$mouseup = () => {
|
|
298
|
+
handleKeyUp();
|
|
299
|
+
};
|
|
300
|
+
_el$.$$mousedown = () => {
|
|
301
|
+
setIsMouseDown(true);
|
|
302
|
+
handleKeyDown();
|
|
303
|
+
};
|
|
304
|
+
insert(_el$, createComponent(Show, {
|
|
305
|
+
get when() {
|
|
306
|
+
return key().isBlack && false;
|
|
307
|
+
},
|
|
308
|
+
get children() {
|
|
309
|
+
const _el$2 = _tmpl$$7.cloneNode(true);
|
|
310
|
+
effect(_p$ => {
|
|
311
|
+
const _v$ = styles$4["black-separator"],
|
|
312
|
+
_v$2 = `${virtualDimensions().offset}px`,
|
|
313
|
+
_v$3 = `${virtualDimensions().size / 2 - 0.25}px`;
|
|
314
|
+
_v$ !== _p$._v$ && className(_el$2, _p$._v$ = _v$);
|
|
315
|
+
_v$2 !== _p$._v$2 && _el$2.style.setProperty("top", _p$._v$2 = _v$2);
|
|
316
|
+
_v$3 !== _p$._v$3 && _el$2.style.setProperty("height", _p$._v$3 = _v$3);
|
|
317
|
+
return _p$;
|
|
318
|
+
}, {
|
|
319
|
+
_v$: undefined,
|
|
320
|
+
_v$2: undefined,
|
|
321
|
+
_v$3: undefined
|
|
322
|
+
});
|
|
323
|
+
return _el$2;
|
|
324
|
+
}
|
|
325
|
+
}));
|
|
326
|
+
effect(_p$ => {
|
|
327
|
+
const _v$4 = {
|
|
328
|
+
[styles$4["Key"]]: true,
|
|
329
|
+
[styles$4["black"]]: key().isBlack,
|
|
330
|
+
[styles$4["white"]]: !key().isBlack,
|
|
331
|
+
[styles$4["down"]]: isDown()
|
|
332
|
+
},
|
|
333
|
+
_v$5 = key().name,
|
|
334
|
+
_v$6 = key().number % 12,
|
|
335
|
+
_v$7 = `${virtualDimensions().offset - (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0)}px`,
|
|
336
|
+
_v$8 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
|
|
337
|
+
_v$9 = [`0px 0px ${Math.min(virtualDimensions().size / 20, 1)}px ${Math.min(virtualDimensions().size / 50, 1)}px rgba(0, 0, 0, 0.5) ${key().isBlack ? "" : "inset"}`, isDown() && `0px 0px ${Math.min(virtualDimensions().size / 8, 2)}px ${Math.min(virtualDimensions().size / 20, 2)}px rgba(0, 0, 0, 0.5) inset`].filter(item => !!item).join(", ");
|
|
338
|
+
_p$._v$4 = classList(_el$, _v$4, _p$._v$4);
|
|
339
|
+
_v$5 !== _p$._v$5 && setAttribute(_el$, "title", _p$._v$5 = _v$5);
|
|
340
|
+
_v$6 !== _p$._v$6 && setAttribute(_el$, "data-index", _p$._v$6 = _v$6);
|
|
341
|
+
_v$7 !== _p$._v$7 && _el$.style.setProperty("top", _p$._v$7 = _v$7);
|
|
342
|
+
_v$8 !== _p$._v$8 && _el$.style.setProperty("height", _p$._v$8 = _v$8);
|
|
343
|
+
_v$9 !== _p$._v$9 && _el$.style.setProperty("box-shadow", _p$._v$9 = _v$9);
|
|
344
|
+
return _p$;
|
|
345
|
+
}, {
|
|
346
|
+
_v$4: undefined,
|
|
347
|
+
_v$5: undefined,
|
|
348
|
+
_v$6: undefined,
|
|
349
|
+
_v$7: undefined,
|
|
350
|
+
_v$8: undefined,
|
|
351
|
+
_v$9: undefined
|
|
352
|
+
});
|
|
353
|
+
return _el$;
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
};
|
|
168
361
|
const blackKeys = [1, 3, 6, 8, 10];
|
|
169
362
|
const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
170
363
|
const keys = Array.from({
|
|
@@ -174,15 +367,16 @@ const keys = Array.from({
|
|
|
174
367
|
name: `${keyNames[index % 12]} ${Math.floor(index / 12) - 2}`,
|
|
175
368
|
isBlack: blackKeys.includes(index % 12)
|
|
176
369
|
}));
|
|
370
|
+
delegateEvents(["mousedown", "mouseup"]);
|
|
177
371
|
|
|
178
372
|
var css_248z$2 = ".PianoRollNotes-module_PianoRollNotes__6pF-y {\n position: absolute;\n flex: 1;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 1;\n cursor: grab;\n}\n.PianoRollNotes-module_PianoRollNotes__6pF-y .PianoRollNotes-module_Note__-jxLb {\n position: absolute;\n box-sizing: border-box;\n border-width: 0.5px;\n border-style: solid;\n border-color: #a00;\n cursor: move;\n}\n.PianoRollNotes-module_PianoRollNotes__6pF-y .PianoRollNotes-module_Note__-jxLb.PianoRollNotes-module_trimStart__vuBlj {\n cursor: w-resize;\n}\n.PianoRollNotes-module_PianoRollNotes__6pF-y .PianoRollNotes-module_Note__-jxLb.PianoRollNotes-module_trimEnd__zPdjr {\n cursor: e-resize;\n}";
|
|
179
373
|
var styles$2 = {"PianoRollNotes":"PianoRollNotes-module_PianoRollNotes__6pF-y","Note":"PianoRollNotes-module_Note__-jxLb","trimStart":"PianoRollNotes-module_trimStart__vuBlj","trimEnd":"PianoRollNotes-module_trimEnd__zPdjr"};
|
|
180
374
|
styleInject(css_248z$2);
|
|
181
375
|
|
|
182
|
-
const _tmpl$$
|
|
376
|
+
const _tmpl$$6 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
183
377
|
const PianoRollNotes = props => {
|
|
184
378
|
const context = usePianoRollContext();
|
|
185
|
-
const verticalViewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
379
|
+
const verticalViewPort = createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
|
|
186
380
|
const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
|
|
187
381
|
const gridDivisionTicks = createMemo(() => context.ppq * 4 / context.gridDivision);
|
|
188
382
|
const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks() : value;
|
|
@@ -190,7 +384,7 @@ const PianoRollNotes = props => {
|
|
|
190
384
|
const position = horizontalViewPort().calculatePosition(event.clientX);
|
|
191
385
|
const existingNote = currentNote();
|
|
192
386
|
const midi = context.mode === "keys" ? 127 - Math.floor(verticalViewPort().calculatePosition(event.clientY)) : existingNote?.midi ?? 60;
|
|
193
|
-
const targetTrackIndex = context.mode === "tracks" ? Math.floor(verticalViewPort().calculatePosition(event.clientY)) : context.selectedTrackIndex ?? 0;
|
|
387
|
+
const targetTrackIndex = context.mode === "tracks" ? clamp(Math.floor(verticalViewPort().calculatePosition(event.clientY)), 0, context.tracks.length - 1) : context.selectedTrackIndex ?? 0;
|
|
194
388
|
const eventPositionTicks = Math.floor(position / gridDivisionTicks()) * gridDivisionTicks();
|
|
195
389
|
const velocity = 127;
|
|
196
390
|
const ticks = existingNote?.ticks ?? eventPositionTicks;
|
|
@@ -218,7 +412,7 @@ const PianoRollNotes = props => {
|
|
|
218
412
|
return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
|
|
219
413
|
};
|
|
220
414
|
return (() => {
|
|
221
|
-
const _el$ = _tmpl$$
|
|
415
|
+
const _el$ = _tmpl$$6.cloneNode(true);
|
|
222
416
|
_el$.$$click = event => {
|
|
223
417
|
if (currentNote()) {
|
|
224
418
|
setCurrentNoteIndex(-1);
|
|
@@ -276,7 +470,7 @@ const PianoRollNotes = props => {
|
|
|
276
470
|
return memo(() => !!verticalViewPort().isVisible(verticalVirtualDimensions()))() && horizontalViewPort().isVisible(horizontalDimensions());
|
|
277
471
|
},
|
|
278
472
|
get children() {
|
|
279
|
-
const _el$2 = _tmpl$$
|
|
473
|
+
const _el$2 = _tmpl$$6.cloneNode(true);
|
|
280
474
|
_el$2.$$mousedown = event => {
|
|
281
475
|
event.stopPropagation();
|
|
282
476
|
setIsDragging(true);
|
|
@@ -305,7 +499,7 @@ const PianoRollNotes = props => {
|
|
|
305
499
|
};
|
|
306
500
|
const previousTrackIndex = currentNoteTrackIndex();
|
|
307
501
|
const previousNoteIndex = currentNoteIndex();
|
|
308
|
-
const targetTrackIndex = context.mode === "tracks" ? Math.floor(verticalViewPort().calculatePosition(mouseMoveEvent.clientY)) : previousTrackIndex;
|
|
502
|
+
const targetTrackIndex = context.mode === "tracks" ? clamp(Math.floor(verticalViewPort().calculatePosition(mouseMoveEvent.clientY)), 0, context.tracks.length - 1) : previousTrackIndex;
|
|
309
503
|
if (targetTrackIndex === previousTrackIndex) {
|
|
310
504
|
context.onNoteChange?.(previousTrackIndex, previousNoteIndex, updatedNote);
|
|
311
505
|
} else {
|
|
@@ -379,109 +573,6 @@ const PianoRollNotes = props => {
|
|
|
379
573
|
};
|
|
380
574
|
delegateEvents(["mousedown", "mousemove", "mouseup", "dblclick", "click"]);
|
|
381
575
|
|
|
382
|
-
const _tmpl$$6 = /*#__PURE__*/template(`<div class="PianoRoll-Scroller"><div><div><div></div></div></div></div>`, 8);
|
|
383
|
-
const ScrollContainer = props => {
|
|
384
|
-
let scrollContentRef;
|
|
385
|
-
const verticalViewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
386
|
-
const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
|
|
387
|
-
const handleScroll = event => {
|
|
388
|
-
event.preventDefault();
|
|
389
|
-
if (didUpdateScroll) {
|
|
390
|
-
didUpdateScroll = false;
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
394
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
395
|
-
const height = verticalViewPort().pixelSize;
|
|
396
|
-
const width = horizontalViewPort().pixelSize;
|
|
397
|
-
const {
|
|
398
|
-
scrollTop,
|
|
399
|
-
scrollLeft,
|
|
400
|
-
scrollWidth,
|
|
401
|
-
scrollHeight
|
|
402
|
-
} = event.currentTarget;
|
|
403
|
-
const scrollTopAmount = scrollTop / (scrollHeight - height);
|
|
404
|
-
const scrollLeftAmount = scrollLeft / (scrollWidth - width);
|
|
405
|
-
verticalViewPort().onPositionChange?.(maxVerticalPosition * scrollTopAmount);
|
|
406
|
-
horizontalViewPort().onPositionChange?.(maxPosition * scrollLeftAmount);
|
|
407
|
-
};
|
|
408
|
-
const handleWheel = event => {
|
|
409
|
-
if (event.altKey) {
|
|
410
|
-
event.preventDefault();
|
|
411
|
-
if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
|
|
412
|
-
horizontalViewPort()?.onZoomChange?.(horizontalViewPort().zoom * (1 + event.deltaX / horizontalViewPort().pixelSize));
|
|
413
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
414
|
-
horizontalViewPort()?.onPositionChange?.(Math.min(maxPosition, horizontalViewPort()?.position));
|
|
415
|
-
} else {
|
|
416
|
-
verticalViewPort()?.onZoomChange?.(verticalViewPort().zoom * (1 + event.deltaY / verticalViewPort().pixelSize));
|
|
417
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
418
|
-
verticalViewPort()?.onPositionChange?.(Math.min(maxVerticalPosition, verticalViewPort()?.position));
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
let didUpdateScroll = false;
|
|
423
|
-
createEffect(() => {
|
|
424
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
425
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
426
|
-
const scrollTopAmount = maxVerticalPosition > 0 ? verticalViewPort().position / maxVerticalPosition : 0;
|
|
427
|
-
const scrollLeftAmount = maxPosition > 0 ? horizontalViewPort().position / maxPosition : 0;
|
|
428
|
-
const height = verticalViewPort().pixelSize;
|
|
429
|
-
const width = horizontalViewPort().pixelSize;
|
|
430
|
-
if (!scrollContentRef?.parentElement) return;
|
|
431
|
-
const scrollDivHeight = verticalViewPort().zoom * verticalViewPort().pixelSize;
|
|
432
|
-
const scrollTop = scrollTopAmount * (scrollDivHeight - height);
|
|
433
|
-
const scrollDivWidth = horizontalViewPort().zoom * horizontalViewPort().pixelSize;
|
|
434
|
-
const scrollLeft = scrollLeftAmount * (scrollDivWidth - width);
|
|
435
|
-
didUpdateScroll = true;
|
|
436
|
-
scrollContentRef.style.height = `${scrollDivHeight}px`;
|
|
437
|
-
scrollContentRef.style.width = `${scrollDivWidth}px`;
|
|
438
|
-
scrollContentRef.parentElement.scrollTo({
|
|
439
|
-
left: scrollLeft,
|
|
440
|
-
top: scrollTop
|
|
441
|
-
});
|
|
442
|
-
});
|
|
443
|
-
return (() => {
|
|
444
|
-
const _el$ = _tmpl$$6.cloneNode(true),
|
|
445
|
-
_el$2 = _el$.firstChild,
|
|
446
|
-
_el$3 = _el$2.firstChild,
|
|
447
|
-
_el$4 = _el$3.firstChild;
|
|
448
|
-
_el$.addEventListener("wheel", handleWheel);
|
|
449
|
-
_el$.addEventListener("scroll", handleScroll);
|
|
450
|
-
const _ref$ = props.ref;
|
|
451
|
-
typeof _ref$ === "function" ? use(_ref$, _el$) : props.ref = _el$;
|
|
452
|
-
_el$.style.setProperty("height", "100%");
|
|
453
|
-
_el$.style.setProperty("width", "100%");
|
|
454
|
-
_el$.style.setProperty("z-index", "4");
|
|
455
|
-
_el$.style.setProperty("overflow", "scroll");
|
|
456
|
-
_el$.style.setProperty("pointer-events", "auto");
|
|
457
|
-
const _ref$2 = scrollContentRef;
|
|
458
|
-
typeof _ref$2 === "function" ? use(_ref$2, _el$2) : scrollContentRef = _el$2;
|
|
459
|
-
_el$3.style.setProperty("top", "0");
|
|
460
|
-
_el$3.style.setProperty("left", "0");
|
|
461
|
-
_el$3.style.setProperty("position", "sticky");
|
|
462
|
-
_el$3.style.setProperty("display", "flex");
|
|
463
|
-
_el$4.style.setProperty("position", "relative");
|
|
464
|
-
insert(_el$4, () => props.children);
|
|
465
|
-
effect(_p$ => {
|
|
466
|
-
const _v$ = `${verticalViewPort().pixelSize}px`,
|
|
467
|
-
_v$2 = `${horizontalViewPort().pixelSize}px`,
|
|
468
|
-
_v$3 = `${verticalViewPort().pixelSize}px`,
|
|
469
|
-
_v$4 = `${horizontalViewPort().pixelSize}px`;
|
|
470
|
-
_v$ !== _p$._v$ && _el$3.style.setProperty("height", _p$._v$ = _v$);
|
|
471
|
-
_v$2 !== _p$._v$2 && _el$3.style.setProperty("width", _p$._v$2 = _v$2);
|
|
472
|
-
_v$3 !== _p$._v$3 && _el$4.style.setProperty("height", _p$._v$3 = _v$3);
|
|
473
|
-
_v$4 !== _p$._v$4 && _el$4.style.setProperty("width", _p$._v$4 = _v$4);
|
|
474
|
-
return _p$;
|
|
475
|
-
}, {
|
|
476
|
-
_v$: undefined,
|
|
477
|
-
_v$2: undefined,
|
|
478
|
-
_v$3: undefined,
|
|
479
|
-
_v$4: undefined
|
|
480
|
-
});
|
|
481
|
-
return _el$;
|
|
482
|
-
})();
|
|
483
|
-
};
|
|
484
|
-
|
|
485
576
|
var css_248z$1 = ".PianoRollGrid-module_PianoRollGrid__tG119 {\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Row__nRMCs {\n position: absolute;\n border-style: solid;\n border-color: gray;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Time__jLz3E {\n position: absolute;\n box-sizing: border-box;\n top: 0px;\n height: 100%;\n border-left-style: solid;\n border-left-width: 0.5px;\n}\n";
|
|
486
577
|
var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
|
|
487
578
|
styleInject(css_248z$1);
|
|
@@ -489,7 +580,7 @@ styleInject(css_248z$1);
|
|
|
489
580
|
const _tmpl$$5 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
490
581
|
const PianoRollGrid = () => {
|
|
491
582
|
const context = usePianoRollContext();
|
|
492
|
-
const verticalViewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
583
|
+
const verticalViewPort = createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
|
|
493
584
|
const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
|
|
494
585
|
const measureTicks = createMemo(() => context.ppq * 4);
|
|
495
586
|
const selectedGridDivisorTicks = createMemo(() => measureTicks() / context.gridDivision);
|
|
@@ -672,14 +763,14 @@ function useBoundingClientRect(containerRef) {
|
|
|
672
763
|
|
|
673
764
|
const _tmpl$$4 = /*#__PURE__*/template(`<input min="1" max="11" step="0.01">`, 1);
|
|
674
765
|
const VerticalZoomControl = props => {
|
|
675
|
-
const
|
|
766
|
+
const dimension = createMemo(() => useViewPortDimension(props.dimensionName ?? "vertical"));
|
|
676
767
|
return (() => {
|
|
677
768
|
const _el$ = _tmpl$$4.cloneNode(true);
|
|
678
|
-
spread(_el$, mergeProps(props, {
|
|
769
|
+
spread(_el$, mergeProps$1(props, {
|
|
679
770
|
get value() {
|
|
680
|
-
return
|
|
771
|
+
return dimension().zoom;
|
|
681
772
|
},
|
|
682
|
-
"onInput": event =>
|
|
773
|
+
"onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
683
774
|
"type": "range"
|
|
684
775
|
}, {
|
|
685
776
|
orient: "vertical"
|
|
@@ -687,6 +778,7 @@ const VerticalZoomControl = props => {
|
|
|
687
778
|
get style() {
|
|
688
779
|
return {
|
|
689
780
|
width: "16px",
|
|
781
|
+
transform: "rotate(180deg)",
|
|
690
782
|
...{
|
|
691
783
|
"writing-mode": "bt-lr" /* IE */,
|
|
692
784
|
"-webkit-appearance": "slider-vertical" /* WebKit */
|
|
@@ -700,14 +792,14 @@ const VerticalZoomControl = props => {
|
|
|
700
792
|
|
|
701
793
|
const _tmpl$$3 = /*#__PURE__*/template(`<input max="500" min="1" step="0.01">`, 1);
|
|
702
794
|
const HorizontalZoomControl = props => {
|
|
703
|
-
const
|
|
795
|
+
const dimension = createMemo(() => useViewPortDimension(props.dimensionName ?? "horizontal"));
|
|
704
796
|
return (() => {
|
|
705
797
|
const _el$ = _tmpl$$3.cloneNode(true);
|
|
706
|
-
spread(_el$, mergeProps(props, {
|
|
798
|
+
spread(_el$, mergeProps$1(props, {
|
|
707
799
|
get value() {
|
|
708
|
-
return
|
|
800
|
+
return dimension().zoom;
|
|
709
801
|
},
|
|
710
|
-
"onInput": event =>
|
|
802
|
+
"onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
711
803
|
"type": "range",
|
|
712
804
|
get style() {
|
|
713
805
|
return {
|
|
@@ -728,7 +820,7 @@ styleInject(css_248z);
|
|
|
728
820
|
const _tmpl$$2 = /*#__PURE__*/template(`<div></div>`, 2),
|
|
729
821
|
_tmpl$2$1 = /*#__PURE__*/template(`<div> </div>`, 2);
|
|
730
822
|
const PianoRollTrackList = () => {
|
|
731
|
-
const viewPort = createMemo(() => useViewPortDimension("
|
|
823
|
+
const viewPort = createMemo(() => useViewPortDimension("verticalTracks"));
|
|
732
824
|
const context = usePianoRollContext();
|
|
733
825
|
return (() => {
|
|
734
826
|
const _el$ = _tmpl$$2.cloneNode(true);
|
|
@@ -737,7 +829,7 @@ const PianoRollTrackList = () => {
|
|
|
737
829
|
return context.tracks;
|
|
738
830
|
},
|
|
739
831
|
children: (track, index) => {
|
|
740
|
-
const virtualDimensions = createMemo(() => viewPort().calculatePixelDimensions(
|
|
832
|
+
const virtualDimensions = createMemo(() => viewPort().calculatePixelDimensions(index, 1));
|
|
741
833
|
return createComponent(Show, {
|
|
742
834
|
get when() {
|
|
743
835
|
return virtualDimensions().size > 0;
|
|
@@ -781,100 +873,149 @@ const PianoRollTrackList = () => {
|
|
|
781
873
|
};
|
|
782
874
|
delegateEvents(["click"]);
|
|
783
875
|
|
|
784
|
-
const _tmpl$$1 = /*#__PURE__*/template(`<div></div>`,
|
|
785
|
-
_tmpl$2 = /*#__PURE__*/template(`<div
|
|
876
|
+
const _tmpl$$1 = /*#__PURE__*/template(`<div><div></div></div>`, 4),
|
|
877
|
+
_tmpl$2 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
786
878
|
const PianoRoll = allProps => {
|
|
787
|
-
const
|
|
879
|
+
const propsWithDefaults = mergeProps({
|
|
880
|
+
showAllTracks: false
|
|
881
|
+
}, allProps);
|
|
882
|
+
const [context, divProps] = splitContextProps(propsWithDefaults);
|
|
788
883
|
const [scrollerRef, setScrollerRef] = createSignal();
|
|
884
|
+
const [trackScrollerRef, setTrackScrollerRef] = createSignal();
|
|
789
885
|
const clientRect = useBoundingClientRect(scrollerRef);
|
|
886
|
+
const trackClientRef = useBoundingClientRect(trackScrollerRef);
|
|
790
887
|
const zoomFactor = 500;
|
|
791
888
|
const minZoom = createMemo(() => 1 / (zoomFactor / clientRect().width));
|
|
792
889
|
const maxZoom = createMemo(() => 500 * (zoomFactor / clientRect().width));
|
|
793
890
|
const minVerticalZoom = createMemo(() => 1 / (zoomFactor / clientRect().height));
|
|
794
891
|
const maxVerticalZoom = createMemo(() => 10 * (zoomFactor / clientRect().height));
|
|
892
|
+
const minVerticalTracksZoom = createMemo(() => 0.8 / (zoomFactor / trackClientRef().height));
|
|
893
|
+
const maxVerticalTracksZoom = createMemo(() => 3 * (zoomFactor / trackClientRef().height));
|
|
795
894
|
createEffect(isInitial => {
|
|
796
895
|
if (isInitial) return false;
|
|
797
|
-
if (
|
|
798
|
-
|
|
896
|
+
if (context.mode === "tracks") {
|
|
897
|
+
context.onVerticalPositionChange?.(0);
|
|
799
898
|
}
|
|
800
899
|
}, true);
|
|
801
900
|
return createComponent(PianoRollContextProvider, {
|
|
802
|
-
value:
|
|
901
|
+
value: context,
|
|
803
902
|
get children() {
|
|
804
|
-
const _el$ = _tmpl$2.cloneNode(true)
|
|
805
|
-
|
|
806
|
-
spread(_el$, mergeProps(divProps, {
|
|
903
|
+
const _el$ = _tmpl$2.cloneNode(true);
|
|
904
|
+
spread(_el$, mergeProps$1(divProps, {
|
|
807
905
|
get ["class"]() {
|
|
808
|
-
return styles$
|
|
906
|
+
return styles$5.PianoRoll;
|
|
809
907
|
}
|
|
810
908
|
}), false, true);
|
|
811
|
-
insert(_el
|
|
909
|
+
insert(_el$, createComponent(ScrollZoomViewPort, {
|
|
812
910
|
dimensions: {
|
|
813
911
|
horizontal: () => ({
|
|
814
912
|
pixelOffset: clientRect().left,
|
|
815
913
|
pixelSize: clientRect().width,
|
|
816
|
-
position:
|
|
817
|
-
range:
|
|
818
|
-
zoom:
|
|
819
|
-
onPositionChange:
|
|
820
|
-
onZoomChange: zoom =>
|
|
914
|
+
position: context.position,
|
|
915
|
+
range: context.duration,
|
|
916
|
+
zoom: context.zoom * (zoomFactor / clientRect().width),
|
|
917
|
+
onPositionChange: context.onPositionChange,
|
|
918
|
+
onZoomChange: zoom => context.onZoomChange?.(clamp(zoom / (zoomFactor / clientRect().width), minZoom(), maxZoom()))
|
|
821
919
|
}),
|
|
822
920
|
vertical: () => ({
|
|
823
921
|
pixelOffset: clientRect().top,
|
|
824
922
|
pixelSize: clientRect().height,
|
|
825
|
-
position:
|
|
826
|
-
range:
|
|
827
|
-
zoom:
|
|
828
|
-
onPositionChange:
|
|
829
|
-
onZoomChange: verticalZoom =>
|
|
923
|
+
position: context.verticalPosition,
|
|
924
|
+
range: 128,
|
|
925
|
+
zoom: context.verticalZoom * (zoomFactor / clientRect().height),
|
|
926
|
+
onPositionChange: context.onVerticalPositionChange,
|
|
927
|
+
onZoomChange: verticalZoom => context.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
|
|
928
|
+
}),
|
|
929
|
+
horizontalTracks: () => ({
|
|
930
|
+
pixelOffset: clientRect().left,
|
|
931
|
+
pixelSize: clientRect().width,
|
|
932
|
+
position: 0,
|
|
933
|
+
range: 1,
|
|
934
|
+
zoom: 1
|
|
935
|
+
}),
|
|
936
|
+
verticalTracks: () => ({
|
|
937
|
+
pixelOffset: trackClientRef().top,
|
|
938
|
+
pixelSize: trackClientRef().height,
|
|
939
|
+
position: context.verticalTrackPosition,
|
|
940
|
+
range: context.tracks.length,
|
|
941
|
+
zoom: context.verticalTrackZoom * (zoomFactor / trackClientRef().height),
|
|
942
|
+
onPositionChange: context.onVerticalTrackPositionChange,
|
|
943
|
+
onZoomChange: verticalTrackZoom => context.onVerticalTrackZoomChange?.(clamp(verticalTrackZoom / (zoomFactor / trackClientRef().height), minVerticalTracksZoom(), maxVerticalTracksZoom()))
|
|
830
944
|
})
|
|
831
945
|
},
|
|
832
946
|
get children() {
|
|
833
947
|
return [(() => {
|
|
834
|
-
const _el$
|
|
948
|
+
const _el$2 = _tmpl$$1.cloneNode(true),
|
|
949
|
+
_el$3 = _el$2.firstChild;
|
|
950
|
+
insert(_el$2, createComponent(VerticalZoomControl, {
|
|
951
|
+
get min() {
|
|
952
|
+
return minVerticalTracksZoom();
|
|
953
|
+
},
|
|
954
|
+
get max() {
|
|
955
|
+
return maxVerticalTracksZoom();
|
|
956
|
+
},
|
|
957
|
+
dimensionName: "verticalTracks"
|
|
958
|
+
}), _el$3);
|
|
835
959
|
_el$3.style.setProperty("display", "flex");
|
|
836
960
|
_el$3.style.setProperty("width", "20%");
|
|
837
961
|
insert(_el$3, createComponent(Show, {
|
|
838
962
|
get when() {
|
|
839
|
-
return
|
|
963
|
+
return context.showTrackList;
|
|
840
964
|
},
|
|
841
965
|
get children() {
|
|
842
|
-
return createComponent(
|
|
966
|
+
return createComponent(ScrollContainer, {
|
|
967
|
+
ref: setTrackScrollerRef,
|
|
968
|
+
horizontalDimensionName: "horizontalTracks",
|
|
969
|
+
verticalDimensionName: "verticalTracks",
|
|
970
|
+
get showScrollbar() {
|
|
971
|
+
return context.mode === "keys";
|
|
972
|
+
},
|
|
973
|
+
get children() {
|
|
974
|
+
return createComponent(PianoRollTrackList, {});
|
|
975
|
+
}
|
|
976
|
+
});
|
|
843
977
|
}
|
|
844
978
|
}), null);
|
|
845
979
|
insert(_el$3, createComponent(Show, {
|
|
846
980
|
get when() {
|
|
847
|
-
return
|
|
981
|
+
return context.mode === "keys";
|
|
848
982
|
},
|
|
849
983
|
get children() {
|
|
850
984
|
return createComponent(PianoRollKeys, {});
|
|
851
985
|
}
|
|
852
986
|
}), null);
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
987
|
+
insert(_el$2, createComponent(ScrollContainer, {
|
|
988
|
+
ref: setScrollerRef,
|
|
989
|
+
get verticalDimensionName() {
|
|
990
|
+
return context.mode === "keys" ? "vertical" : "verticalTracks";
|
|
991
|
+
},
|
|
992
|
+
get children() {
|
|
993
|
+
return [memo(() => allProps.children), createComponent(PianoRollGrid, {}), createComponent(PianoRollNotes, {})];
|
|
994
|
+
}
|
|
995
|
+
}), null);
|
|
996
|
+
insert(_el$2, createComponent(VerticalZoomControl, {
|
|
997
|
+
get min() {
|
|
998
|
+
return minVerticalZoom();
|
|
999
|
+
},
|
|
1000
|
+
get max() {
|
|
1001
|
+
return maxVerticalZoom();
|
|
1002
|
+
},
|
|
1003
|
+
get disabled() {
|
|
1004
|
+
return context.mode !== "keys";
|
|
1005
|
+
}
|
|
1006
|
+
}), null);
|
|
1007
|
+
effect(() => className(_el$2, styles$5.PianoRollContainer));
|
|
1008
|
+
return _el$2;
|
|
1009
|
+
})(), createComponent(HorizontalZoomControl, {
|
|
860
1010
|
get min() {
|
|
861
|
-
return
|
|
1011
|
+
return minZoom();
|
|
862
1012
|
},
|
|
863
1013
|
get max() {
|
|
864
|
-
return
|
|
1014
|
+
return maxZoom();
|
|
865
1015
|
}
|
|
866
1016
|
})];
|
|
867
1017
|
}
|
|
868
1018
|
}));
|
|
869
|
-
insert(_el$, createComponent(HorizontalZoomControl, {
|
|
870
|
-
get min() {
|
|
871
|
-
return minZoom();
|
|
872
|
-
},
|
|
873
|
-
get max() {
|
|
874
|
-
return maxZoom();
|
|
875
|
-
}
|
|
876
|
-
}), null);
|
|
877
|
-
effect(() => className(_el$2, styles$4.PianoRollContainer));
|
|
878
1019
|
return _el$;
|
|
879
1020
|
}
|
|
880
1021
|
});
|
|
@@ -882,7 +1023,7 @@ const PianoRoll = allProps => {
|
|
|
882
1023
|
|
|
883
1024
|
const _tmpl$ = /*#__PURE__*/template(`<div class="PlayHead"></div>`, 2);
|
|
884
1025
|
const PlayHead = allProps => {
|
|
885
|
-
const propsWithDefauls = mergeProps
|
|
1026
|
+
const propsWithDefauls = mergeProps({
|
|
886
1027
|
playHeadPosition: 0,
|
|
887
1028
|
sync: false
|
|
888
1029
|
}, allProps);
|
|
@@ -897,7 +1038,7 @@ const PlayHead = allProps => {
|
|
|
897
1038
|
const leftPosition = createMemo(() => viewPort.calculatePixelOffset(props.playHeadPosition));
|
|
898
1039
|
return (() => {
|
|
899
1040
|
const _el$ = _tmpl$.cloneNode(true);
|
|
900
|
-
spread(_el$, mergeProps(divProps, {
|
|
1041
|
+
spread(_el$, mergeProps$1(divProps, {
|
|
901
1042
|
get style() {
|
|
902
1043
|
return {
|
|
903
1044
|
position: "absolute",
|
|
@@ -958,37 +1099,83 @@ const useNotes = () => {
|
|
|
958
1099
|
};
|
|
959
1100
|
};
|
|
960
1101
|
|
|
961
|
-
const
|
|
962
|
-
const [
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1102
|
+
const createPianoRollstate = defaultState => {
|
|
1103
|
+
const [state, setState] = createStore({
|
|
1104
|
+
ppq: 0,
|
|
1105
|
+
mode: "keys",
|
|
1106
|
+
position: 0,
|
|
1107
|
+
zoom: 10,
|
|
1108
|
+
verticalZoom: 5,
|
|
1109
|
+
verticalPosition: 44,
|
|
1110
|
+
verticalTrackZoom: 0.5,
|
|
1111
|
+
verticalTrackPosition: 0,
|
|
1112
|
+
gridDivision: 4,
|
|
1113
|
+
snapToGrid: true,
|
|
1114
|
+
duration: 0,
|
|
1115
|
+
tracks: [],
|
|
1116
|
+
selectedTrackIndex: 0,
|
|
1117
|
+
pressedKeys: [],
|
|
1118
|
+
...defaultState
|
|
1119
|
+
});
|
|
1120
|
+
const updateNotes = async (trackIndex, getNotes) => {
|
|
1121
|
+
const track = state.tracks[trackIndex];
|
|
1122
|
+
if (!track) return;
|
|
1123
|
+
const notes = track.notes;
|
|
1124
|
+
onTracksChange([...state.tracks.slice(0, trackIndex), {
|
|
1125
|
+
...track,
|
|
1126
|
+
notes: getNotes(notes)
|
|
1127
|
+
}, ...state.tracks.slice(trackIndex + 1)]);
|
|
1128
|
+
};
|
|
1129
|
+
const onNoteChange = (trackIndex, noteIndex, note) => {
|
|
1130
|
+
updateNotes(trackIndex, notes => [...notes.slice(0, noteIndex), note, ...notes.slice(noteIndex + 1)]);
|
|
1131
|
+
};
|
|
1132
|
+
const onInsertNote = (trackIndex, note) => {
|
|
1133
|
+
const track = state.tracks[trackIndex];
|
|
1134
|
+
if (!track) return -1;
|
|
1135
|
+
const notes = track.notes;
|
|
1136
|
+
const newNoteIndex = Math.max(notes.findIndex(({
|
|
1137
|
+
ticks
|
|
1138
|
+
}) => ticks > note.ticks), 0);
|
|
1139
|
+
updateNotes(trackIndex, notes => [...notes.slice(0, newNoteIndex), note, ...notes.slice(newNoteIndex)]);
|
|
1140
|
+
return newNoteIndex;
|
|
1141
|
+
};
|
|
1142
|
+
const onRemoveNote = (trackIndex, noteIndex) => {
|
|
1143
|
+
updateNotes(trackIndex, notes => [...notes.slice(0, noteIndex), ...notes.slice(noteIndex + 1)]);
|
|
1144
|
+
};
|
|
1145
|
+
const onPpqChange = ppq => setState("ppq", ppq);
|
|
1146
|
+
const onModeChange = mode => setState("mode", mode);
|
|
1147
|
+
const onPositionChange = position => setState("position", position);
|
|
1148
|
+
const onZoomChange = zoom => setState("zoom", zoom);
|
|
1149
|
+
const onVerticalZoomChange = verticalZoom => setState("verticalZoom", verticalZoom);
|
|
1150
|
+
const onVerticalPositionChange = verticalPosition => setState("verticalPosition", verticalPosition);
|
|
1151
|
+
const onVerticalTrackZoomChange = verticalTrackZoom => setState("verticalTrackZoom", verticalTrackZoom);
|
|
1152
|
+
const onVerticalTrackPositionChange = verticalTrackPosition => setState("verticalTrackPosition", verticalTrackPosition);
|
|
1153
|
+
const onGridDivisionChange = gridDivision => setState("gridDivision", gridDivision);
|
|
1154
|
+
const onSnapToGridChange = snapToGrid => setState("snapToGrid", snapToGrid);
|
|
1155
|
+
const onDurationChange = duration => setState("duration", duration);
|
|
1156
|
+
const onTracksChange = tracks => setState("tracks", tracks);
|
|
1157
|
+
const onSelectedTrackIndexChange = selectedTrackIndex => setState("selectedTrackIndex", selectedTrackIndex);
|
|
1158
|
+
const onPressedKeysChange = pressedKeys => setState("pressedKeys", pressedKeys);
|
|
1159
|
+
return mergeProps(state, {
|
|
973
1160
|
onPpqChange,
|
|
974
|
-
|
|
1161
|
+
onModeChange,
|
|
975
1162
|
onPositionChange,
|
|
976
|
-
zoom,
|
|
977
1163
|
onZoomChange,
|
|
978
|
-
verticalPosition,
|
|
979
|
-
onVerticalPositionChange,
|
|
980
|
-
verticalZoom,
|
|
981
1164
|
onVerticalZoomChange,
|
|
982
|
-
|
|
1165
|
+
onVerticalPositionChange,
|
|
1166
|
+
onVerticalTrackZoomChange,
|
|
1167
|
+
onVerticalTrackPositionChange,
|
|
983
1168
|
onGridDivisionChange,
|
|
984
|
-
snapToGrid,
|
|
985
1169
|
onSnapToGridChange,
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1170
|
+
onDurationChange,
|
|
1171
|
+
onTracksChange,
|
|
1172
|
+
onNoteChange,
|
|
1173
|
+
onInsertNote,
|
|
1174
|
+
onRemoveNote,
|
|
1175
|
+
onSelectedTrackIndexChange,
|
|
1176
|
+
onPressedKeysChange
|
|
1177
|
+
});
|
|
991
1178
|
};
|
|
992
1179
|
|
|
993
|
-
export { PianoRoll, PlayHead,
|
|
1180
|
+
export { PianoRoll, PlayHead, createPianoRollstate, useNotes };
|
|
994
1181
|
//# sourceMappingURL=index.js.map
|