solid-pianoroll 0.0.16 → 0.0.18
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 +422 -265
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +429 -272
- 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 +39 -5
- 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,
|
|
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,84 +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
|
-
get children() {
|
|
144
|
-
const _el$3 = _tmpl$$8.cloneNode(true);
|
|
145
|
-
effect(_p$ => {
|
|
146
|
-
const _v$ = styles$3["black-separator"],
|
|
147
|
-
_v$2 = `${virtualDimensions().offset}px`,
|
|
148
|
-
_v$3 = `${virtualDimensions().size / 2 - 0.25}px`;
|
|
149
|
-
_v$ !== _p$._v$ && className(_el$3, _p$._v$ = _v$);
|
|
150
|
-
_v$2 !== _p$._v$2 && _el$3.style.setProperty("top", _p$._v$2 = _v$2);
|
|
151
|
-
_v$3 !== _p$._v$3 && _el$3.style.setProperty("height", _p$._v$3 = _v$3);
|
|
152
|
-
return _p$;
|
|
153
|
-
}, {
|
|
154
|
-
_v$: undefined,
|
|
155
|
-
_v$2: undefined,
|
|
156
|
-
_v$3: undefined
|
|
157
|
-
});
|
|
158
|
-
return _el$3;
|
|
159
|
-
}
|
|
160
|
-
}));
|
|
161
|
-
effect(_p$ => {
|
|
162
|
-
const _v$4 = {
|
|
163
|
-
[styles$3["Key"]]: true,
|
|
164
|
-
[styles$3["black"]]: key().isBlack,
|
|
165
|
-
[styles$3["white"]]: !key().isBlack,
|
|
166
|
-
[styles$3["down"]]: isDown()
|
|
167
|
-
},
|
|
168
|
-
_v$5 = key().name,
|
|
169
|
-
_v$6 = key().number % 12,
|
|
170
|
-
_v$7 = `${virtualDimensions().offset - (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0)}px`,
|
|
171
|
-
_v$8 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
|
|
172
|
-
_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(", ");
|
|
173
|
-
_p$._v$4 = classList(_el$2, _v$4, _p$._v$4);
|
|
174
|
-
_v$5 !== _p$._v$5 && setAttribute(_el$2, "title", _p$._v$5 = _v$5);
|
|
175
|
-
_v$6 !== _p$._v$6 && setAttribute(_el$2, "data-index", _p$._v$6 = _v$6);
|
|
176
|
-
_v$7 !== _p$._v$7 && _el$2.style.setProperty("top", _p$._v$7 = _v$7);
|
|
177
|
-
_v$8 !== _p$._v$8 && _el$2.style.setProperty("height", _p$._v$8 = _v$8);
|
|
178
|
-
_v$9 !== _p$._v$9 && _el$2.style.setProperty("box-shadow", _p$._v$9 = _v$9);
|
|
179
|
-
return _p$;
|
|
180
|
-
}, {
|
|
181
|
-
_v$4: undefined,
|
|
182
|
-
_v$5: undefined,
|
|
183
|
-
_v$6: undefined,
|
|
184
|
-
_v$7: undefined,
|
|
185
|
-
_v$8: undefined,
|
|
186
|
-
_v$9: undefined
|
|
187
|
-
});
|
|
188
|
-
return _el$2;
|
|
189
|
-
}
|
|
190
|
-
});
|
|
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
|
+
};
|
|
191
215
|
}
|
|
192
|
-
}));
|
|
193
|
-
|
|
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
|
+
});
|
|
194
241
|
return _el$;
|
|
195
242
|
})();
|
|
196
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
|
+
};
|
|
197
361
|
const blackKeys = [1, 3, 6, 8, 10];
|
|
198
362
|
const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
199
363
|
const keys = Array.from({
|
|
@@ -209,10 +373,10 @@ var css_248z$2 = ".PianoRollNotes-module_PianoRollNotes__6pF-y {\n position: ab
|
|
|
209
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"};
|
|
210
374
|
styleInject(css_248z$2);
|
|
211
375
|
|
|
212
|
-
const _tmpl$$
|
|
376
|
+
const _tmpl$$6 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
213
377
|
const PianoRollNotes = props => {
|
|
214
378
|
const context = usePianoRollContext();
|
|
215
|
-
const verticalViewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
379
|
+
const verticalViewPort = createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
|
|
216
380
|
const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
|
|
217
381
|
const gridDivisionTicks = createMemo(() => context.ppq * 4 / context.gridDivision);
|
|
218
382
|
const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks() : value;
|
|
@@ -220,7 +384,7 @@ const PianoRollNotes = props => {
|
|
|
220
384
|
const position = horizontalViewPort().calculatePosition(event.clientX);
|
|
221
385
|
const existingNote = currentNote();
|
|
222
386
|
const midi = context.mode === "keys" ? 127 - Math.floor(verticalViewPort().calculatePosition(event.clientY)) : existingNote?.midi ?? 60;
|
|
223
|
-
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;
|
|
224
388
|
const eventPositionTicks = Math.floor(position / gridDivisionTicks()) * gridDivisionTicks();
|
|
225
389
|
const velocity = 127;
|
|
226
390
|
const ticks = existingNote?.ticks ?? eventPositionTicks;
|
|
@@ -248,7 +412,7 @@ const PianoRollNotes = props => {
|
|
|
248
412
|
return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
|
|
249
413
|
};
|
|
250
414
|
return (() => {
|
|
251
|
-
const _el$ = _tmpl$$
|
|
415
|
+
const _el$ = _tmpl$$6.cloneNode(true);
|
|
252
416
|
_el$.$$click = event => {
|
|
253
417
|
if (currentNote()) {
|
|
254
418
|
setCurrentNoteIndex(-1);
|
|
@@ -306,7 +470,7 @@ const PianoRollNotes = props => {
|
|
|
306
470
|
return memo(() => !!verticalViewPort().isVisible(verticalVirtualDimensions()))() && horizontalViewPort().isVisible(horizontalDimensions());
|
|
307
471
|
},
|
|
308
472
|
get children() {
|
|
309
|
-
const _el$2 = _tmpl$$
|
|
473
|
+
const _el$2 = _tmpl$$6.cloneNode(true);
|
|
310
474
|
_el$2.$$mousedown = event => {
|
|
311
475
|
event.stopPropagation();
|
|
312
476
|
setIsDragging(true);
|
|
@@ -335,7 +499,7 @@ const PianoRollNotes = props => {
|
|
|
335
499
|
};
|
|
336
500
|
const previousTrackIndex = currentNoteTrackIndex();
|
|
337
501
|
const previousNoteIndex = currentNoteIndex();
|
|
338
|
-
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;
|
|
339
503
|
if (targetTrackIndex === previousTrackIndex) {
|
|
340
504
|
context.onNoteChange?.(previousTrackIndex, previousNoteIndex, updatedNote);
|
|
341
505
|
} else {
|
|
@@ -409,109 +573,6 @@ const PianoRollNotes = props => {
|
|
|
409
573
|
};
|
|
410
574
|
delegateEvents(["mousedown", "mousemove", "mouseup", "dblclick", "click"]);
|
|
411
575
|
|
|
412
|
-
const _tmpl$$6 = /*#__PURE__*/template(`<div class="PianoRoll-Scroller"><div><div><div></div></div></div></div>`, 8);
|
|
413
|
-
const ScrollContainer = props => {
|
|
414
|
-
let scrollContentRef;
|
|
415
|
-
const verticalViewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
416
|
-
const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
|
|
417
|
-
const handleScroll = event => {
|
|
418
|
-
event.preventDefault();
|
|
419
|
-
if (didUpdateScroll) {
|
|
420
|
-
didUpdateScroll = false;
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
424
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
425
|
-
const height = verticalViewPort().pixelSize;
|
|
426
|
-
const width = horizontalViewPort().pixelSize;
|
|
427
|
-
const {
|
|
428
|
-
scrollTop,
|
|
429
|
-
scrollLeft,
|
|
430
|
-
scrollWidth,
|
|
431
|
-
scrollHeight
|
|
432
|
-
} = event.currentTarget;
|
|
433
|
-
const scrollTopAmount = scrollTop / (scrollHeight - height);
|
|
434
|
-
const scrollLeftAmount = scrollLeft / (scrollWidth - width);
|
|
435
|
-
verticalViewPort().onPositionChange?.(maxVerticalPosition * scrollTopAmount);
|
|
436
|
-
horizontalViewPort().onPositionChange?.(maxPosition * scrollLeftAmount);
|
|
437
|
-
};
|
|
438
|
-
const handleWheel = event => {
|
|
439
|
-
if (event.altKey) {
|
|
440
|
-
event.preventDefault();
|
|
441
|
-
if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
|
|
442
|
-
horizontalViewPort()?.onZoomChange?.(horizontalViewPort().zoom * (1 + event.deltaX / horizontalViewPort().pixelSize));
|
|
443
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
444
|
-
horizontalViewPort()?.onPositionChange?.(Math.min(maxPosition, horizontalViewPort()?.position));
|
|
445
|
-
} else {
|
|
446
|
-
verticalViewPort()?.onZoomChange?.(verticalViewPort().zoom * (1 + event.deltaY / verticalViewPort().pixelSize));
|
|
447
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
448
|
-
verticalViewPort()?.onPositionChange?.(Math.min(maxVerticalPosition, verticalViewPort()?.position));
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
};
|
|
452
|
-
let didUpdateScroll = false;
|
|
453
|
-
createEffect(() => {
|
|
454
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
455
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
456
|
-
const scrollTopAmount = maxVerticalPosition > 0 ? verticalViewPort().position / maxVerticalPosition : 0;
|
|
457
|
-
const scrollLeftAmount = maxPosition > 0 ? horizontalViewPort().position / maxPosition : 0;
|
|
458
|
-
const height = verticalViewPort().pixelSize;
|
|
459
|
-
const width = horizontalViewPort().pixelSize;
|
|
460
|
-
if (!scrollContentRef?.parentElement) return;
|
|
461
|
-
const scrollDivHeight = verticalViewPort().zoom * verticalViewPort().pixelSize;
|
|
462
|
-
const scrollTop = scrollTopAmount * (scrollDivHeight - height);
|
|
463
|
-
const scrollDivWidth = horizontalViewPort().zoom * horizontalViewPort().pixelSize;
|
|
464
|
-
const scrollLeft = scrollLeftAmount * (scrollDivWidth - width);
|
|
465
|
-
didUpdateScroll = true;
|
|
466
|
-
scrollContentRef.style.height = `${scrollDivHeight}px`;
|
|
467
|
-
scrollContentRef.style.width = `${scrollDivWidth}px`;
|
|
468
|
-
scrollContentRef.parentElement.scrollTo({
|
|
469
|
-
left: scrollLeft,
|
|
470
|
-
top: scrollTop
|
|
471
|
-
});
|
|
472
|
-
});
|
|
473
|
-
return (() => {
|
|
474
|
-
const _el$ = _tmpl$$6.cloneNode(true),
|
|
475
|
-
_el$2 = _el$.firstChild,
|
|
476
|
-
_el$3 = _el$2.firstChild,
|
|
477
|
-
_el$4 = _el$3.firstChild;
|
|
478
|
-
_el$.addEventListener("wheel", handleWheel);
|
|
479
|
-
_el$.addEventListener("scroll", handleScroll);
|
|
480
|
-
const _ref$ = props.ref;
|
|
481
|
-
typeof _ref$ === "function" ? use(_ref$, _el$) : props.ref = _el$;
|
|
482
|
-
_el$.style.setProperty("height", "100%");
|
|
483
|
-
_el$.style.setProperty("width", "100%");
|
|
484
|
-
_el$.style.setProperty("z-index", "4");
|
|
485
|
-
_el$.style.setProperty("overflow", "scroll");
|
|
486
|
-
_el$.style.setProperty("pointer-events", "auto");
|
|
487
|
-
const _ref$2 = scrollContentRef;
|
|
488
|
-
typeof _ref$2 === "function" ? use(_ref$2, _el$2) : scrollContentRef = _el$2;
|
|
489
|
-
_el$3.style.setProperty("top", "0");
|
|
490
|
-
_el$3.style.setProperty("left", "0");
|
|
491
|
-
_el$3.style.setProperty("position", "sticky");
|
|
492
|
-
_el$3.style.setProperty("display", "flex");
|
|
493
|
-
_el$4.style.setProperty("position", "relative");
|
|
494
|
-
insert(_el$4, () => props.children);
|
|
495
|
-
effect(_p$ => {
|
|
496
|
-
const _v$ = `${verticalViewPort().pixelSize}px`,
|
|
497
|
-
_v$2 = `${horizontalViewPort().pixelSize}px`,
|
|
498
|
-
_v$3 = `${verticalViewPort().pixelSize}px`,
|
|
499
|
-
_v$4 = `${horizontalViewPort().pixelSize}px`;
|
|
500
|
-
_v$ !== _p$._v$ && _el$3.style.setProperty("height", _p$._v$ = _v$);
|
|
501
|
-
_v$2 !== _p$._v$2 && _el$3.style.setProperty("width", _p$._v$2 = _v$2);
|
|
502
|
-
_v$3 !== _p$._v$3 && _el$4.style.setProperty("height", _p$._v$3 = _v$3);
|
|
503
|
-
_v$4 !== _p$._v$4 && _el$4.style.setProperty("width", _p$._v$4 = _v$4);
|
|
504
|
-
return _p$;
|
|
505
|
-
}, {
|
|
506
|
-
_v$: undefined,
|
|
507
|
-
_v$2: undefined,
|
|
508
|
-
_v$3: undefined,
|
|
509
|
-
_v$4: undefined
|
|
510
|
-
});
|
|
511
|
-
return _el$;
|
|
512
|
-
})();
|
|
513
|
-
};
|
|
514
|
-
|
|
515
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";
|
|
516
577
|
var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
|
|
517
578
|
styleInject(css_248z$1);
|
|
@@ -519,7 +580,7 @@ styleInject(css_248z$1);
|
|
|
519
580
|
const _tmpl$$5 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
520
581
|
const PianoRollGrid = () => {
|
|
521
582
|
const context = usePianoRollContext();
|
|
522
|
-
const verticalViewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
583
|
+
const verticalViewPort = createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
|
|
523
584
|
const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
|
|
524
585
|
const measureTicks = createMemo(() => context.ppq * 4);
|
|
525
586
|
const selectedGridDivisorTicks = createMemo(() => measureTicks() / context.gridDivision);
|
|
@@ -702,14 +763,14 @@ function useBoundingClientRect(containerRef) {
|
|
|
702
763
|
|
|
703
764
|
const _tmpl$$4 = /*#__PURE__*/template(`<input min="1" max="11" step="0.01">`, 1);
|
|
704
765
|
const VerticalZoomControl = props => {
|
|
705
|
-
const
|
|
766
|
+
const dimension = createMemo(() => useViewPortDimension(props.dimensionName ?? "vertical"));
|
|
706
767
|
return (() => {
|
|
707
768
|
const _el$ = _tmpl$$4.cloneNode(true);
|
|
708
|
-
spread(_el$, mergeProps(props, {
|
|
769
|
+
spread(_el$, mergeProps$1(props, {
|
|
709
770
|
get value() {
|
|
710
|
-
return
|
|
771
|
+
return dimension().zoom;
|
|
711
772
|
},
|
|
712
|
-
"onInput": event =>
|
|
773
|
+
"onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
713
774
|
"type": "range"
|
|
714
775
|
}, {
|
|
715
776
|
orient: "vertical"
|
|
@@ -717,6 +778,7 @@ const VerticalZoomControl = props => {
|
|
|
717
778
|
get style() {
|
|
718
779
|
return {
|
|
719
780
|
width: "16px",
|
|
781
|
+
transform: "rotate(180deg)",
|
|
720
782
|
...{
|
|
721
783
|
"writing-mode": "bt-lr" /* IE */,
|
|
722
784
|
"-webkit-appearance": "slider-vertical" /* WebKit */
|
|
@@ -730,14 +792,14 @@ const VerticalZoomControl = props => {
|
|
|
730
792
|
|
|
731
793
|
const _tmpl$$3 = /*#__PURE__*/template(`<input max="500" min="1" step="0.01">`, 1);
|
|
732
794
|
const HorizontalZoomControl = props => {
|
|
733
|
-
const
|
|
795
|
+
const dimension = createMemo(() => useViewPortDimension(props.dimensionName ?? "horizontal"));
|
|
734
796
|
return (() => {
|
|
735
797
|
const _el$ = _tmpl$$3.cloneNode(true);
|
|
736
|
-
spread(_el$, mergeProps(props, {
|
|
798
|
+
spread(_el$, mergeProps$1(props, {
|
|
737
799
|
get value() {
|
|
738
|
-
return
|
|
800
|
+
return dimension().zoom;
|
|
739
801
|
},
|
|
740
|
-
"onInput": event =>
|
|
802
|
+
"onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
741
803
|
"type": "range",
|
|
742
804
|
get style() {
|
|
743
805
|
return {
|
|
@@ -758,7 +820,7 @@ styleInject(css_248z);
|
|
|
758
820
|
const _tmpl$$2 = /*#__PURE__*/template(`<div></div>`, 2),
|
|
759
821
|
_tmpl$2$1 = /*#__PURE__*/template(`<div> </div>`, 2);
|
|
760
822
|
const PianoRollTrackList = () => {
|
|
761
|
-
const viewPort = createMemo(() => useViewPortDimension("
|
|
823
|
+
const viewPort = createMemo(() => useViewPortDimension("verticalTracks"));
|
|
762
824
|
const context = usePianoRollContext();
|
|
763
825
|
return (() => {
|
|
764
826
|
const _el$ = _tmpl$$2.cloneNode(true);
|
|
@@ -767,7 +829,7 @@ const PianoRollTrackList = () => {
|
|
|
767
829
|
return context.tracks;
|
|
768
830
|
},
|
|
769
831
|
children: (track, index) => {
|
|
770
|
-
const virtualDimensions = createMemo(() => viewPort().calculatePixelDimensions(
|
|
832
|
+
const virtualDimensions = createMemo(() => viewPort().calculatePixelDimensions(index, 1));
|
|
771
833
|
return createComponent(Show, {
|
|
772
834
|
get when() {
|
|
773
835
|
return virtualDimensions().size > 0;
|
|
@@ -811,100 +873,149 @@ const PianoRollTrackList = () => {
|
|
|
811
873
|
};
|
|
812
874
|
delegateEvents(["click"]);
|
|
813
875
|
|
|
814
|
-
const _tmpl$$1 = /*#__PURE__*/template(`<div></div>`,
|
|
815
|
-
_tmpl$2 = /*#__PURE__*/template(`<div
|
|
876
|
+
const _tmpl$$1 = /*#__PURE__*/template(`<div><div></div></div>`, 4),
|
|
877
|
+
_tmpl$2 = /*#__PURE__*/template(`<div></div>`, 2);
|
|
816
878
|
const PianoRoll = allProps => {
|
|
817
|
-
const
|
|
879
|
+
const propsWithDefaults = mergeProps({
|
|
880
|
+
showAllTracks: false
|
|
881
|
+
}, allProps);
|
|
882
|
+
const [context, divProps] = splitContextProps(propsWithDefaults);
|
|
818
883
|
const [scrollerRef, setScrollerRef] = createSignal();
|
|
884
|
+
const [trackScrollerRef, setTrackScrollerRef] = createSignal();
|
|
819
885
|
const clientRect = useBoundingClientRect(scrollerRef);
|
|
886
|
+
const trackClientRef = useBoundingClientRect(trackScrollerRef);
|
|
820
887
|
const zoomFactor = 500;
|
|
821
888
|
const minZoom = createMemo(() => 1 / (zoomFactor / clientRect().width));
|
|
822
889
|
const maxZoom = createMemo(() => 500 * (zoomFactor / clientRect().width));
|
|
823
890
|
const minVerticalZoom = createMemo(() => 1 / (zoomFactor / clientRect().height));
|
|
824
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));
|
|
825
894
|
createEffect(isInitial => {
|
|
826
895
|
if (isInitial) return false;
|
|
827
|
-
if (
|
|
828
|
-
|
|
896
|
+
if (context.mode === "tracks") {
|
|
897
|
+
context.onVerticalPositionChange?.(0);
|
|
829
898
|
}
|
|
830
899
|
}, true);
|
|
831
900
|
return createComponent(PianoRollContextProvider, {
|
|
832
|
-
value:
|
|
901
|
+
value: context,
|
|
833
902
|
get children() {
|
|
834
|
-
const _el$ = _tmpl$2.cloneNode(true)
|
|
835
|
-
|
|
836
|
-
spread(_el$, mergeProps(divProps, {
|
|
903
|
+
const _el$ = _tmpl$2.cloneNode(true);
|
|
904
|
+
spread(_el$, mergeProps$1(divProps, {
|
|
837
905
|
get ["class"]() {
|
|
838
|
-
return styles$
|
|
906
|
+
return styles$5.PianoRoll;
|
|
839
907
|
}
|
|
840
908
|
}), false, true);
|
|
841
|
-
insert(_el
|
|
909
|
+
insert(_el$, createComponent(ScrollZoomViewPort, {
|
|
842
910
|
dimensions: {
|
|
843
911
|
horizontal: () => ({
|
|
844
912
|
pixelOffset: clientRect().left,
|
|
845
913
|
pixelSize: clientRect().width,
|
|
846
|
-
position:
|
|
847
|
-
range:
|
|
848
|
-
zoom:
|
|
849
|
-
onPositionChange:
|
|
850
|
-
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()))
|
|
851
919
|
}),
|
|
852
920
|
vertical: () => ({
|
|
853
921
|
pixelOffset: clientRect().top,
|
|
854
922
|
pixelSize: clientRect().height,
|
|
855
|
-
position:
|
|
856
|
-
range:
|
|
857
|
-
zoom:
|
|
858
|
-
onPositionChange:
|
|
859
|
-
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()))
|
|
860
944
|
})
|
|
861
945
|
},
|
|
862
946
|
get children() {
|
|
863
947
|
return [(() => {
|
|
864
|
-
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);
|
|
865
959
|
_el$3.style.setProperty("display", "flex");
|
|
866
960
|
_el$3.style.setProperty("width", "20%");
|
|
867
961
|
insert(_el$3, createComponent(Show, {
|
|
868
962
|
get when() {
|
|
869
|
-
return
|
|
963
|
+
return context.showTrackList;
|
|
870
964
|
},
|
|
871
965
|
get children() {
|
|
872
|
-
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
|
+
});
|
|
873
977
|
}
|
|
874
978
|
}), null);
|
|
875
979
|
insert(_el$3, createComponent(Show, {
|
|
876
980
|
get when() {
|
|
877
|
-
return
|
|
981
|
+
return context.mode === "keys";
|
|
878
982
|
},
|
|
879
983
|
get children() {
|
|
880
984
|
return createComponent(PianoRollKeys, {});
|
|
881
985
|
}
|
|
882
986
|
}), null);
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
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, {
|
|
890
1010
|
get min() {
|
|
891
|
-
return
|
|
1011
|
+
return minZoom();
|
|
892
1012
|
},
|
|
893
1013
|
get max() {
|
|
894
|
-
return
|
|
1014
|
+
return maxZoom();
|
|
895
1015
|
}
|
|
896
1016
|
})];
|
|
897
1017
|
}
|
|
898
1018
|
}));
|
|
899
|
-
insert(_el$, createComponent(HorizontalZoomControl, {
|
|
900
|
-
get min() {
|
|
901
|
-
return minZoom();
|
|
902
|
-
},
|
|
903
|
-
get max() {
|
|
904
|
-
return maxZoom();
|
|
905
|
-
}
|
|
906
|
-
}), null);
|
|
907
|
-
effect(() => className(_el$2, styles$4.PianoRollContainer));
|
|
908
1019
|
return _el$;
|
|
909
1020
|
}
|
|
910
1021
|
});
|
|
@@ -912,7 +1023,7 @@ const PianoRoll = allProps => {
|
|
|
912
1023
|
|
|
913
1024
|
const _tmpl$ = /*#__PURE__*/template(`<div class="PlayHead"></div>`, 2);
|
|
914
1025
|
const PlayHead = allProps => {
|
|
915
|
-
const propsWithDefauls = mergeProps
|
|
1026
|
+
const propsWithDefauls = mergeProps({
|
|
916
1027
|
playHeadPosition: 0,
|
|
917
1028
|
sync: false
|
|
918
1029
|
}, allProps);
|
|
@@ -927,7 +1038,7 @@ const PlayHead = allProps => {
|
|
|
927
1038
|
const leftPosition = createMemo(() => viewPort.calculatePixelOffset(props.playHeadPosition));
|
|
928
1039
|
return (() => {
|
|
929
1040
|
const _el$ = _tmpl$.cloneNode(true);
|
|
930
|
-
spread(_el$, mergeProps(divProps, {
|
|
1041
|
+
spread(_el$, mergeProps$1(divProps, {
|
|
931
1042
|
get style() {
|
|
932
1043
|
return {
|
|
933
1044
|
position: "absolute",
|
|
@@ -988,37 +1099,83 @@ const useNotes = () => {
|
|
|
988
1099
|
};
|
|
989
1100
|
};
|
|
990
1101
|
|
|
991
|
-
const
|
|
992
|
-
const [
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
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, {
|
|
1003
1160
|
onPpqChange,
|
|
1004
|
-
|
|
1161
|
+
onModeChange,
|
|
1005
1162
|
onPositionChange,
|
|
1006
|
-
zoom,
|
|
1007
1163
|
onZoomChange,
|
|
1008
|
-
verticalPosition,
|
|
1009
|
-
onVerticalPositionChange,
|
|
1010
|
-
verticalZoom,
|
|
1011
1164
|
onVerticalZoomChange,
|
|
1012
|
-
|
|
1165
|
+
onVerticalPositionChange,
|
|
1166
|
+
onVerticalTrackZoomChange,
|
|
1167
|
+
onVerticalTrackPositionChange,
|
|
1013
1168
|
onGridDivisionChange,
|
|
1014
|
-
snapToGrid,
|
|
1015
1169
|
onSnapToGridChange,
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1170
|
+
onDurationChange,
|
|
1171
|
+
onTracksChange,
|
|
1172
|
+
onNoteChange,
|
|
1173
|
+
onInsertNote,
|
|
1174
|
+
onRemoveNote,
|
|
1175
|
+
onSelectedTrackIndexChange,
|
|
1176
|
+
onPressedKeysChange
|
|
1177
|
+
});
|
|
1021
1178
|
};
|
|
1022
1179
|
|
|
1023
|
-
export { PianoRoll, PlayHead,
|
|
1180
|
+
export { PianoRoll, PlayHead, createPianoRollstate, useNotes };
|
|
1024
1181
|
//# sourceMappingURL=index.js.map
|