Alexander Zinchuk 3afcde3217 Initial commit
2021-04-09 14:11:51 +03:00

64 lines
1.6 KiB
TypeScript

type IWaveformProps = {
peak: number;
fillStyle: string;
progressFillStyle: string;
};
const SPIKE_WIDTH = 2;
const SPIKE_STEP = 4;
const SPIKE_RADIUS = 1;
const HEIGHT = 23;
export function renderWaveformToDataUri(
spikes: number[],
progress: number,
{
peak, fillStyle, progressFillStyle,
}: IWaveformProps,
) {
const width = spikes.length * SPIKE_STEP;
const height = HEIGHT;
const canvas = document.createElement('canvas');
canvas.width = width * 2;
canvas.height = height * 2;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
const ctx = canvas.getContext('2d')!;
ctx.scale(2, 2);
spikes.forEach((item, i) => {
ctx.globalAlpha = (i / spikes.length >= progress) ? 0.5 : 1;
ctx.fillStyle = progress > i / spikes.length ? progressFillStyle : fillStyle;
const spikeHeight = Math.max(2, HEIGHT * (item / Math.max(1, peak)));
roundedRectangle(ctx, i * SPIKE_STEP, height, SPIKE_WIDTH, spikeHeight, SPIKE_RADIUS);
ctx.fill();
});
return {
src: canvas.toDataURL(),
width,
height,
};
}
function roundedRectangle(
ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number,
) {
if (width < 2 * radius) {
radius = width / 2;
}
if (height < 2 * radius) {
radius = height / 2;
}
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.arcTo(x + width, y, x + width, y - height, radius);
ctx.arcTo(x + width, y - height, x, y - height, radius);
ctx.arcTo(x, y - height, x, y, radius);
ctx.arcTo(x, y, x + width, y, radius);
ctx.closePath();
}