mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 13:48:34 +00:00
support multiple animationFrames
+ break out spiral draw logic
This commit is contained in:
parent
a8712fd8ce
commit
6dce9d5deb
@ -29,12 +29,13 @@ export const getDrawContext = (id = 'test-canvas', options) => {
|
||||
return canvas.getContext(contextType);
|
||||
};
|
||||
|
||||
Pattern.prototype.draw = function (callback, { from, to, onQuery, ctx } = {}) {
|
||||
let animationFrames = {};
|
||||
Pattern.prototype.draw = function (callback, { id = 'std', from, to, onQuery, ctx } = {}) {
|
||||
if (typeof window === 'undefined') {
|
||||
return this;
|
||||
}
|
||||
if (window.strudelAnimation) {
|
||||
cancelAnimationFrame(window.strudelAnimation);
|
||||
if (animationFrames[id]) {
|
||||
cancelAnimationFrame(animationFrames[id]);
|
||||
}
|
||||
ctx = ctx || getDrawContext();
|
||||
let cycle,
|
||||
@ -56,7 +57,7 @@ Pattern.prototype.draw = function (callback, { from, to, onQuery, ctx } = {}) {
|
||||
}
|
||||
}
|
||||
callback(ctx, events, t, time);
|
||||
window.strudelAnimation = requestAnimationFrame(animate);
|
||||
animationFrames[id] = requestAnimationFrame(animate);
|
||||
};
|
||||
requestAnimationFrame(animate);
|
||||
return this;
|
||||
@ -64,18 +65,18 @@ Pattern.prototype.draw = function (callback, { from, to, onQuery, ctx } = {}) {
|
||||
|
||||
// this is a more generic helper to get a rendering callback for the currently active haps
|
||||
// TODO: this misses events that are prolonged with clip or duration (would need state)
|
||||
Pattern.prototype.onFrame = function (fn, offset = 0) {
|
||||
Pattern.prototype.onFrame = function (id, fn, offset = 0) {
|
||||
if (typeof window === 'undefined') {
|
||||
return this;
|
||||
}
|
||||
if (window.strudelAnimation) {
|
||||
cancelAnimationFrame(window.strudelAnimation);
|
||||
if (animationFrames[id]) {
|
||||
cancelAnimationFrame(animationFrames[id]);
|
||||
}
|
||||
const animate = () => {
|
||||
const t = getTime() + offset;
|
||||
const haps = this.queryArc(t, t);
|
||||
fn(haps, t, this);
|
||||
window.strudelAnimation = requestAnimationFrame(animate);
|
||||
animationFrames[id] = requestAnimationFrame(animate);
|
||||
};
|
||||
requestAnimationFrame(animate);
|
||||
return this;
|
||||
@ -84,9 +85,7 @@ Pattern.prototype.onFrame = function (fn, offset = 0) {
|
||||
export const cleanupDraw = (clearScreen = true) => {
|
||||
const ctx = getDrawContext();
|
||||
clearScreen && ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.width);
|
||||
if (window.strudelAnimation) {
|
||||
cancelAnimationFrame(window.strudelAnimation);
|
||||
}
|
||||
Object.values(animationFrames).forEach((id) => cancelAnimationFrame(id));
|
||||
if (window.strudelScheduler) {
|
||||
clearInterval(window.strudelScheduler);
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ const getValue = (e) => {
|
||||
};
|
||||
|
||||
Pattern.prototype.pianoroll = function (options = {}) {
|
||||
let { cycles = 4, playhead = 0.5, overscan = 1, hideNegative = false, ctx } = options;
|
||||
let { cycles = 4, playhead = 0.5, overscan = 1, hideNegative = false, ctx, id } = options;
|
||||
|
||||
let from = -cycles * playhead;
|
||||
let to = cycles * (1 - playhead);
|
||||
@ -50,6 +50,7 @@ Pattern.prototype.pianoroll = function (options = {}) {
|
||||
from: from - overscan,
|
||||
to: to + overscan,
|
||||
ctx,
|
||||
id,
|
||||
},
|
||||
);
|
||||
return this;
|
||||
|
||||
@ -49,7 +49,7 @@ function spiralSegment(options) {
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
Pattern.prototype.spiral = function (options = {}) {
|
||||
function drawSpiral(options) {
|
||||
const {
|
||||
stretch = 1,
|
||||
size = 80,
|
||||
@ -65,54 +65,58 @@ Pattern.prototype.spiral = function (options = {}) {
|
||||
colorizeInactive = 0,
|
||||
fade = true,
|
||||
// logSpiral = true,
|
||||
ctx,
|
||||
time,
|
||||
haps,
|
||||
drawTime,
|
||||
} = options;
|
||||
|
||||
function spiral({ ctx, time, haps, drawTime }) {
|
||||
const [w, h] = [ctx.canvas.width, ctx.canvas.height];
|
||||
ctx.clearRect(0, 0, w * 2, h * 2);
|
||||
const [cx, cy] = [w / 2, h / 2];
|
||||
const settings = {
|
||||
margin: size / stretch,
|
||||
cx,
|
||||
cy,
|
||||
stretch,
|
||||
cap,
|
||||
thickness,
|
||||
};
|
||||
const [w, h] = [ctx.canvas.width, ctx.canvas.height];
|
||||
ctx.clearRect(0, 0, w * 2, h * 2);
|
||||
const [cx, cy] = [w / 2, h / 2];
|
||||
const settings = {
|
||||
margin: size / stretch,
|
||||
cx,
|
||||
cy,
|
||||
stretch,
|
||||
cap,
|
||||
thickness,
|
||||
};
|
||||
|
||||
const playhead = {
|
||||
...settings,
|
||||
thickness: playheadThickness,
|
||||
from: inset - playheadLength,
|
||||
to: inset,
|
||||
color: playheadColor,
|
||||
};
|
||||
const playhead = {
|
||||
...settings,
|
||||
thickness: playheadThickness,
|
||||
from: inset - playheadLength,
|
||||
to: inset,
|
||||
color: playheadColor,
|
||||
};
|
||||
|
||||
const [min] = drawTime;
|
||||
const rotate = steady * time;
|
||||
haps.forEach((hap) => {
|
||||
const isActive = hap.whole.begin <= time && hap.endClipped > time;
|
||||
const from = hap.whole.begin - time + inset;
|
||||
const to = hap.endClipped - time + inset - padding;
|
||||
const { color } = hap.context;
|
||||
const opacity = fade ? 1 - Math.abs((hap.whole.begin - time) / min) : 1;
|
||||
spiralSegment({
|
||||
ctx,
|
||||
...settings,
|
||||
from,
|
||||
to,
|
||||
rotate,
|
||||
color: colorizeInactive || isActive ? color : inactiveColor,
|
||||
fromOpacity: opacity,
|
||||
toOpacity: opacity,
|
||||
});
|
||||
});
|
||||
const [min] = drawTime;
|
||||
const rotate = steady * time;
|
||||
haps.forEach((hap) => {
|
||||
const isActive = hap.whole.begin <= time && hap.endClipped > time;
|
||||
const from = hap.whole.begin - time + inset;
|
||||
const to = hap.endClipped - time + inset - padding;
|
||||
const { color } = hap.context;
|
||||
const opacity = fade ? 1 - Math.abs((hap.whole.begin - time) / min) : 1;
|
||||
spiralSegment({
|
||||
ctx,
|
||||
...playhead,
|
||||
...settings,
|
||||
from,
|
||||
to,
|
||||
rotate,
|
||||
color: colorizeInactive || isActive ? color : inactiveColor,
|
||||
fromOpacity: opacity,
|
||||
toOpacity: opacity,
|
||||
});
|
||||
}
|
||||
});
|
||||
spiralSegment({
|
||||
ctx,
|
||||
...playhead,
|
||||
rotate,
|
||||
});
|
||||
}
|
||||
|
||||
return this.onPaint((ctx, time, haps, drawTime) => spiral({ ctx, time, haps, drawTime }));
|
||||
Pattern.prototype.spiral = function (options = {}) {
|
||||
return this.onPaint((ctx, time, haps, drawTime) => drawSpiral({ ctx, time, haps, drawTime, ...options }));
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user