solid-pianoroll 0.0.18 → 0.0.19

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/esm/index.js CHANGED
@@ -40,21 +40,28 @@ const usePianoRollContext = () => {
40
40
  };
41
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$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";
43
+ var css_248z$4 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\n border-width: 0;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-left-width: 1px;\n background: white;\n cursor: pointer;\n}\n\n.PianoRollKeys-module_Key__jybNC {\n transition-property: background-color, box-shadow;\n transition-duration: 200ms;\n transition-timing-function: ease-out;\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 120%;\n left: -20%;\n border-color: #000;\n border-style: solid;\n}\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
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
45
  styleInject(css_248z$4);
46
46
 
47
47
  function createViewPortDimension(getState) {
48
- const getStateWithFunctions = () => ({
49
- ...getState(),
50
- calculatePixelOffset,
51
- calculatePixelValue,
52
- calculatePosition,
53
- calculatePixelDimensions,
54
- calculateVisibleRange,
55
- calculateMaxPosition,
56
- isVisible
57
- });
48
+ const getStateWithFunctions = () => {
49
+ const state = getState();
50
+ const onZoomChange = zoom => state.onZoomChange?.(clamp(zoom, state.minZoom, state.maxZoom));
51
+ const onPositionChange = position => state.onPositionChange?.(position);
52
+ return {
53
+ ...state,
54
+ onZoomChange,
55
+ onPositionChange,
56
+ calculatePixelOffset,
57
+ calculatePixelValue,
58
+ calculatePosition,
59
+ calculatePixelDimensions,
60
+ calculateVisibleRange,
61
+ calculateMaxPosition,
62
+ isVisible
63
+ };
64
+ };
58
65
  const [state, setState] = createStore(getStateWithFunctions());
59
66
  createEffect(() => setState(getStateWithFunctions()));
60
67
  function calculatePixelValue(position = state.position) {
@@ -93,9 +100,18 @@ function createViewPortDimension(getState) {
93
100
  }
94
101
  const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
95
102
 
103
+ const defaultViewPortProps = {
104
+ pixelOffset: 0,
105
+ position: 0,
106
+ range: 1,
107
+ zoom: 1,
108
+ minZoom: 1,
109
+ maxZoom: Infinity
110
+ };
96
111
  const ScrollZoomViewPort = props => {
97
112
  const viewPorts = Object.entries(props.dimensions).map(([name, viewPortProps]) => createViewPortDimension(() => ({
98
113
  name: name,
114
+ ...defaultViewPortProps,
99
115
  ...viewPortProps()
100
116
  })));
101
117
  const parentViewPorts = useContext(ScrollZoomViewPortContext);
@@ -116,12 +132,12 @@ const useViewPortDimension = name => {
116
132
  return viewPort;
117
133
  };
118
134
 
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"};
135
+ var css_248z$3 = ".ScrollZoomContainer-module_ScrollZoomContainer__o2bRt {\n height: 100%;\n width: 100%;\n z-index: 4;\n}\n";
136
+ var styles$3 = {"ScrollZoomContainer":"ScrollZoomContainer-module_ScrollZoomContainer__o2bRt"};
121
137
  styleInject(css_248z$3);
122
138
 
123
- const _tmpl$$8 = /*#__PURE__*/template(`<div><div><div><div></div></div></div></div>`, 8);
124
- const ScrollContainer = props => {
139
+ const _tmpl$$7 = /*#__PURE__*/template(`<div><div><div><div></div></div></div></div>`, 8);
140
+ const ScrollZoomContainer = props => {
125
141
  let scrollContentRef;
126
142
  const [ownProps, divProps] = splitProps(props, ["ref", "verticalDimensionName", "horizontalDimensionName", "showScrollbar"]);
127
143
  const propsWithDefaults = mergeProps({
@@ -192,7 +208,7 @@ const ScrollContainer = props => {
192
208
  });
193
209
  });
194
210
  return (() => {
195
- const _el$ = _tmpl$$8.cloneNode(true),
211
+ const _el$ = _tmpl$$7.cloneNode(true),
196
212
  _el$2 = _el$.firstChild,
197
213
  _el$3 = _el$2.firstChild,
198
214
  _el$4 = _el$3.firstChild;
@@ -200,7 +216,7 @@ const ScrollContainer = props => {
200
216
  _el$.addEventListener("scroll", handleScroll);
201
217
  const _ref$ = props.ref;
202
218
  typeof _ref$ === "function" ? use(_ref$, _el$) : props.ref = _el$;
203
- spread(_el$, mergeProps$1({
219
+ spread(_el$, mergeProps$1(divProps, {
204
220
  get style() {
205
221
  return {
206
222
  overflow: propsWithDefaults.showScrollbar ? "scroll" : "hidden",
@@ -209,11 +225,11 @@ const ScrollContainer = props => {
209
225
  },
210
226
  get classList() {
211
227
  return {
212
- [styles$3.ScrollContainer]: true,
228
+ [styles$3.ScrollZoomContainer]: true,
213
229
  ...divProps.classList
214
230
  };
215
231
  }
216
- }, divProps), false, true);
232
+ }), false, true);
217
233
  const _ref$2 = scrollContentRef;
218
234
  typeof _ref$2 === "function" ? use(_ref$2, _el$2) : scrollContentRef = _el$2;
219
235
  _el$3.style.setProperty("top", "0");
@@ -242,9 +258,10 @@ const ScrollContainer = props => {
242
258
  })();
243
259
  };
244
260
 
245
- const _tmpl$$7 = /*#__PURE__*/template(`<div></div>`, 2);
261
+ const _tmpl$$6 = /*#__PURE__*/template(`<div></div>`, 2);
246
262
  const PianoRollKeys = () => {
247
- const viewPort = createMemo(() => useViewPortDimension("vertical"));
263
+ const verticalViewPort = createMemo(() => useViewPortDimension("vertical"));
264
+ const horizontalViewPort = createMemo(() => useViewPortDimension("horizontalKeys"));
248
265
  const [isMouseDown, setIsMouseDown] = createSignal(false);
249
266
  const context = usePianoRollContext();
250
267
  const handleMouseUp = () => {
@@ -257,106 +274,116 @@ const PianoRollKeys = () => {
257
274
  window.removeEventListener("mouseup", handleMouseUp);
258
275
  }
259
276
  });
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()) {
277
+ return (() => {
278
+ const _el$ = _tmpl$$6.cloneNode(true);
279
+ insert(_el$, createComponent(ScrollZoomContainer, {
280
+ horizontalDimensionName: "horizontalKeys",
281
+ showScrollbar: false,
282
+ get children() {
283
+ return createComponent(Index, {
284
+ each: keys,
285
+ children: key => {
286
+ const isDown = createMemo(() => context.pressedKeys.includes(key().number));
287
+ const handleKeyDown = () => {
288
+ context.onPressedKeysChange?.([...context.pressedKeys, key().number]);
289
+ };
290
+ const handleKeyUp = () => {
291
+ context.onPressedKeysChange?.([...context.pressedKeys].filter(number => number !== key().number));
292
+ };
293
+ const virtualDimensions = createMemo(() => verticalViewPort().calculatePixelDimensions(127 - key().number, 1));
294
+ const previousIsBlack = blackKeys.includes((key().number - 1) % 12);
295
+ const nextIsBlack = blackKeys.includes((key().number + 1) % 12);
296
+ return createComponent(Show, {
297
+ get when() {
298
+ return virtualDimensions().size > 0;
299
+ },
300
+ get children() {
301
+ const _el$2 = _tmpl$$6.cloneNode(true);
302
+ _el$2.addEventListener("mouseleave", () => {
303
+ if (isMouseDown()) {
304
+ handleKeyUp();
305
+ }
306
+ });
307
+ _el$2.addEventListener("mouseenter", () => {
308
+ if (isMouseDown()) {
309
+ handleKeyDown();
310
+ }
311
+ });
312
+ _el$2.$$mouseup = () => {
289
313
  handleKeyUp();
290
- }
291
- });
292
- _el$.addEventListener("mouseenter", () => {
293
- if (isMouseDown()) {
314
+ };
315
+ _el$2.$$mousedown = () => {
316
+ setIsMouseDown(true);
294
317
  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()
318
+ };
319
+ insert(_el$2, createComponent(Show, {
320
+ get when() {
321
+ return key().isBlack && false;
332
322
  },
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
- });
323
+ get children() {
324
+ const _el$3 = _tmpl$$6.cloneNode(true);
325
+ effect(_p$ => {
326
+ const _v$3 = styles$4["black-separator"],
327
+ _v$4 = `${virtualDimensions().offset}px`,
328
+ _v$5 = `${virtualDimensions().size / 2 - 0.25}px`;
329
+ _v$3 !== _p$._v$3 && className(_el$3, _p$._v$3 = _v$3);
330
+ _v$4 !== _p$._v$4 && _el$3.style.setProperty("top", _p$._v$4 = _v$4);
331
+ _v$5 !== _p$._v$5 && _el$3.style.setProperty("height", _p$._v$5 = _v$5);
332
+ return _p$;
333
+ }, {
334
+ _v$3: undefined,
335
+ _v$4: undefined,
336
+ _v$5: undefined
337
+ });
338
+ return _el$3;
339
+ }
340
+ }));
341
+ effect(_p$ => {
342
+ const _v$6 = {
343
+ [styles$4["Key"]]: true,
344
+ [styles$4["black"]]: key().isBlack,
345
+ [styles$4["white"]]: !key().isBlack,
346
+ [styles$4["down"]]: isDown()
347
+ },
348
+ _v$7 = key().name,
349
+ _v$8 = key().number % 12,
350
+ _v$9 = `${virtualDimensions().offset - (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0)}px`,
351
+ _v$10 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
352
+ _v$11 = [`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(", ");
353
+ _p$._v$6 = classList(_el$2, _v$6, _p$._v$6);
354
+ _v$7 !== _p$._v$7 && setAttribute(_el$2, "title", _p$._v$7 = _v$7);
355
+ _v$8 !== _p$._v$8 && setAttribute(_el$2, "data-index", _p$._v$8 = _v$8);
356
+ _v$9 !== _p$._v$9 && _el$2.style.setProperty("top", _p$._v$9 = _v$9);
357
+ _v$10 !== _p$._v$10 && _el$2.style.setProperty("height", _p$._v$10 = _v$10);
358
+ _v$11 !== _p$._v$11 && _el$2.style.setProperty("box-shadow", _p$._v$11 = _v$11);
359
+ return _p$;
360
+ }, {
361
+ _v$6: undefined,
362
+ _v$7: undefined,
363
+ _v$8: undefined,
364
+ _v$9: undefined,
365
+ _v$10: undefined,
366
+ _v$11: undefined
367
+ });
368
+ return _el$2;
369
+ }
370
+ });
371
+ }
372
+ });
373
+ }
374
+ }));
375
+ effect(_p$ => {
376
+ const _v$ = styles$4.PianoRollKeys,
377
+ _v$2 = `${horizontalViewPort().pixelSize}px`;
378
+ _v$ !== _p$._v$ && className(_el$, _p$._v$ = _v$);
379
+ _v$2 !== _p$._v$2 && _el$.style.setProperty("width", _p$._v$2 = _v$2);
380
+ return _p$;
381
+ }, {
382
+ _v$: undefined,
383
+ _v$2: undefined
384
+ });
385
+ return _el$;
386
+ })();
360
387
  };
361
388
  const blackKeys = [1, 3, 6, 8, 10];
362
389
  const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
@@ -373,7 +400,7 @@ var css_248z$2 = ".PianoRollNotes-module_PianoRollNotes__6pF-y {\n position: ab
373
400
  var styles$2 = {"PianoRollNotes":"PianoRollNotes-module_PianoRollNotes__6pF-y","Note":"PianoRollNotes-module_Note__-jxLb","trimStart":"PianoRollNotes-module_trimStart__vuBlj","trimEnd":"PianoRollNotes-module_trimEnd__zPdjr"};
374
401
  styleInject(css_248z$2);
375
402
 
376
- const _tmpl$$6 = /*#__PURE__*/template(`<div></div>`, 2);
403
+ const _tmpl$$5 = /*#__PURE__*/template(`<div></div>`, 2);
377
404
  const PianoRollNotes = props => {
378
405
  const context = usePianoRollContext();
379
406
  const verticalViewPort = createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
@@ -412,7 +439,7 @@ const PianoRollNotes = props => {
412
439
  return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
413
440
  };
414
441
  return (() => {
415
- const _el$ = _tmpl$$6.cloneNode(true);
442
+ const _el$ = _tmpl$$5.cloneNode(true);
416
443
  _el$.$$click = event => {
417
444
  if (currentNote()) {
418
445
  setCurrentNoteIndex(-1);
@@ -470,7 +497,7 @@ const PianoRollNotes = props => {
470
497
  return memo(() => !!verticalViewPort().isVisible(verticalVirtualDimensions()))() && horizontalViewPort().isVisible(horizontalDimensions());
471
498
  },
472
499
  get children() {
473
- const _el$2 = _tmpl$$6.cloneNode(true);
500
+ const _el$2 = _tmpl$$5.cloneNode(true);
474
501
  _el$2.$$mousedown = event => {
475
502
  event.stopPropagation();
476
503
  setIsDragging(true);
@@ -567,7 +594,9 @@ const PianoRollNotes = props => {
567
594
  });
568
595
  }
569
596
  }));
570
- effect(() => className(_el$, styles$2.PianoRollNotes));
597
+ effect(_$p => classList(_el$, {
598
+ [styles$2.PianoRollNotes]: true
599
+ }, _$p));
571
600
  return _el$;
572
601
  })();
573
602
  };
@@ -577,7 +606,7 @@ var css_248z$1 = ".PianoRollGrid-module_PianoRollGrid__tG119 {\n position: rela
577
606
  var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
578
607
  styleInject(css_248z$1);
579
608
 
580
- const _tmpl$$5 = /*#__PURE__*/template(`<div></div>`, 2);
609
+ const _tmpl$$4 = /*#__PURE__*/template(`<div></div>`, 2);
581
610
  const PianoRollGrid = () => {
582
611
  const context = usePianoRollContext();
583
612
  const verticalViewPort = createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
@@ -607,7 +636,7 @@ const PianoRollGrid = () => {
607
636
  }));
608
637
  });
609
638
  return (() => {
610
- const _el$ = _tmpl$$5.cloneNode(true);
639
+ const _el$ = _tmpl$$4.cloneNode(true);
611
640
  insert(_el$, createComponent(Index, {
612
641
  get each() {
613
642
  return gridArray();
@@ -619,7 +648,7 @@ const PianoRollGrid = () => {
619
648
  return virtualDimensions().size > 0;
620
649
  },
621
650
  get children() {
622
- const _el$2 = _tmpl$$5.cloneNode(true);
651
+ const _el$2 = _tmpl$$4.cloneNode(true);
623
652
  effect(_p$ => {
624
653
  const _v$ = styles$1["PianoRollGrid-Time"],
625
654
  _v$2 = Math.ceil((entry().index + 1 * selectedGridDivisorTicks()) / measureTicks()) % 2 === 0 ? "#ddd" : "#ccc",
@@ -658,7 +687,7 @@ const PianoRollGrid = () => {
658
687
  return virtualDimensions().size > 0;
659
688
  },
660
689
  get children() {
661
- const _el$3 = _tmpl$$5.cloneNode(true);
690
+ const _el$3 = _tmpl$$4.cloneNode(true);
662
691
  _el$3.style.setProperty("width", "100%");
663
692
  effect(_p$ => {
664
693
  const _v$6 = styles$1["PianoRollGrid-Row"],
@@ -702,7 +731,7 @@ const PianoRollGrid = () => {
702
731
  return virtualDimensions().size > 0;
703
732
  },
704
733
  get children() {
705
- const _el$4 = _tmpl$$5.cloneNode(true);
734
+ const _el$4 = _tmpl$$4.cloneNode(true);
706
735
  _el$4.style.setProperty("width", "100%");
707
736
  _el$4.style.setProperty("border-width", "0");
708
737
  effect(_p$ => {
@@ -761,50 +790,47 @@ function useBoundingClientRect(containerRef) {
761
790
  return boundingClientRect;
762
791
  }
763
792
 
764
- const _tmpl$$4 = /*#__PURE__*/template(`<input min="1" max="11" step="0.01">`, 1);
765
- const VerticalZoomControl = props => {
766
- const dimension = createMemo(() => useViewPortDimension(props.dimensionName ?? "vertical"));
793
+ const _tmpl$$3 = /*#__PURE__*/template(`<input step="0.01">`, 1);
794
+ const ZoomSliderControl = props => {
795
+ const propsWithDefaults = mergeProps({
796
+ orientation: "horizontal"
797
+ }, props);
798
+ const dimension = createMemo(() => useViewPortDimension(props.dimensionName ?? propsWithDefaults.orientation));
767
799
  return (() => {
768
- const _el$ = _tmpl$$4.cloneNode(true);
769
- spread(_el$, mergeProps$1(props, {
800
+ const _el$ = _tmpl$$3.cloneNode(true);
801
+ spread(_el$, mergeProps$1({
802
+ get min() {
803
+ return dimension().minZoom;
804
+ },
805
+ get max() {
806
+ return dimension().maxZoom;
807
+ }
808
+ }, props, {
770
809
  get value() {
771
810
  return dimension().zoom;
772
811
  },
773
812
  "onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
774
813
  "type": "range"
775
- }, {
776
- orient: "vertical"
777
- }, {
814
+ }, () => ({
815
+ orient: propsWithDefaults.orientation
816
+ }), {
778
817
  get style() {
779
- return {
818
+ return propsWithDefaults.orientation === "vertical" ? {
819
+ margin: 0,
820
+ "margin-left": "4px",
821
+ "margin-right": "4px",
780
822
  width: "16px",
781
823
  transform: "rotate(180deg)",
782
824
  ...{
783
825
  "writing-mode": "bt-lr" /* IE */,
784
826
  "-webkit-appearance": "slider-vertical" /* WebKit */
785
- }
786
- };
787
- }
788
- }), false, false);
789
- return _el$;
790
- })();
791
- };
827
+ },
792
828
 
793
- const _tmpl$$3 = /*#__PURE__*/template(`<input max="500" min="1" step="0.01">`, 1);
794
- const HorizontalZoomControl = props => {
795
- const dimension = createMemo(() => useViewPortDimension(props.dimensionName ?? "horizontal"));
796
- return (() => {
797
- const _el$ = _tmpl$$3.cloneNode(true);
798
- spread(_el$, mergeProps$1(props, {
799
- get value() {
800
- return dimension().zoom;
801
- },
802
- "onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
803
- "type": "range",
804
- get style() {
805
- return {
806
- "margin-left": "50px",
807
- "margin-right": "16px",
829
+ ...(typeof props.style === "object" && props.style)
830
+ } : {
831
+ margin: 0,
832
+ "margin-top": "4px",
833
+ "margin-bottom": "4px",
808
834
  ...(typeof props.style === "object" && props.style)
809
835
  };
810
836
  }
@@ -880,23 +906,11 @@ const PianoRoll = allProps => {
880
906
  showAllTracks: false
881
907
  }, allProps);
882
908
  const [context, divProps] = splitContextProps(propsWithDefaults);
883
- const [scrollerRef, setScrollerRef] = createSignal();
884
- const [trackScrollerRef, setTrackScrollerRef] = createSignal();
885
- const clientRect = useBoundingClientRect(scrollerRef);
886
- const trackClientRef = useBoundingClientRect(trackScrollerRef);
909
+ const [notesScrollerRef, setNotesScrollerRef] = createSignal();
910
+ const [tracksScrollerRef, setTracksScrollerRef] = createSignal();
911
+ const notesScrollerClientRect = useBoundingClientRect(notesScrollerRef);
912
+ const tracksScrollerClientRect = useBoundingClientRect(tracksScrollerRef);
887
913
  const zoomFactor = 500;
888
- const minZoom = createMemo(() => 1 / (zoomFactor / clientRect().width));
889
- const maxZoom = createMemo(() => 500 * (zoomFactor / clientRect().width));
890
- const minVerticalZoom = createMemo(() => 1 / (zoomFactor / clientRect().height));
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));
894
- createEffect(isInitial => {
895
- if (isInitial) return false;
896
- if (context.mode === "tracks") {
897
- context.onVerticalPositionChange?.(0);
898
- }
899
- }, true);
900
914
  return createComponent(PianoRollContextProvider, {
901
915
  value: context,
902
916
  get children() {
@@ -909,62 +923,64 @@ const PianoRoll = allProps => {
909
923
  insert(_el$, createComponent(ScrollZoomViewPort, {
910
924
  dimensions: {
911
925
  horizontal: () => ({
912
- pixelOffset: clientRect().left,
913
- pixelSize: clientRect().width,
926
+ pixelOffset: notesScrollerClientRect().left,
927
+ pixelSize: notesScrollerClientRect().width,
914
928
  position: context.position,
915
929
  range: context.duration,
916
- zoom: context.zoom * (zoomFactor / clientRect().width),
930
+ zoom: context.zoom * (zoomFactor / notesScrollerClientRect().width),
917
931
  onPositionChange: context.onPositionChange,
918
- onZoomChange: zoom => context.onZoomChange?.(clamp(zoom / (zoomFactor / clientRect().width), minZoom(), maxZoom()))
932
+ onZoomChange: zoom => context.onZoomChange?.(zoom / (zoomFactor / notesScrollerClientRect().width)),
933
+ minZoom: 1,
934
+ maxZoom: 500
919
935
  }),
920
936
  vertical: () => ({
921
- pixelOffset: clientRect().top,
922
- pixelSize: clientRect().height,
937
+ pixelOffset: notesScrollerClientRect().top,
938
+ pixelSize: notesScrollerClientRect().height,
923
939
  position: context.verticalPosition,
924
940
  range: 128,
925
- zoom: context.verticalZoom * (zoomFactor / clientRect().height),
941
+ zoom: context.verticalZoom * (zoomFactor / notesScrollerClientRect().height),
926
942
  onPositionChange: context.onVerticalPositionChange,
927
- onZoomChange: verticalZoom => context.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
943
+ onZoomChange: verticalZoom => context.onVerticalZoomChange?.(verticalZoom / (zoomFactor / notesScrollerClientRect().height)),
944
+ minZoom: 1,
945
+ maxZoom: 10
928
946
  }),
929
947
  horizontalTracks: () => ({
930
- pixelOffset: clientRect().left,
931
- pixelSize: clientRect().width,
932
- position: 0,
933
- range: 1,
934
- zoom: 1
948
+ pixelOffset: 0,
949
+ pixelSize: notesScrollerClientRect().width
935
950
  }),
936
951
  verticalTracks: () => ({
937
- pixelOffset: trackClientRef().top,
938
- pixelSize: trackClientRef().height,
952
+ pixelOffset: tracksScrollerClientRect().top,
953
+ pixelSize: tracksScrollerClientRect().height,
939
954
  position: context.verticalTrackPosition,
940
955
  range: context.tracks.length,
941
- zoom: context.verticalTrackZoom * (zoomFactor / trackClientRef().height),
956
+ zoom: context.verticalTrackZoom * (zoomFactor / tracksScrollerClientRect().height),
942
957
  onPositionChange: context.onVerticalTrackPositionChange,
943
- onZoomChange: verticalTrackZoom => context.onVerticalTrackZoomChange?.(clamp(verticalTrackZoom / (zoomFactor / trackClientRef().height), minVerticalTracksZoom(), maxVerticalTracksZoom()))
958
+ onZoomChange: verticalTrackZoom => context.onVerticalTrackZoomChange?.(verticalTrackZoom / (zoomFactor / tracksScrollerClientRect().height)),
959
+ minZoom: 0.8,
960
+ maxZoom: 3
961
+ }),
962
+ horizontalKeys: () => ({
963
+ pixelSize: 60
944
964
  })
945
965
  },
946
966
  get children() {
947
967
  return [(() => {
948
968
  const _el$2 = _tmpl$$1.cloneNode(true),
949
969
  _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
- },
970
+ insert(_el$2, createComponent(ZoomSliderControl, {
971
+ orientation: "vertical",
957
972
  dimensionName: "verticalTracks"
958
973
  }), _el$3);
959
974
  _el$3.style.setProperty("display", "flex");
960
- _el$3.style.setProperty("width", "20%");
975
+ _el$3.style.setProperty("width", "30%");
976
+ _el$3.style.setProperty("max-width", "250px");
961
977
  insert(_el$3, createComponent(Show, {
962
978
  get when() {
963
979
  return context.showTrackList;
964
980
  },
965
981
  get children() {
966
- return createComponent(ScrollContainer, {
967
- ref: setTrackScrollerRef,
982
+ return createComponent(ScrollZoomContainer, {
983
+ ref: setTracksScrollerRef,
968
984
  horizontalDimensionName: "horizontalTracks",
969
985
  verticalDimensionName: "verticalTracks",
970
986
  get showScrollbar() {
@@ -984,8 +1000,8 @@ const PianoRoll = allProps => {
984
1000
  return createComponent(PianoRollKeys, {});
985
1001
  }
986
1002
  }), null);
987
- insert(_el$2, createComponent(ScrollContainer, {
988
- ref: setScrollerRef,
1003
+ insert(_el$2, createComponent(ScrollZoomContainer, {
1004
+ ref: setNotesScrollerRef,
989
1005
  get verticalDimensionName() {
990
1006
  return context.mode === "keys" ? "vertical" : "verticalTracks";
991
1007
  },
@@ -993,25 +1009,21 @@ const PianoRoll = allProps => {
993
1009
  return [memo(() => allProps.children), createComponent(PianoRollGrid, {}), createComponent(PianoRollNotes, {})];
994
1010
  }
995
1011
  }), null);
996
- insert(_el$2, createComponent(VerticalZoomControl, {
997
- get min() {
998
- return minVerticalZoom();
999
- },
1000
- get max() {
1001
- return maxVerticalZoom();
1002
- },
1012
+ insert(_el$2, createComponent(ZoomSliderControl, {
1013
+ orientation: "vertical",
1003
1014
  get disabled() {
1004
1015
  return context.mode !== "keys";
1005
1016
  }
1006
1017
  }), null);
1007
1018
  effect(() => className(_el$2, styles$5.PianoRollContainer));
1008
1019
  return _el$2;
1009
- })(), createComponent(HorizontalZoomControl, {
1010
- get min() {
1011
- return minZoom();
1012
- },
1013
- get max() {
1014
- return maxZoom();
1020
+ })(), createComponent(ZoomSliderControl, {
1021
+ orientation: "horizontal",
1022
+ get style() {
1023
+ return {
1024
+ "margin-left": `${tracksScrollerClientRect().width + 24}px`,
1025
+ "margin-right": "24px"
1026
+ };
1015
1027
  }
1016
1028
  })];
1017
1029
  }