mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
Displays a white → #74E1B9 → #6ADCFF gradient HYPERFRAMES banner using ANSI Shadow figlet font when running hyperframes init. Gracefully skips in non-TTY or no-color environments. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
70 lines
4.7 KiB
TypeScript
70 lines
4.7 KiB
TypeScript
import { isColorSupported } from "./colors.js";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Gradient stops: white → teal #74E1B9 → cyan #6ADCFF
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const GRADIENT: [number, number, number][] = [
|
|
[255, 255, 255], // white
|
|
[116, 225, 185], // #74E1B9 teal
|
|
[106, 220, 255], // #6ADCFF cyan
|
|
];
|
|
|
|
function lerp(a: number, b: number, t: number): number {
|
|
return Math.round(a + (b - a) * t);
|
|
}
|
|
|
|
function gradientColor(t: number): [number, number, number] {
|
|
const segments = GRADIENT.length - 1;
|
|
const scaled = t * segments;
|
|
const i = Math.min(Math.floor(scaled), segments - 1);
|
|
const frac = scaled - i;
|
|
const a = GRADIENT[i]!;
|
|
const b = GRADIENT[i + 1]!;
|
|
return [lerp(a[0], b[0], frac), lerp(a[1], b[1], frac), lerp(a[2], b[2], frac)];
|
|
}
|
|
|
|
function rgb(r: number, g: number, b: number, text: string): string {
|
|
return `\x1b[38;2;${r};${g};${b}m${text}\x1b[0m`;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Box-drawing block art (figlet "ANSI Shadow" style)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const BANNER = [
|
|
"\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
|
|
"\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D",
|
|
"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
|
|
"\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u255A\u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551",
|
|
"\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551",
|
|
"\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D",
|
|
];
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Public
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function printBanner(): void {
|
|
if (!isColorSupported || !process.stdout.isTTY) return;
|
|
|
|
const maxWidth = Math.max(...BANNER.map((r) => r.length));
|
|
|
|
console.log();
|
|
for (const row of BANNER) {
|
|
let line = " ";
|
|
for (let col = 0; col < row.length; col++) {
|
|
const ch = row[col];
|
|
if (!ch || ch === " ") {
|
|
line += " ";
|
|
continue;
|
|
}
|
|
const t = maxWidth > 1 ? col / (maxWidth - 1) : 0;
|
|
const [r, g, b] = gradientColor(t);
|
|
line += rgb(r, g, b, ch);
|
|
}
|
|
console.log(line);
|
|
}
|
|
console.log();
|
|
}
|