Files
topos/src/DOM/Visuals/Blinkers.ts
2024-04-20 03:06:23 +02:00

119 lines
3.1 KiB
TypeScript

import { type Editor } from "../../main";
export const drawCircle = (
/**
* Draw a circle at a specific position on the canvas.
* @param {number} x - The x-coordinate of the circle's center.
* @param {number} y - The y-coordinate of the circle's center.
* @param {number} radius - The radius of the circle.
* @param {string} color - The fill color of the circle.
*/
app: Editor,
x: number,
y: number,
radius: number,
color: string,
): void => {
// @ts-ignore
const canvas: HTMLCanvasElement = app.interface.feedback;
const ctx = canvas.getContext("2d");
if (!ctx) return;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = color;
ctx.fill();
ctx.closePath();
};
export const blinkScript = (
/**
* Blinks a script indicator circle.
* @param script - The type of script.
* @param no - The shift amount multiplier.
*/
app: Editor,
script: "local" | "global" | "init",
no?: number,
) => {
if (no !== undefined && no < 1 && no > 9) return;
const blinkDuration =
(app.clock.bpm / 60 / app.clock.time_position.num) * 200;
// @ts-ignore
const ctx = app.interface.feedback.getContext("2d");
/**
* Draws a circle at a given shift.
* @param shift - The pixel distance from the origin.
*/
const _drawBlinker = (shift: number) => {
const horizontalOffset = 50;
drawCircle(
app,
horizontalOffset + shift,
app.interface.feedback.clientHeight - 15,
8,
"#fdba74",
);
};
const _clearBlinker = (shift: number) => {
/**
* Clears the circle at a given shift.
* @param shift - The pixel distance from the origin.
*/
const x = 50 + shift;
const y = app.interface.feedback.clientHeight - 15;
const radius = 8;
ctx.clearRect(x - radius, y - radius, radius * 2, radius * 2);
};
if (script === "local" && no !== undefined) {
const shiftAmount = no * 25;
// Clear existing timeout if any
if (app.blinkTimeouts[shiftAmount]) {
clearTimeout(app.blinkTimeouts[shiftAmount]);
}
_drawBlinker(shiftAmount);
// Save timeout ID for later clearing
// @ts-ignore
app.blinkTimeouts[shiftAmount] = setTimeout(() => {
_clearBlinker(shiftAmount);
// Clear the canvas before drawing new blinkers
(app.interface.feedback as HTMLCanvasElement)
.getContext("2d")!
.clearRect(
0,
0,
(app.interface.feedback as HTMLCanvasElement).width,
(app.interface.feedback as HTMLCanvasElement).height,
);
}, blinkDuration);
}
};
export const scriptBlinkers = () => {
/**
* Manages animation updates using requestAnimationFrame.
* @param app - The Editor application context.
*/
let lastFrameTime = Date.now();
const frameRate = 10;
const minFrameDelay = 1000 / frameRate;
const update = () => {
const now = Date.now();
const timeSinceLastFrame = now - lastFrameTime;
if (timeSinceLastFrame >= minFrameDelay) {
lastFrameTime = now;
}
requestAnimationFrame(update);
};
requestAnimationFrame(update);
};