Last active
December 14, 2024 15:48
-
-
Save shiftyp/c2a298ce712d8d9c97b3b7d8c9ff20d5 to your computer and use it in GitHub Desktop.
holidayconifer.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Console } from "node:console"; | |
const BALL = '⏺' | |
const COLOR = { | |
'blue': '\\033[94m', | |
'yellow': '\\033[93m', | |
'cyan': '\\033[96m', | |
'green': '\\033[92m', | |
'magenta': '\\033[95m', | |
'white': '\\033[97m', | |
'red': '\\033[91m' | |
} | |
const STAR = '★' | |
const getRandomIndexes = (string: string, count: number) => { | |
const indexes: Record<number, true> = {}; | |
let length = 0 | |
while (length < count) { | |
const randomIndex = Math.floor(Math.random() * string.length); | |
if (!indexes[randomIndex]) { | |
indexes[randomIndex] = true; | |
} | |
} | |
return Object.keys(indexes); | |
} | |
const randomChangeChar = (string, count) => { | |
const indexes = getRandomIndexes(string, count) | |
const arr = string.split('') | |
for (const idx in indexes) { | |
if (arr[idx] === '_') { | |
arr[idx] = BALL | |
} | |
} | |
return arr.join('') | |
} | |
const tree = (height: number = 13, screenWidth: number = 80) => { | |
const star = [STAR, STAR, STAR, STAR] | |
if (height % 2 !== 0) { | |
height += 1 | |
} | |
const body = ['/_\\', '/_\_\\'] | |
const trunk = '[___]' | |
const begin = '/' | |
const end = '\\' | |
const pattern = '_/' | |
let j = 5 | |
for (let i = 7; i < height + 1; i += 2) { | |
let middle = pattern | |
for (let k = 0; k < i - j; k++) { | |
middle += pattern | |
} | |
let line = [begin, middle.slice(-1), end].join('') | |
body.push(line) | |
middle = middle.replace('/', '\\') | |
line = [begin, middle.slice(-1), end].join('') | |
body.push(line) | |
j += 1 | |
} | |
const ret: string[] = [] | |
for (const line in [...star, ...body, trunk]) { | |
// center the tree based on screen width | |
const spaces = ' '.repeat((screenWidth - line.length) / 2) | |
ret.push(spaces + line) | |
} | |
return ret | |
} | |
const balls = (tree: string[]) => { | |
for (let idx = 0; idx < tree.length - 3; idx++) { | |
tree[idx] = randomChangeChar(tree[idx], tree[idx].length) | |
} | |
return tree | |
} | |
const coloredStarsBalls = (tree: string[]) => { | |
for (const idx in tree) { | |
const string = tree[idx].split('') | |
for (const pos in string) { | |
if (string[pos] === STAR) { | |
string[pos] = [COLOR['yellow'], STAR, '\\033[0m'].join('') | |
} | |
else if (string[pos] === BALL) { | |
string[pos] = [Object.values(COLOR)[Math.random() * Object.values(COLOR).length], BALL, '\\033[0m'].join('') | |
} | |
} | |
tree[idx] = string.join('') | |
} | |
return tree | |
} | |
const cli = () => { | |
const {columns, rows} = Deno.consoleSize(Deno.stdout.rid) | |
const height = rows - 2 | |
const console = new Console(Deno.stdout) | |
setInterval(() => { | |
console.clear() | |
console.log(coloredStarsBalls(balls(tree(height, columns))).join('\n')) | |
}, 1000) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment