UNPKG

@trap_stevo/terminal-plus

Version:

Transform your CLI into a visually striking, feature-rich command layer. Blend animated gradients, stylish badges, dynamic progress bars, sleek tables, and precise formatting utilities — all turning terminal output into a powerful visual experience.

179 lines (178 loc) 5.15 kB
"use strict"; const chalk = require("chalk"); const easing = { easeInOutQuad: t => t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2, easeInOut: t => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t, cosine: t => (1 - Math.cos(t * Math.PI)) / 2, linear: t => t }; function convertHexToRGB(hex) { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return [r, g, b]; } ; function hexToRGB(hex) { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } ; function generateLerp(a, b, t) { return a + (b - a) * t; } ; function generateColorInterpolation(color1, color2, factor) { const result = color1.slice(); for (let i = 0; i < 3; i++) { result[i] = Math.round(generateLerp(color1[i], color2[i], factor)); } return result; } ; function generateGradientColors(colors, steps, easingType = "linear") { let gradient = []; const sections = colors.length - 1; const stepsPerSection = Math.floor(steps / sections); for (let section = 0; section < sections; section++) { for (let step = 0; step < stepsPerSection; step++) { const color1 = convertHexToRGB(colors[section]); const color2 = convertHexToRGB(colors[section + 1]); const t = step / stepsPerSection; const factor = easing[easingType] ? easing[easingType](t) : t; gradient.push(generateColorInterpolation(color1, color2, factor)); } } gradient.push(convertHexToRGB(colors[colors.length - 1])); while (gradient.length < steps) { gradient.push(convertHexToRGB(colors[colors.length - 1])); } return gradient; } ; function generateGradientText(text, colors = ["#ffffff", "#000000"]) { if (!Array.isArray(colors) || colors.length === 0) { return text; } const segments = colors.length - 1; const segmentLength = text.length / segments; let gradientText = ""; for (let i = 0; i < text.length; i++) { const seg = Math.min(Math.floor(i / segmentLength), segments - 1); const ratio = i % segmentLength / segmentLength; const startRGB = convertHexToRGB(colors[seg]); const endRGB = convertHexToRGB(colors[seg + 1]); if (!startRGB || !endRGB) { gradientText += text[i]; continue; } const [r, g, b] = generateColorInterpolation(startRGB, endRGB, ratio); gradientText += chalk.rgb(r, g, b)(text[i]); } return gradientText; } ; function outputGradient(text, colors) { const gradient = generateGradientColors(colors, text.length); let coloredText = ""; for (let i = 0; i < text.length; i++) { const [r, g, b] = gradient[i]; coloredText += chalk.rgb(r, g, b)(text[i]); } console.log(coloredText); } ; function movingGradientRenderer(text, colors, interval = 100, skipRange = [0, 0], options = {}) { const readline = require("readline"); const { inlinePosition = "left" } = options; let offset = 0; let intervalID = null; let running = false; let inlineFollower = ""; const renderFrame = () => { const gradientColors = generateGradientColors(colors, text.length); let coloredText = ""; for (let i = 0; i < text.length; i++) { if (i >= skipRange[0] && i < skipRange[1]) { coloredText += text[i]; continue; } const colorIndex = (i + offset) % gradientColors.length; const [r, g, b] = gradientColors[colorIndex]; coloredText += chalk.rgb(r, g, b)(text[i]); } readline.cursorTo(process.stdout, 0); readline.clearLine(process.stdout, 0); process.stdout.write(inlinePosition === "left" ? (inlineFollower ? inlineFollower + " " : "") + coloredText : coloredText + (inlineFollower ? " " + inlineFollower : "")); offset = (offset + 1) % text.length; }; return { start() { if (running) { return; } running = true; renderFrame(); intervalID = setInterval(renderFrame, interval); }, stop() { if (!running) { return; } clearInterval(intervalID); running = false; process.stdout.write("\n"); }, moving() { return running; }, setFollower(content) { inlineFollower = content; } }; } ; function outputGradientToString(text, colors) { const gradient = generateGradientColors(colors, text.length); let coloredText = ""; for (let i = 0; i < text.length; i++) { const [r, g, b] = gradient[i]; coloredText += chalk.rgb(r, g, b)(text[i]); } return coloredText; } ; function applyColor(text, options = {}) { const { backgroundColor = null, textColor = null } = options; let styled = text; if (backgroundColor) { styled = chalk.bgHex(backgroundColor)(styled); } if (textColor) { styled = chalk.hex(textColor)(styled); } return styled; } ; module.exports = { convertHexToRGB, hexToRGB, generateLerp, generateColorInterpolation, generateGradientColors, generateGradientText, outputGradient, outputGradientToString, movingGradientRenderer, applyColor, chalk };