solid-pianoroll 0.0.2
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/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/cjs/index.js +403 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.js +401 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/source/PianoRoll.jsx +282 -0
- package/dist/source/helpers.js +3 -0
- package/dist/source/index.jsx +2 -0
- package/dist/source/useViewPortScaler.js +31 -0
- package/dist/types/PianoRoll.d.ts +19 -0
- package/dist/types/helpers.d.ts +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/useViewPortScaler.d.ts +15 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 jdachtera
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<p>
|
|
2
|
+
<img width="100%" src="https://assets.solidjs.com/banner?type=solid-pianoroll&background=tiles&project=%20" alt="solid-pianoroll">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# solid-pianoroll
|
|
6
|
+
|
|
7
|
+
[](https://yarnpkg.com/)
|
|
8
|
+
|
|
9
|
+
[Demo](https://solid-pianoroll.netlify.app/)
|
|
10
|
+
|
|
11
|
+
Pianoroll UI Control for Solid JS apps
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
Install it:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm i solid-pianoroll
|
|
19
|
+
# or
|
|
20
|
+
yarn add solid-pianoroll
|
|
21
|
+
# or
|
|
22
|
+
pnpm add solid-pianoroll
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Use it:
|
|
26
|
+
|
|
27
|
+
### Interactive waveform
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { PianoRoll } from "solid-pianoroll";
|
|
31
|
+
|
|
32
|
+
<PianoRoll
|
|
33
|
+
...
|
|
34
|
+
/>
|
|
35
|
+
|
|
36
|
+
```
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var web = require('solid-js/web');
|
|
4
|
+
var solidJs = require('solid-js');
|
|
5
|
+
|
|
6
|
+
const clamp = (value, min, max) => {
|
|
7
|
+
return Math.max(min, Math.min(max, value));
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
function useViewPortScaler(getState) {
|
|
11
|
+
const state = solidJs.createMemo(() => getState());
|
|
12
|
+
function getScaledValue(position) {
|
|
13
|
+
const virtualSize = state().viewPortSize * state().zoom;
|
|
14
|
+
return position / state().virtualRange * virtualSize;
|
|
15
|
+
}
|
|
16
|
+
function getCoordinates(position) {
|
|
17
|
+
return getScaledValue(position) - getScaledValue(state().virtualPosition);
|
|
18
|
+
}
|
|
19
|
+
function getPosition(offset) {
|
|
20
|
+
const visibleDuration = state().virtualRange / state().zoom;
|
|
21
|
+
const percentX = (offset - state().viewPortOffset) / state().viewPortSize;
|
|
22
|
+
const position = state().virtualPosition + percentX * visibleDuration;
|
|
23
|
+
return position;
|
|
24
|
+
}
|
|
25
|
+
function getVirtualDimensions(position, length) {
|
|
26
|
+
const virtualLeft = getCoordinates(position);
|
|
27
|
+
const virtualWidth = getScaledValue(length);
|
|
28
|
+
const offset = clamp(virtualLeft, 0, state().viewPortSize);
|
|
29
|
+
const size = clamp(virtualWidth - (offset - virtualLeft), 0, state().viewPortSize - offset);
|
|
30
|
+
return {
|
|
31
|
+
offset,
|
|
32
|
+
size
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
getScaledValue,
|
|
37
|
+
getCoordinates,
|
|
38
|
+
getPosition,
|
|
39
|
+
getVirtualDimensions
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const _tmpl$ = /*#__PURE__*/web.template(`<div><div><div class="PianoRoll-Keys"></div><div><div class="PianoRoll-Notes-Container"><div class="PianoRoll-Notes"></div></div><div class="PianoRoll-Vertical-Scroller"><div></div></div></div><input type="range" min="1" max="11" step="0.01"></div><input type="range" max="500" min="1" step="0.01"></div>`, 18),
|
|
44
|
+
_tmpl$2 = /*#__PURE__*/web.template(`<div class="PianoRoll-Key"></div>`, 2),
|
|
45
|
+
_tmpl$3 = /*#__PURE__*/web.template(`<div class="PianoRoll-Note"></div>`, 2);
|
|
46
|
+
const PianoRoll = allProps => {
|
|
47
|
+
let scrollContainerRef;
|
|
48
|
+
let scrollContentRef;
|
|
49
|
+
let notesContainerRef;
|
|
50
|
+
const [props, divProps] = solidJs.splitProps(allProps, ["ppq", "notes", "position", "duration", "zoom", "verticalPosition", "verticalZoom", "onVerticalZoomChange", "onVerticalPositionChange", "onZoomChange", "onPositionChange", "onNoteChange"]);
|
|
51
|
+
const [dimensions, setDimensions] = solidJs.createSignal({
|
|
52
|
+
left: 0,
|
|
53
|
+
width: 0,
|
|
54
|
+
top: 0,
|
|
55
|
+
height: 0
|
|
56
|
+
});
|
|
57
|
+
const resizeObserver = new ResizeObserver(event => {
|
|
58
|
+
const {
|
|
59
|
+
left,
|
|
60
|
+
top,
|
|
61
|
+
width,
|
|
62
|
+
height
|
|
63
|
+
} = scrollContainerRef?.getBoundingClientRect() ?? {
|
|
64
|
+
left: 0,
|
|
65
|
+
width: 0,
|
|
66
|
+
top: 0,
|
|
67
|
+
height: 0
|
|
68
|
+
};
|
|
69
|
+
setDimensions({
|
|
70
|
+
left,
|
|
71
|
+
top,
|
|
72
|
+
width,
|
|
73
|
+
height
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
solidJs.createEffect(() => {
|
|
77
|
+
console.log(props.notes);
|
|
78
|
+
});
|
|
79
|
+
solidJs.onMount(() => {
|
|
80
|
+
if (!scrollContainerRef) return;
|
|
81
|
+
resizeObserver.observe(scrollContainerRef);
|
|
82
|
+
});
|
|
83
|
+
solidJs.onCleanup(() => {
|
|
84
|
+
resizeObserver.disconnect();
|
|
85
|
+
});
|
|
86
|
+
const horizontalViewPort = useViewPortScaler(() => ({
|
|
87
|
+
viewPortOffset: dimensions().left,
|
|
88
|
+
viewPortSize: dimensions().width,
|
|
89
|
+
virtualPosition: props.position,
|
|
90
|
+
virtualRange: props.duration,
|
|
91
|
+
zoom: props.zoom
|
|
92
|
+
}));
|
|
93
|
+
const verticalViewPort = useViewPortScaler(() => ({
|
|
94
|
+
viewPortOffset: dimensions().top,
|
|
95
|
+
viewPortSize: dimensions().height,
|
|
96
|
+
virtualPosition: props.verticalPosition,
|
|
97
|
+
virtualRange: 128,
|
|
98
|
+
zoom: props.verticalZoom
|
|
99
|
+
}));
|
|
100
|
+
const handleScroll = event => {
|
|
101
|
+
event.preventDefault();
|
|
102
|
+
if (didUpdateScroll) {
|
|
103
|
+
didUpdateScroll = false;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const maxVerticalPosition = 128 - 128 / props.verticalZoom;
|
|
107
|
+
const maxPosition = props.duration - props.duration / props.zoom;
|
|
108
|
+
const {
|
|
109
|
+
width,
|
|
110
|
+
height
|
|
111
|
+
} = dimensions();
|
|
112
|
+
const {
|
|
113
|
+
scrollTop,
|
|
114
|
+
scrollLeft,
|
|
115
|
+
scrollWidth,
|
|
116
|
+
scrollHeight
|
|
117
|
+
} = event.currentTarget;
|
|
118
|
+
const scrollTopAmount = scrollTop / (scrollHeight - height);
|
|
119
|
+
const scrollLeftAmount = scrollLeft / (scrollWidth - width);
|
|
120
|
+
props.onVerticalPositionChange?.(maxVerticalPosition * scrollTopAmount);
|
|
121
|
+
props.onPositionChange?.(maxPosition * scrollLeftAmount);
|
|
122
|
+
};
|
|
123
|
+
let didUpdateScroll = false;
|
|
124
|
+
solidJs.createEffect(() => {
|
|
125
|
+
const maxVerticalPosition = 128 - 128 / props.verticalZoom;
|
|
126
|
+
const maxPosition = props.duration - props.duration / props.zoom;
|
|
127
|
+
const scrollTopAmount = maxVerticalPosition > 0 ? props.verticalPosition / maxVerticalPosition : 0;
|
|
128
|
+
const scrollLeftAmount = maxPosition > 0 ? props.position / maxPosition : 0;
|
|
129
|
+
const {
|
|
130
|
+
height,
|
|
131
|
+
width
|
|
132
|
+
} = dimensions();
|
|
133
|
+
if (!scrollContentRef?.parentElement) return;
|
|
134
|
+
const scrollDivHeight = clamp(props.verticalZoom * height, height, 10000);
|
|
135
|
+
const scrollTop = scrollTopAmount * (scrollDivHeight - height);
|
|
136
|
+
const scrollDivWidth = clamp(props.zoom * width, width, 10000);
|
|
137
|
+
const scrollLeft = scrollLeftAmount * (scrollDivWidth - width);
|
|
138
|
+
didUpdateScroll = true;
|
|
139
|
+
scrollContentRef.style.height = `${scrollDivHeight}px`;
|
|
140
|
+
scrollContentRef.style.width = `${scrollDivWidth}px`;
|
|
141
|
+
scrollContentRef.parentElement.scrollTo({
|
|
142
|
+
left: scrollLeft,
|
|
143
|
+
top: scrollTop
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
const forwardEventToNote = event => {
|
|
147
|
+
const x = "clientX" in event ? event.clientX : event.touches[0]?.clientX;
|
|
148
|
+
const y = "clientY" in event ? event.clientY : event.touches[0]?.clientY;
|
|
149
|
+
const elementUnderMouse = [...(notesContainerRef?.querySelectorAll?.("div") ?? [])].find(element => {
|
|
150
|
+
const rect = element.getBoundingClientRect();
|
|
151
|
+
return x >= rect.left && rect.left + rect.width > x && y >= rect.top && rect.top + rect.height > y;
|
|
152
|
+
});
|
|
153
|
+
if (elementUnderMouse) {
|
|
154
|
+
return elementUnderMouse.dispatchEvent(new MouseEvent(event.type, event));
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const [noteDragMode, setNoteDragMode] = solidJs.createSignal();
|
|
158
|
+
const [isDragging, setIsDragging] = solidJs.createSignal(false);
|
|
159
|
+
return (() => {
|
|
160
|
+
const _el$ = _tmpl$.cloneNode(true),
|
|
161
|
+
_el$2 = _el$.firstChild,
|
|
162
|
+
_el$3 = _el$2.firstChild,
|
|
163
|
+
_el$4 = _el$3.nextSibling,
|
|
164
|
+
_el$5 = _el$4.firstChild,
|
|
165
|
+
_el$6 = _el$5.firstChild,
|
|
166
|
+
_el$7 = _el$5.nextSibling,
|
|
167
|
+
_el$8 = _el$7.firstChild,
|
|
168
|
+
_el$9 = _el$4.nextSibling,
|
|
169
|
+
_el$10 = _el$2.nextSibling;
|
|
170
|
+
web.spread(_el$, web.mergeProps(divProps, {
|
|
171
|
+
"class": "PianoRoll",
|
|
172
|
+
get style() {
|
|
173
|
+
return {
|
|
174
|
+
"box-sizing": "border-box",
|
|
175
|
+
display: "flex",
|
|
176
|
+
overflow: "hidden",
|
|
177
|
+
"flex-direction": "column",
|
|
178
|
+
padding: "16px",
|
|
179
|
+
...(typeof divProps.style === "object" && divProps.style)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}), false, true);
|
|
183
|
+
_el$2.style.setProperty("overflow", "hidden");
|
|
184
|
+
_el$2.style.setProperty("height", "100%");
|
|
185
|
+
_el$2.style.setProperty("display", "flex");
|
|
186
|
+
_el$2.style.setProperty("flex-direction", "row");
|
|
187
|
+
_el$3.style.setProperty("position", "relative");
|
|
188
|
+
_el$3.style.setProperty("height", "100%");
|
|
189
|
+
_el$3.style.setProperty("width", "50px");
|
|
190
|
+
web.insert(_el$3, web.createComponent(solidJs.Index, {
|
|
191
|
+
each: keys,
|
|
192
|
+
children: key => {
|
|
193
|
+
const virtualDimensions = solidJs.createMemo(() => verticalViewPort.getVirtualDimensions(127 - key().number, 1));
|
|
194
|
+
return web.createComponent(solidJs.Show, {
|
|
195
|
+
get when() {
|
|
196
|
+
return virtualDimensions().size > 0;
|
|
197
|
+
},
|
|
198
|
+
get children() {
|
|
199
|
+
const _el$11 = _tmpl$2.cloneNode(true);
|
|
200
|
+
_el$11.style.setProperty("position", "absolute");
|
|
201
|
+
_el$11.style.setProperty("box-sizing", "border-box");
|
|
202
|
+
_el$11.style.setProperty("left", "0");
|
|
203
|
+
_el$11.style.setProperty("width", "100%");
|
|
204
|
+
_el$11.style.setProperty("border-color", "#000");
|
|
205
|
+
_el$11.style.setProperty("border-style", "solid");
|
|
206
|
+
web.effect(_p$ => {
|
|
207
|
+
const _v$5 = key().name,
|
|
208
|
+
_v$6 = key().number % 12,
|
|
209
|
+
_v$7 = `${virtualDimensions().offset}px`,
|
|
210
|
+
_v$8 = `${virtualDimensions().size}px`,
|
|
211
|
+
_v$9 = key().isBlack ? "#000" : "#fff",
|
|
212
|
+
_v$10 = `${!key().isBlack && !blackKeys.includes((key().number + 1) % 12) ? "0.1px" : 0} 1px ${!key().isBlack && !blackKeys.includes((key().number - 1) % 12) ? "0.1px" : 0} 0`;
|
|
213
|
+
_v$5 !== _p$._v$5 && web.setAttribute(_el$11, "title", _p$._v$5 = _v$5);
|
|
214
|
+
_v$6 !== _p$._v$6 && web.setAttribute(_el$11, "data-index", _p$._v$6 = _v$6);
|
|
215
|
+
_v$7 !== _p$._v$7 && _el$11.style.setProperty("top", _p$._v$7 = _v$7);
|
|
216
|
+
_v$8 !== _p$._v$8 && _el$11.style.setProperty("height", _p$._v$8 = _v$8);
|
|
217
|
+
_v$9 !== _p$._v$9 && _el$11.style.setProperty("background-color", _p$._v$9 = _v$9);
|
|
218
|
+
_v$10 !== _p$._v$10 && _el$11.style.setProperty("border-width", _p$._v$10 = _v$10);
|
|
219
|
+
return _p$;
|
|
220
|
+
}, {
|
|
221
|
+
_v$5: undefined,
|
|
222
|
+
_v$6: undefined,
|
|
223
|
+
_v$7: undefined,
|
|
224
|
+
_v$8: undefined,
|
|
225
|
+
_v$9: undefined,
|
|
226
|
+
_v$10: undefined
|
|
227
|
+
});
|
|
228
|
+
return _el$11;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}));
|
|
233
|
+
_el$4.style.setProperty("position", "relative");
|
|
234
|
+
_el$4.style.setProperty("display", "flex");
|
|
235
|
+
_el$4.style.setProperty("overflow", "hidden");
|
|
236
|
+
_el$4.style.setProperty("flex", "1");
|
|
237
|
+
_el$5.style.setProperty("position", "absolute");
|
|
238
|
+
const _ref$ = notesContainerRef;
|
|
239
|
+
typeof _ref$ === "function" ? web.use(_ref$, _el$6) : notesContainerRef = _el$6;
|
|
240
|
+
_el$6.style.setProperty("position", "relative");
|
|
241
|
+
_el$6.style.setProperty("height", "100%");
|
|
242
|
+
web.insert(_el$6, web.createComponent(solidJs.Index, {
|
|
243
|
+
get each() {
|
|
244
|
+
return props.notes;
|
|
245
|
+
},
|
|
246
|
+
children: (note, index) => {
|
|
247
|
+
const horizontalVirtualDimensions = solidJs.createMemo(() => verticalViewPort.getVirtualDimensions(127 - note().midi, 1));
|
|
248
|
+
const verticalVirtualDimensions = solidJs.createMemo(() => horizontalViewPort.getVirtualDimensions(note().ticks, note().durationTicks));
|
|
249
|
+
return web.createComponent(solidJs.Show, {
|
|
250
|
+
get when() {
|
|
251
|
+
return web.memo(() => !!!!horizontalVirtualDimensions().size)() && !!verticalVirtualDimensions().size;
|
|
252
|
+
},
|
|
253
|
+
get children() {
|
|
254
|
+
const _el$12 = _tmpl$3.cloneNode(true);
|
|
255
|
+
_el$12.$$mousedown = event => {
|
|
256
|
+
setIsDragging(true);
|
|
257
|
+
const initialPosition = horizontalViewPort.getPosition(event.clientX);
|
|
258
|
+
const diffPosition = initialPosition - note().ticks;
|
|
259
|
+
const handleMouseMove = mouseMoveEvent => {
|
|
260
|
+
const ticks = Math.max(horizontalViewPort.getPosition(mouseMoveEvent.clientX) - diffPosition, 0);
|
|
261
|
+
props.onNoteChange?.(index, {
|
|
262
|
+
...note(),
|
|
263
|
+
midi: Math.round(127 - verticalViewPort.getPosition(mouseMoveEvent.clientY)),
|
|
264
|
+
...((noteDragMode() === "move" || noteDragMode() === "trimStart") && {
|
|
265
|
+
ticks
|
|
266
|
+
}),
|
|
267
|
+
...(noteDragMode() === "trimStart" && {
|
|
268
|
+
durationTicks: note().durationTicks + note().ticks - ticks
|
|
269
|
+
}),
|
|
270
|
+
...(noteDragMode() === "trimEnd" && {
|
|
271
|
+
durationTicks: horizontalViewPort.getPosition(mouseMoveEvent.clientX) - note().ticks
|
|
272
|
+
})
|
|
273
|
+
});
|
|
274
|
+
};
|
|
275
|
+
const handleMouseUp = () => {
|
|
276
|
+
setIsDragging(false);
|
|
277
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
278
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
279
|
+
};
|
|
280
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
281
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
282
|
+
};
|
|
283
|
+
_el$12.$$mousemove = event => {
|
|
284
|
+
if (isDragging()) return;
|
|
285
|
+
const relativeX = horizontalViewPort.getScaledValue(horizontalViewPort.getPosition(event.clientX));
|
|
286
|
+
const noteStartX = horizontalViewPort.getScaledValue(note().ticks);
|
|
287
|
+
const noteEndX = horizontalViewPort.getScaledValue(note().ticks + note().durationTicks);
|
|
288
|
+
setNoteDragMode(relativeX - noteStartX < 3 ? "trimStart" : noteEndX - relativeX < 3 ? "trimEnd" : "move");
|
|
289
|
+
};
|
|
290
|
+
_el$12.style.setProperty("z-index", "1");
|
|
291
|
+
_el$12.style.setProperty("position", "absolute");
|
|
292
|
+
_el$12.style.setProperty("box-sizing", "border-box");
|
|
293
|
+
_el$12.style.setProperty("border-width", "0.5px");
|
|
294
|
+
_el$12.style.setProperty("border-style", "solid");
|
|
295
|
+
_el$12.style.setProperty("background-color", "#f00");
|
|
296
|
+
_el$12.style.setProperty("border-color", "#a00");
|
|
297
|
+
web.effect(_p$ => {
|
|
298
|
+
const _v$11 = `${horizontalVirtualDimensions().offset}px`,
|
|
299
|
+
_v$12 = `${horizontalVirtualDimensions().size}px`,
|
|
300
|
+
_v$13 = `${verticalVirtualDimensions().offset}px`,
|
|
301
|
+
_v$14 = `${verticalVirtualDimensions().size}px`;
|
|
302
|
+
_v$11 !== _p$._v$11 && _el$12.style.setProperty("top", _p$._v$11 = _v$11);
|
|
303
|
+
_v$12 !== _p$._v$12 && _el$12.style.setProperty("height", _p$._v$12 = _v$12);
|
|
304
|
+
_v$13 !== _p$._v$13 && _el$12.style.setProperty("left", _p$._v$13 = _v$13);
|
|
305
|
+
_v$14 !== _p$._v$14 && _el$12.style.setProperty("width", _p$._v$14 = _v$14);
|
|
306
|
+
return _p$;
|
|
307
|
+
}, {
|
|
308
|
+
_v$11: undefined,
|
|
309
|
+
_v$12: undefined,
|
|
310
|
+
_v$13: undefined,
|
|
311
|
+
_v$14: undefined
|
|
312
|
+
});
|
|
313
|
+
return _el$12;
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}));
|
|
318
|
+
_el$7.addEventListener("dragend", forwardEventToNote);
|
|
319
|
+
_el$7.addEventListener("drag", forwardEventToNote);
|
|
320
|
+
_el$7.addEventListener("dragstart", forwardEventToNote);
|
|
321
|
+
_el$7.addEventListener("touchcancel", forwardEventToNote);
|
|
322
|
+
_el$7.$$touchend = forwardEventToNote;
|
|
323
|
+
_el$7.$$touchmove = forwardEventToNote;
|
|
324
|
+
_el$7.$$touchstart = forwardEventToNote;
|
|
325
|
+
_el$7.$$mouseup = forwardEventToNote;
|
|
326
|
+
_el$7.$$dblclick = event => {
|
|
327
|
+
if (!forwardEventToNote(event)) ;
|
|
328
|
+
};
|
|
329
|
+
_el$7.$$click = forwardEventToNote;
|
|
330
|
+
_el$7.$$mousemove = event => {
|
|
331
|
+
if (forwardEventToNote(event)) return;
|
|
332
|
+
if (isDragging()) return;
|
|
333
|
+
setNoteDragMode(undefined);
|
|
334
|
+
};
|
|
335
|
+
_el$7.$$mousedown = forwardEventToNote;
|
|
336
|
+
_el$7.addEventListener("scroll", handleScroll);
|
|
337
|
+
const _ref$2 = scrollContainerRef;
|
|
338
|
+
typeof _ref$2 === "function" ? web.use(_ref$2, _el$7) : scrollContainerRef = _el$7;
|
|
339
|
+
const _ref$3 = scrollContentRef;
|
|
340
|
+
typeof _ref$3 === "function" ? web.use(_ref$3, _el$8) : scrollContentRef = _el$8;
|
|
341
|
+
_el$9.$$input = event => props.onVerticalZoomChange?.(event.currentTarget.valueAsNumber);
|
|
342
|
+
web.spread(_el$9, web.mergeProps({
|
|
343
|
+
get value() {
|
|
344
|
+
return props.verticalZoom;
|
|
345
|
+
}
|
|
346
|
+
}, {
|
|
347
|
+
orient: "vertical"
|
|
348
|
+
}, {
|
|
349
|
+
get style() {
|
|
350
|
+
return {
|
|
351
|
+
width: "16px",
|
|
352
|
+
...{
|
|
353
|
+
"writing-mode": "bt-lr" /* IE */,
|
|
354
|
+
"-webkit-appearance": "slider-vertical" /* WebKit */
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
}), false, false);
|
|
359
|
+
_el$10.$$input = event => props.onZoomChange?.(event.currentTarget.valueAsNumber);
|
|
360
|
+
_el$10.style.setProperty("margin-left", "50px");
|
|
361
|
+
_el$10.style.setProperty("margin-right", "16px");
|
|
362
|
+
web.effect(_p$ => {
|
|
363
|
+
const _v$ = `${dimensions().width}px`,
|
|
364
|
+
_v$2 = `${dimensions().height}px`,
|
|
365
|
+
_v$3 = `${dimensions().width}px`,
|
|
366
|
+
_v$4 = {
|
|
367
|
+
flex: 1,
|
|
368
|
+
...(noteDragMode() && {
|
|
369
|
+
cursor: noteDragMode() === "trimStart" ? "w-resize" : noteDragMode() === "trimEnd" ? "e-resize" : "pointer"
|
|
370
|
+
}),
|
|
371
|
+
//"box-sizing": "border-box",
|
|
372
|
+
"z-index": 1,
|
|
373
|
+
overflow: "scroll",
|
|
374
|
+
"pointer-events": "auto"
|
|
375
|
+
};
|
|
376
|
+
_v$ !== _p$._v$ && _el$5.style.setProperty("width", _p$._v$ = _v$);
|
|
377
|
+
_v$2 !== _p$._v$2 && _el$5.style.setProperty("height", _p$._v$2 = _v$2);
|
|
378
|
+
_v$3 !== _p$._v$3 && _el$6.style.setProperty("width", _p$._v$3 = _v$3);
|
|
379
|
+
_p$._v$4 = web.style(_el$7, _v$4, _p$._v$4);
|
|
380
|
+
return _p$;
|
|
381
|
+
}, {
|
|
382
|
+
_v$: undefined,
|
|
383
|
+
_v$2: undefined,
|
|
384
|
+
_v$3: undefined,
|
|
385
|
+
_v$4: undefined
|
|
386
|
+
});
|
|
387
|
+
web.effect(() => _el$10.value = props.zoom);
|
|
388
|
+
return _el$;
|
|
389
|
+
})();
|
|
390
|
+
};
|
|
391
|
+
const blackKeys = [1, 3, 6, 8, 10];
|
|
392
|
+
const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
393
|
+
const keys = Array.from({
|
|
394
|
+
length: 128
|
|
395
|
+
}).map((_, index) => ({
|
|
396
|
+
number: index,
|
|
397
|
+
name: `${keyNames[index % 12]} ${Math.floor(index / 12) - 2}`,
|
|
398
|
+
isBlack: blackKeys.includes(index % 12)
|
|
399
|
+
}));
|
|
400
|
+
web.delegateEvents(["mousedown", "mousemove", "click", "dblclick", "mouseup", "touchstart", "touchmove", "touchend", "input"]);
|
|
401
|
+
|
|
402
|
+
exports.PianoRoll = PianoRoll;
|
|
403
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/helpers.ts","../../src/useViewPortScaler.ts","../../src/PianoRoll.tsx"],"sourcesContent":["export const clamp = (value: number, min: number, max: number) => {\n return Math.max(min, Math.min(max, value));\n};\n","import { createMemo } from \"solid-js\";\nimport { clamp } from \"./helpers\";\n\nexport default function useViewPortScaler(\n getState: () => {\n virtualPosition: number;\n virtualRange: number;\n\n viewPortOffset: number;\n viewPortSize: number;\n\n zoom: number;\n },\n) {\n const state = createMemo(() => getState());\n\n function getScaledValue(position: number) {\n const virtualSize = state().viewPortSize * state().zoom;\n return (position / state().virtualRange) * virtualSize;\n }\n\n function getCoordinates(position: number) {\n return getScaledValue(position) - getScaledValue(state().virtualPosition);\n }\n\n function getPosition(offset: number) {\n const visibleDuration = state().virtualRange / state().zoom;\n const percentX = (offset - state().viewPortOffset) / state().viewPortSize;\n const position = state().virtualPosition + percentX * visibleDuration;\n\n return position;\n }\n\n function getVirtualDimensions(position: number, length: number) {\n const virtualLeft = getCoordinates(position);\n const virtualWidth = getScaledValue(length);\n\n const offset = clamp(virtualLeft, 0, state().viewPortSize);\n const size = clamp(virtualWidth - (offset - virtualLeft), 0, state().viewPortSize - offset);\n\n return { offset, size };\n }\n\n return {\n getScaledValue,\n getCoordinates,\n getPosition,\n getVirtualDimensions,\n };\n}\n","import { Midi } from \"@tonejs/midi\";\n\nimport {\n JSX,\n createMemo,\n splitProps,\n createSignal,\n onMount,\n onCleanup,\n Index,\n createEffect,\n Show,\n} from \"solid-js\";\nimport { clamp } from \"./helpers\";\nimport useViewPortScaler from \"./useViewPortScaler\";\n\ntype Note = Pick<\n ReturnType<Midi[\"tracks\"][number][\"notes\"][number][\"toJSON\"]>,\n \"durationTicks\" | \"midi\" | \"ticks\" | \"velocity\"\n>;\n\ntype PianoRollProps = {\n ppq: number;\n notes: Note[];\n\n verticalPosition: number;\n verticalZoom: number;\n\n position: number;\n duration: number;\n zoom: number;\n\n onVerticalZoomChange?: (zoom: number) => void;\n onVerticalPositionChange?: (zoom: number) => void;\n onZoomChange?: (zoom: number) => void;\n onPositionChange?: (zoom: number) => void;\n\n onNoteChange?: (index: number, note: Note) => void;\n} & JSX.IntrinsicElements[\"div\"];\n\nconst PianoRoll = (allProps: PianoRollProps) => {\n let scrollContainerRef: HTMLDivElement | undefined;\n let scrollContentRef: HTMLDivElement | undefined;\n let notesContainerRef: HTMLDivElement | undefined;\n\n const [props, divProps] = splitProps(allProps, [\n \"ppq\",\n \"notes\",\n \"position\",\n \"duration\",\n \"zoom\",\n \"verticalPosition\",\n \"verticalZoom\",\n \"onVerticalZoomChange\",\n \"onVerticalPositionChange\",\n \"onZoomChange\",\n \"onPositionChange\",\n \"onNoteChange\",\n ]);\n\n const [dimensions, setDimensions] = createSignal<{\n left: number;\n width: number;\n top: number;\n height: number;\n }>({\n left: 0,\n width: 0,\n top: 0,\n height: 0,\n });\n\n const resizeObserver = new ResizeObserver((event) => {\n const { left, top, width, height } = scrollContainerRef?.getBoundingClientRect() ?? {\n left: 0,\n width: 0,\n top: 0,\n height: 0,\n };\n setDimensions({ left, top, width, height });\n });\n\n createEffect(() => {\n console.log(props.notes);\n });\n onMount(() => {\n if (!scrollContainerRef) return;\n resizeObserver.observe(scrollContainerRef);\n });\n\n onCleanup(() => {\n resizeObserver.disconnect();\n });\n\n const horizontalViewPort = useViewPortScaler(() => ({\n viewPortOffset: dimensions().left,\n viewPortSize: dimensions().width,\n virtualPosition: props.position,\n virtualRange: props.duration,\n zoom: props.zoom,\n }));\n\n const verticalViewPort = useViewPortScaler(() => ({\n viewPortOffset: dimensions().top,\n viewPortSize: dimensions().height,\n virtualPosition: props.verticalPosition,\n virtualRange: 128,\n zoom: props.verticalZoom,\n }));\n\n const handleScroll = (event: UIEvent & { currentTarget: Element }) => {\n event.preventDefault();\n\n if (didUpdateScroll) {\n didUpdateScroll = false;\n return;\n }\n const maxVerticalPosition = 128 - 128 / props.verticalZoom;\n const maxPosition = props.duration - props.duration / props.zoom;\n\n const { width, height } = dimensions();\n const { scrollTop, scrollLeft, scrollWidth, scrollHeight } = event.currentTarget;\n\n const scrollTopAmount = scrollTop / (scrollHeight - height);\n const scrollLeftAmount = scrollLeft / (scrollWidth - width);\n\n props.onVerticalPositionChange?.(maxVerticalPosition * scrollTopAmount);\n props.onPositionChange?.(maxPosition * scrollLeftAmount);\n };\n\n let didUpdateScroll = false;\n\n createEffect(() => {\n const maxVerticalPosition = 128 - 128 / props.verticalZoom;\n const maxPosition = props.duration - props.duration / props.zoom;\n\n const scrollTopAmount =\n maxVerticalPosition > 0 ? props.verticalPosition / maxVerticalPosition : 0;\n const scrollLeftAmount = maxPosition > 0 ? props.position / maxPosition : 0;\n\n const { height, width } = dimensions();\n\n if (!scrollContentRef?.parentElement) return;\n\n const scrollDivHeight = clamp(props.verticalZoom * height, height, 10000);\n const scrollTop = scrollTopAmount * (scrollDivHeight - height);\n\n const scrollDivWidth = clamp(props.zoom * width, width, 10000);\n const scrollLeft = scrollLeftAmount * (scrollDivWidth - width);\n\n didUpdateScroll = true;\n\n scrollContentRef.style.height = `${scrollDivHeight}px`;\n scrollContentRef.style.width = `${scrollDivWidth}px`;\n\n scrollContentRef.parentElement.scrollTo({\n left: scrollLeft,\n top: scrollTop,\n });\n });\n\n const forwardEventToNote = (event: MouseEvent | PointerEvent | TouchEvent) => {\n const x = \"clientX\" in event ? event.clientX : event.touches[0]?.clientX;\n const y = \"clientY\" in event ? event.clientY : event.touches[0]?.clientY;\n\n const elementUnderMouse = [...(notesContainerRef?.querySelectorAll?.(\"div\") ?? [])].find(\n (element) => {\n const rect = element.getBoundingClientRect();\n\n return (\n x >= rect.left &&\n rect.left + rect.width > x &&\n y >= rect.top &&\n rect.top + rect.height > y\n );\n },\n );\n\n if (elementUnderMouse) {\n return elementUnderMouse.dispatchEvent(new MouseEvent(event.type, event));\n }\n };\n\n type NoteDragMode = \"trimStart\" | \"move\" | \"trimEnd\";\n const [noteDragMode, setNoteDragMode] = createSignal<NoteDragMode>();\n const [isDragging, setIsDragging] = createSignal(false);\n\n return (\n <div\n {...divProps}\n class=\"PianoRoll\"\n style={{\n \"box-sizing\": \"border-box\",\n display: \"flex\",\n overflow: \"hidden\",\n \"flex-direction\": \"column\",\n padding: \"16px\",\n ...(typeof divProps.style === \"object\" && divProps.style),\n }}\n >\n <div\n style={{\n overflow: \"hidden\",\n height: \"100%\",\n display: \"flex\",\n \"flex-direction\": \"row\",\n }}\n >\n <div\n class=\"PianoRoll-Keys\"\n style={{\n position: \"relative\",\n height: \"100%\",\n width: `${50}px`,\n }}\n >\n <Index each={keys}>\n {(key) => {\n const virtualDimensions = createMemo(() =>\n verticalViewPort.getVirtualDimensions(127 - key().number, 1),\n );\n\n return (\n <Show when={virtualDimensions().size > 0}>\n <div\n class=\"PianoRoll-Key\"\n title={key().name}\n data-index={key().number % 12}\n style={{\n position: \"absolute\",\n \"box-sizing\": \"border-box\",\n left: 0,\n top: `${virtualDimensions().offset}px`,\n height: `${virtualDimensions().size}px`,\n width: \"100%\",\n \"background-color\": key().isBlack ? \"#000\" : \"#fff\",\n \"border-width\": `${\n !key().isBlack && !blackKeys.includes((key().number + 1) % 12) ? \"0.1px\" : 0\n } 1px ${\n !key().isBlack && !blackKeys.includes((key().number - 1) % 12) ? \"0.1px\" : 0\n } 0`,\n \"border-color\": \"#000\",\n\n \"border-style\": \"solid\",\n }}\n ></div>\n </Show>\n );\n }}\n </Index>\n </div>\n\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n overflow: \"hidden\",\n flex: 1,\n }}\n >\n <div\n class=\"PianoRoll-Notes-Container\"\n style={{\n position: \"absolute\",\n width: `${dimensions().width}px`,\n height: `${dimensions().height}px`,\n }}\n >\n <div\n class=\"PianoRoll-Notes\"\n ref={notesContainerRef}\n style={{\n position: \"relative\",\n width: `${dimensions().width}px`,\n height: \"100%\",\n }}\n >\n <Index each={props.notes}>\n {(note, index) => {\n const horizontalVirtualDimensions = createMemo(() =>\n verticalViewPort.getVirtualDimensions(127 - note().midi, 1),\n );\n\n const verticalVirtualDimensions = createMemo(() =>\n horizontalViewPort.getVirtualDimensions(note().ticks, note().durationTicks),\n );\n\n return (\n <Show\n when={\n !!horizontalVirtualDimensions().size && !!verticalVirtualDimensions().size\n }\n >\n <div\n class=\"PianoRoll-Note\"\n onMouseMove={(event) => {\n if (isDragging()) return;\n\n const relativeX = horizontalViewPort.getScaledValue(\n horizontalViewPort.getPosition(event.clientX),\n );\n const noteStartX = horizontalViewPort.getScaledValue(note().ticks);\n const noteEndX = horizontalViewPort.getScaledValue(\n note().ticks + note().durationTicks,\n );\n\n setNoteDragMode(\n relativeX - noteStartX < 3\n ? \"trimStart\"\n : noteEndX - relativeX < 3\n ? \"trimEnd\"\n : \"move\",\n );\n }}\n onMouseDown={(event) => {\n setIsDragging(true);\n const initialPosition = horizontalViewPort.getPosition(event.clientX);\n const diffPosition = initialPosition - note().ticks;\n\n const handleMouseMove = (mouseMoveEvent: MouseEvent) => {\n const ticks = Math.max(\n horizontalViewPort.getPosition(mouseMoveEvent.clientX) - diffPosition,\n 0,\n );\n\n props.onNoteChange?.(index, {\n ...note(),\n midi: Math.round(\n 127 - verticalViewPort.getPosition(mouseMoveEvent.clientY),\n ),\n ...((noteDragMode() === \"move\" || noteDragMode() === \"trimStart\") && {\n ticks,\n }),\n ...(noteDragMode() === \"trimStart\" && {\n durationTicks: note().durationTicks + note().ticks - ticks,\n }),\n ...(noteDragMode() === \"trimEnd\" && {\n durationTicks:\n horizontalViewPort.getPosition(mouseMoveEvent.clientX) -\n note().ticks,\n }),\n });\n };\n const handleMouseUp = () => {\n setIsDragging(false);\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n }}\n style={{\n \"z-index\": 1,\n\n position: \"absolute\",\n \"box-sizing\": \"border-box\",\n top: `${horizontalVirtualDimensions().offset}px`,\n height: `${horizontalVirtualDimensions().size}px`,\n left: `${verticalVirtualDimensions().offset}px`,\n width: `${verticalVirtualDimensions().size}px`,\n \"border-width\": \"0.5px\",\n \"border-style\": \"solid\",\n \"background-color\": \"#f00\",\n \"border-color\": \"#a00\",\n }}\n ></div>\n </Show>\n );\n }}\n </Index>\n </div>\n </div>\n <div\n ref={scrollContainerRef}\n class=\"PianoRoll-Vertical-Scroller\"\n style={{\n flex: 1,\n ...(noteDragMode() && {\n cursor:\n noteDragMode() === \"trimStart\"\n ? \"w-resize\"\n : noteDragMode() === \"trimEnd\"\n ? \"e-resize\"\n : \"pointer\",\n }),\n //\"box-sizing\": \"border-box\",\n \"z-index\": 1,\n overflow: \"scroll\",\n \"pointer-events\": \"auto\",\n }}\n onScroll={handleScroll}\n onMouseDown={forwardEventToNote}\n onMouseMove={(event) => {\n if (forwardEventToNote(event)) return;\n if (isDragging()) return;\n setNoteDragMode(undefined);\n }}\n onClick={forwardEventToNote}\n onDblClick={(event) => {\n if (!forwardEventToNote(event)) {\n //TODO create new note with current gutter length\n }\n }}\n onMouseUp={forwardEventToNote}\n onTouchStart={forwardEventToNote}\n onTouchMove={forwardEventToNote}\n onTouchEnd={forwardEventToNote}\n onTouchCancel={forwardEventToNote}\n onDragStart={forwardEventToNote}\n onDrag={forwardEventToNote}\n onDragEnd={forwardEventToNote}\n >\n <div ref={scrollContentRef}></div>\n </div>\n </div>\n\n <input\n value={props.verticalZoom}\n onInput={(event) => props.onVerticalZoomChange?.(event.currentTarget.valueAsNumber)}\n type=\"range\"\n min=\"1\"\n max=\"11\"\n step={0.01}\n {...{ orient: \"vertical\" }}\n style={{\n width: \"16px\",\n ...({\n \"writing-mode\": \"bt-lr\" /* IE */,\n \"-webkit-appearance\": \"slider-vertical\" /* WebKit */,\n } as any),\n }}\n />\n </div>\n\n <input\n value={props.zoom}\n onInput={(event) => props.onZoomChange?.(event.currentTarget.valueAsNumber)}\n type=\"range\"\n max=\"500\"\n min=\"1\"\n step={0.01}\n style={{\n \"margin-left\": \"50px\",\n \"margin-right\": \"16px\",\n }}\n />\n </div>\n );\n};\n\nconst blackKeys = [1, 3, 6, 8, 10];\nconst keyNames = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\nconst keys = Array.from({ length: 128 }).map((_, index) => ({\n number: index,\n name: `${keyNames[index % 12]} ${Math.floor(index / 12) - 2}`,\n isBlack: blackKeys.includes(index % 12),\n}));\n\nexport default PianoRoll;\n"],"names":["clamp","value","min","max","Math","useViewPortScaler","getState","state","createMemo","getScaledValue","position","virtualSize","viewPortSize","zoom","virtualRange","getCoordinates","virtualPosition","getPosition","offset","visibleDuration","percentX","viewPortOffset","getVirtualDimensions","length","virtualLeft","virtualWidth","size","PianoRoll","allProps","scrollContainerRef","scrollContentRef","notesContainerRef","props","divProps","splitProps","dimensions","setDimensions","createSignal","left","width","top","height","resizeObserver","ResizeObserver","event","getBoundingClientRect","createEffect","console","log","notes","onMount","observe","onCleanup","disconnect","horizontalViewPort","duration","verticalViewPort","verticalPosition","verticalZoom","handleScroll","preventDefault","didUpdateScroll","maxVerticalPosition","maxPosition","scrollTop","scrollLeft","scrollWidth","scrollHeight","currentTarget","scrollTopAmount","scrollLeftAmount","onVerticalPositionChange","onPositionChange","parentElement","scrollDivHeight","scrollDivWidth","style","scrollTo","forwardEventToNote","x","clientX","touches","y","clientY","elementUnderMouse","querySelectorAll","find","element","rect","dispatchEvent","MouseEvent","type","noteDragMode","setNoteDragMode","isDragging","setIsDragging","_$spread","_$mergeProps","display","overflow","padding","_$insert","_$createComponent","Index","keys","key","virtualDimensions","number","Show","_$effect","name","isBlack","blackKeys","includes","_$setAttribute","_$use","note","index","horizontalVirtualDimensions","midi","verticalVirtualDimensions","ticks","durationTicks","_$memo","initialPosition","diffPosition","handleMouseMove","mouseMoveEvent","onNoteChange","round","handleMouseUp","window","removeEventListener","addEventListener","relativeX","noteStartX","noteEndX","undefined","onVerticalZoomChange","valueAsNumber","orient","onZoomChange","flex","cursor","_$style","keyNames","Array","from","map","_","floor","_$delegateEvents"],"mappings":"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"}
|