add pianoroll widget

This commit is contained in:
Felix Roos 2024-03-15 01:40:21 +01:00
parent 094b30cd26
commit 48e0691eec
8 changed files with 62 additions and 23 deletions

View File

@ -14,13 +14,18 @@ export const updateWidgets = (view, widgets) => {
};
function getWidgets(widgetConfigs) {
return widgetConfigs.map(({ to, type }) => {
return Decoration.widget({
widget: new BlockWidget(to, type),
side: 0,
block: true,
}).range(to);
});
return (
widgetConfigs
// codemirror throws an error if we don't sort
.sort((a, b) => a.to - b.to)
.map(({ to, type }) => {
return Decoration.widget({
widget: new BlockWidget(to, type),
side: 0,
block: true,
}).range(to);
})
);
}
const widgetField = StateField.define(

View File

@ -29,14 +29,14 @@ export const getDrawContext = (id = 'test-canvas', options) => {
return canvas.getContext(contextType);
};
Pattern.prototype.draw = function (callback, { from, to, onQuery } = {}) {
Pattern.prototype.draw = function (callback, { from, to, onQuery, ctx } = {}) {
if (typeof window === 'undefined') {
return this;
}
if (window.strudelAnimation) {
cancelAnimationFrame(window.strudelAnimation);
}
const ctx = getDrawContext();
ctx = ctx || getDrawContext();
let cycle,
events = [];
const animate = (time) => {

View File

@ -30,7 +30,7 @@ const getValue = (e) => {
};
Pattern.prototype.pianoroll = function (options = {}) {
let { cycles = 4, playhead = 0.5, overscan = 1, hideNegative = false } = options;
let { cycles = 4, playhead = 0.5, overscan = 1, hideNegative = false, ctx } = options;
let from = -cycles * playhead;
let to = cycles * (1 - playhead);
@ -49,6 +49,7 @@ Pattern.prototype.pianoroll = function (options = {}) {
{
from: from - overscan,
to: to + overscan,
ctx,
},
);
return this;

View File

@ -17,19 +17,17 @@ customElement('strudel-claviature', { options: JSON.stringify(defaultOptions) },
return c;
};
return (
<div>
<svg {...svg().attributes}>
<For each={svg().children}>
{(el) => {
return (
<Dynamic component={el.name} {...el.attributes}>
{el.value}
</Dynamic>
);
}}
</For>
</svg>
</div>
<svg {...svg().attributes}>
<For each={svg().children}>
{(el) => {
return (
<Dynamic component={el.name} {...el.attributes}>
{el.value}
</Dynamic>
);
}}
</For>
</svg>
);
});

View File

@ -0,0 +1,30 @@
import { Pattern } from '@strudel/core';
import { registerWidget } from '@strudel/transpiler';
import { customElement } from 'solid-element';
customElement('strudel-pianoroll', { options: JSON.stringify('{}') }, (props, { element }) => {
return <canvas width={400} height={100} />;
});
registerWidget('roll', 'strudel-pianoroll');
Pattern.prototype.roll = function (id, options = { fold: 1 }) {
// TODO: remove setTimeout...
setTimeout(() => {
let el = document.getElementById(id);
if (!el) {
console.log('widget not found...');
return this;
}
const { width = 400, height = 100 } = options;
const canvas = el?.shadowRoot.firstChild;
const pixelRatio = window.devicePixelRatio;
canvas.width = width * pixelRatio;
canvas.height = height * pixelRatio;
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
const ctx = canvas.getContext('2d');
this.pianoroll({ ...options, ctx });
});
return this;
};

View File

@ -1 +1,2 @@
export * from './Claviature.jsx';
export * from './Pianoroll.jsx';

View File

@ -29,6 +29,7 @@
"dependencies": {
"@strudel/core": "workspace:*",
"@strudel/transpiler": "workspace:*",
"@strudel/draw": "workspace:*",
"claviature": "^0.1.0",
"solid-element": "^1.8.0",
"solid-js": "^1.8.15",

3
pnpm-lock.yaml generated
View File

@ -493,6 +493,9 @@ importers:
'@strudel/core':
specifier: workspace:*
version: link:../core
'@strudel/draw':
specifier: workspace:*
version: link:../draw
'@strudel/transpiler':
specifier: workspace:*
version: link:../transpiler