mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
function lerp(start: number, end: number, t: number): number {
|
|
return start + (end - start) * t
|
|
}
|
|
|
|
export interface AnimationLoop {
|
|
/** User callback to be called on each animation frame. */
|
|
callback: FrameRequestCallback
|
|
/** {@link loopFrame} bound to this loop. */
|
|
frame: FrameRequestCallback
|
|
/** The current frame id returned by {@link requestAnimationFrame}. */
|
|
frame_id: number
|
|
}
|
|
|
|
export function animationLoop(callback: FrameRequestCallback): AnimationLoop {
|
|
const loop: AnimationLoop = {
|
|
callback: callback,
|
|
frame: t => loopFrame(loop, t),
|
|
frame_id: 0,
|
|
}
|
|
return loop
|
|
}
|
|
export function loopFrame(loop: AnimationLoop, time: number): void {
|
|
loop.frame_id = requestAnimationFrame(loop.frame)
|
|
loop.callback(time)
|
|
}
|
|
export function loopStart(loop: AnimationLoop): void {
|
|
loop.frame_id ||= requestAnimationFrame(loop.frame)
|
|
}
|
|
export function loopClear(loop: AnimationLoop): void {
|
|
cancelAnimationFrame(loop.frame_id)
|
|
loop.frame_id = 0
|
|
}
|
|
|
|
export const DEFAULT_TARGET_FPS = 44
|
|
|
|
export interface FrameIterationsLimit {
|
|
target_fps: number
|
|
last_timestamp: number
|
|
}
|
|
|
|
export function frameIterationsLimit(
|
|
target_fps: number = DEFAULT_TARGET_FPS,
|
|
): FrameIterationsLimit {
|
|
return {
|
|
target_fps,
|
|
last_timestamp: performance.now(),
|
|
}
|
|
}
|
|
export function calcIterations(limit: FrameIterationsLimit, current_time: number): number {
|
|
let target_ms = 1000 / limit.target_fps
|
|
let delta_time = current_time - limit.last_timestamp
|
|
let times = Math.floor(delta_time / target_ms)
|
|
limit.last_timestamp += times * target_ms
|
|
return times
|
|
}
|
|
|
|
export interface AlphaUpdateSteps {
|
|
increment: number
|
|
decrement: number
|
|
}
|
|
export const DEFAULT_ALPHA_UPDATE_STEPS: AlphaUpdateSteps = {
|
|
increment: 0.03,
|
|
decrement: 0.005,
|
|
}
|
|
export const updateAlpha = (
|
|
alpha: number,
|
|
is_playing: boolean,
|
|
update_steps = DEFAULT_ALPHA_UPDATE_STEPS,
|
|
): number => {
|
|
return is_playing
|
|
? lerp(alpha, 1, update_steps.increment)
|
|
: lerp(alpha, 0, update_steps.decrement)
|
|
}
|
|
|
|
export const DEFAULT_BUMP_TIMEOUT_DURATION = 2000
|
|
|
|
export const bump = (
|
|
bump_end: number,
|
|
duration: number = DEFAULT_BUMP_TIMEOUT_DURATION,
|
|
): number => {
|
|
const start = performance.now()
|
|
const end = start + duration
|
|
return end > bump_end ? end : bump_end
|
|
}
|