Skip to content

Instantly share code, notes, and snippets.

@fabiospampinato
Created April 23, 2023 19:56
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fabiospampinato/8739843e34f43757989197337e93dd51 to your computer and use it in GitHub Desktop.
Save fabiospampinato/8739843e34f43757989197337e93dd51 to your computer and use it in GitHub Desktop.
My lag bar implementation for Voby
/* IMPORT */
import {$, $$, useEffect, useInterval} from 'voby';
/* STYLE */
css`
:root {
--lag-bar-color-bg: var(--color-black-bg);
}
.ui-lag-bar {
position: relative;
display: flex;
overflow: hidden;
border-radius: var(--border-radius-smooth);
background-color: var(--lag-bar-color-bg);
/* FLOATING */
&.floating {
position: absolute;
top: var(--gutter-100);
left: 50%;
transform: translateX(-50%);
box-shadow: var(--elevation-8);
z-index: var(--layer-8);
}
}
`;
/* TYPES */
type $<T> = T | (() => T);
type Props = {
floating?: $<boolean>,
height?: $<number>,
interval?: $<number>,
width?: $<number>
};
/* HELPERS */
const sigmoid = ( value: number ): number => {
return 1 / ( 1 + Math.exp ( -value ) );
};
const useLag = ( interval: $<number>, callback: ( elapsed: number ) => void ): void => {
let start = performance.now ();
useInterval ( () => {
const end = performance.now ();
const elapsed = ( end - start );
start = end;
callback ( elapsed );
}, interval );
};
/* MAIN */
const LagBar = ( { floating, height = 12, interval = 8, width = 256 }: Props ): JSX.Element => {
let ref = $<HTMLCanvasElement>();
let ctx: CanvasRenderingContext2D | undefined | null;
let x = 0;
useEffect ( () => {
ctx = ref ()?.getContext ( '2d' );
});
useLag ( interval, elapsed => {
const h = $$(height);
const i = $$(interval);
const w = $$(width);
if ( !ctx ) return;
const percentage = sigmoid ( ( Math.min ( 1, elapsed / ( i * 10 ) ) - 0.5 ) * 5 );
const green = Math.round ( 255 * ( 1 - percentage ) ).toString ( 16 ).padStart ( 2, '0' );
const red = Math.round ( 255 * percentage ).toString ( 16 ).padStart ( 2, '0' );
const color = `#${red}${green}00`;
const cursorSize = 4;
const elapsedSize = Math.round ( elapsed / i );
const elapsedSizeChunk1 = Math.min ( w - x, elapsedSize );
const elapsedSizeChunk2 = ( elapsedSize - elapsedSizeChunk1 );
ctx.fillStyle = color;
ctx.fillRect ( x, 0, elapsedSizeChunk1, h );
x = ( x + elapsedSizeChunk1 ) % w;
ctx.fillStyle = color;
ctx.fillRect ( x, 0, elapsedSizeChunk2, h );
x = ( x + elapsedSizeChunk2 ) % w;
ctx.fillStyle = '#ffffffff';
ctx.fillRect ( x, 0, cursorSize, h );
});
return (
<div use:ui="lag-bar" class={{ floating }} style={{ width, height }}>
<canvas ref={ref} width={width} height={height} />
</div>
);
};
/* EXPORT */
export default LagBar;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment