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_signature[1]) * 200; // @ts-ignore const ctx = app.interface.feedback.getContext("2d"); // Assuming a canvas context /** * 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); };