yechancho 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +29 -119
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -9,12 +9,11 @@ import terminalLink from 'terminal-link'
|
|
|
9
9
|
import logUpdate from 'log-update'
|
|
10
10
|
import ansiEscapes from 'ansi-escapes'
|
|
11
11
|
import cliCursor from 'cli-cursor'
|
|
12
|
-
import readline from 'node:readline'
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* Flags:
|
|
16
15
|
* --static no animation, show card only
|
|
17
|
-
* --duration=2500
|
|
16
|
+
* --duration=2500 intro animation length in ms (default 2.5s)
|
|
18
17
|
* --fps=30 animation fps (default 30)
|
|
19
18
|
*/
|
|
20
19
|
|
|
@@ -46,8 +45,7 @@ const LINKS = [
|
|
|
46
45
|
{ label: 'GitHub', url: 'https://github.com/yechancho5', icon: '✿' },
|
|
47
46
|
]
|
|
48
47
|
|
|
49
|
-
const
|
|
50
|
-
const NOW = sakura.soft('building: ') + sakura.mint('cool products + shipping fast')
|
|
48
|
+
const NOW = sakura.soft('building ') + sakura.mint('and looking for an internship')
|
|
51
49
|
|
|
52
50
|
function clamp(n, a, b) {
|
|
53
51
|
return Math.max(a, Math.min(b, n))
|
|
@@ -61,36 +59,10 @@ function makeHeader() {
|
|
|
61
59
|
return gradient(['#FFB7C5', '#FFD7E5', '#C7A2FF'])(text)
|
|
62
60
|
}
|
|
63
61
|
|
|
64
|
-
function makeBranchArt() {
|
|
65
|
-
const cols = process.stdout.columns ?? 80
|
|
66
|
-
if (cols < 70) return ''
|
|
67
|
-
|
|
68
|
-
const art = [
|
|
69
|
-
" .::' '::..",
|
|
70
|
-
" .:' `:.",
|
|
71
|
-
" :: _.._ ::",
|
|
72
|
-
" `:..-' `-..:'",
|
|
73
|
-
" \\ 🌸 /",
|
|
74
|
-
" _.-'\\ /`-._",
|
|
75
|
-
" .' \\__/ `.",
|
|
76
|
-
" / ✿ .-..-. ❀ \\",
|
|
77
|
-
" \\ ( ) /",
|
|
78
|
-
" `-._ `-..-' _.-'",
|
|
79
|
-
" `--. .--'",
|
|
80
|
-
" \\/",
|
|
81
|
-
].join('\n')
|
|
82
|
-
|
|
83
|
-
return gradient(['#FFD7E5', '#FFB7C5', '#C7A2FF'])(art)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
62
|
function sectionTitle(t) {
|
|
87
63
|
return sakura.rose('✿ ') + sakura.white.bold(t)
|
|
88
64
|
}
|
|
89
65
|
|
|
90
|
-
function pill(text) {
|
|
91
|
-
return chalk.hex('#1A1A1A').bgHex('#FFD7E5')(` ${text} `)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
66
|
function makeBody() {
|
|
95
67
|
const about =
|
|
96
68
|
sakura.white("hi, i'm ") +
|
|
@@ -104,27 +76,19 @@ function makeBody() {
|
|
|
104
76
|
return left + right
|
|
105
77
|
}).join('\n')
|
|
106
78
|
|
|
107
|
-
const techLine = TECH.map((t) => pill(t)).join(' ')
|
|
108
|
-
|
|
109
79
|
return [
|
|
110
80
|
about,
|
|
111
81
|
'',
|
|
112
82
|
sectionTitle('links'),
|
|
113
83
|
linkLines,
|
|
114
84
|
'',
|
|
115
|
-
sectionTitle('stack'),
|
|
116
|
-
techLine,
|
|
117
|
-
'',
|
|
118
85
|
sectionTitle('now'),
|
|
119
86
|
NOW,
|
|
120
|
-
'',
|
|
121
|
-
sakura.dim('run: ') + sakura.pink('npx @yechancho/terminal-card') + ' ' + sakura.rose('🌸'),
|
|
122
87
|
].join('\n')
|
|
123
88
|
}
|
|
124
89
|
|
|
125
90
|
function makeCard() {
|
|
126
|
-
const
|
|
127
|
-
const content = `${makeHeader()}\n${branch ? branch + '\n' : ''}\n${makeBody()}`
|
|
91
|
+
const content = `${makeHeader()}\n\n${makeBody()}`
|
|
128
92
|
return boxen(content, {
|
|
129
93
|
padding: 1,
|
|
130
94
|
margin: 1,
|
|
@@ -133,10 +97,11 @@ function makeCard() {
|
|
|
133
97
|
})
|
|
134
98
|
}
|
|
135
99
|
|
|
100
|
+
/* ---------------- Short Intro Petal Animation ---------------- */
|
|
101
|
+
|
|
136
102
|
const PETALS = ['🌸', '❀', '✿', '·', '•']
|
|
137
103
|
|
|
138
104
|
function rand(seed) {
|
|
139
|
-
// tiny deterministic-ish PRNG
|
|
140
105
|
const x = Math.sin(seed) * 10000
|
|
141
106
|
return x - Math.floor(x)
|
|
142
107
|
}
|
|
@@ -150,9 +115,9 @@ function initPetals(count, width, height) {
|
|
|
150
115
|
petals.push({
|
|
151
116
|
x: Math.floor(r1 * width),
|
|
152
117
|
y: Math.floor(r2 * height),
|
|
153
|
-
vy: 0.25 + r3 * 0.85,
|
|
154
|
-
drift: (r2 - 0.5) * 0.6,
|
|
155
|
-
sway: 0.6 + r1 * 1.2,
|
|
118
|
+
vy: 0.25 + r3 * 0.85,
|
|
119
|
+
drift: (r2 - 0.5) * 0.6,
|
|
120
|
+
sway: 0.6 + r1 * 1.2,
|
|
156
121
|
ch: PETALS[i % PETALS.length],
|
|
157
122
|
})
|
|
158
123
|
}
|
|
@@ -181,7 +146,6 @@ function stepPetals(petals, width, height) {
|
|
|
181
146
|
p.y += p.vy
|
|
182
147
|
p.x += p.drift
|
|
183
148
|
|
|
184
|
-
// wrap around
|
|
185
149
|
if (p.y >= height) {
|
|
186
150
|
p.y = 0
|
|
187
151
|
p.x = Math.floor(Math.random() * width)
|
|
@@ -191,50 +155,28 @@ function stepPetals(petals, width, height) {
|
|
|
191
155
|
}
|
|
192
156
|
}
|
|
193
157
|
|
|
158
|
+
async function runIntroAnimation(card, durationMs, fps) {
|
|
159
|
+
const frameMs = Math.round(1000 / fps)
|
|
194
160
|
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
try {
|
|
198
|
-
cliCursor.show()
|
|
199
|
-
logUpdate.clear()
|
|
200
|
-
process.stdout.write(ansiEscapes.cursorShow)
|
|
201
|
-
} catch {}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
process.on('SIGINT', () => {
|
|
205
|
-
cleanup()
|
|
206
|
-
process.exit(0)
|
|
207
|
-
})
|
|
208
|
-
process.on('SIGTERM', () => {
|
|
209
|
-
cleanup()
|
|
210
|
-
process.exit(0)
|
|
211
|
-
})
|
|
212
|
-
process.on('exit', cleanup)
|
|
213
|
-
|
|
214
|
-
return cleanup
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
async function waitForKeyOrDuration(durationMs) {
|
|
218
|
-
return new Promise((resolve) => {
|
|
219
|
-
const done = () => resolve()
|
|
161
|
+
const termW = process.stdout.columns ?? 80
|
|
162
|
+
const termH = process.stdout.rows ?? 24
|
|
220
163
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
timer = setTimeout(done, durationMs)
|
|
224
|
-
}
|
|
164
|
+
const overlayW = clamp(termW - 2, 40, 120)
|
|
165
|
+
const overlayH = clamp(Math.floor(termH / 2), 8, 18)
|
|
225
166
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
process.stdin.resume()
|
|
167
|
+
const petalCount = clamp(Math.floor(overlayW / 4), 12, 40)
|
|
168
|
+
const petals = initPetals(petalCount, overlayW, overlayH)
|
|
229
169
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
process.stdin.off('keypress', onKey)
|
|
233
|
-
done()
|
|
234
|
-
}
|
|
170
|
+
const start = Date.now()
|
|
171
|
+
let t = 0
|
|
235
172
|
|
|
236
|
-
|
|
237
|
-
|
|
173
|
+
while (Date.now() - start < durationMs) {
|
|
174
|
+
const overlay = renderOverlay(petals, t, overlayW, overlayH)
|
|
175
|
+
logUpdate(`${overlay}\n\n${card}`)
|
|
176
|
+
stepPetals(petals, overlayW, overlayH)
|
|
177
|
+
t += frameMs
|
|
178
|
+
await sleep(frameMs)
|
|
179
|
+
}
|
|
238
180
|
}
|
|
239
181
|
|
|
240
182
|
async function main() {
|
|
@@ -246,48 +188,16 @@ async function main() {
|
|
|
246
188
|
}
|
|
247
189
|
|
|
248
190
|
const fps = clamp(parseInt(args.get('--fps') ?? '30', 10) || 30, 10, 60)
|
|
249
|
-
const frameMs = Math.round(1000 / fps)
|
|
250
|
-
|
|
251
|
-
const cleanup = setupExitCleanup()
|
|
252
|
-
|
|
253
|
-
cliCursor.hide()
|
|
254
|
-
process.stdout.write(ansiEscapes.clearScreen)
|
|
255
|
-
|
|
256
|
-
// Overlay size adapts to terminal
|
|
257
|
-
const termW = process.stdout.columns ?? 80
|
|
258
|
-
const termH = process.stdout.rows ?? 24
|
|
259
|
-
|
|
260
|
-
const overlayW = clamp(termW - 2, 40, 120)
|
|
261
|
-
const overlayH = clamp(Math.floor(termH / 2), 8, 18)
|
|
262
|
-
|
|
263
|
-
// More petals on bigger screens
|
|
264
|
-
const petalCount = clamp(Math.floor(overlayW / 4), 12, 40)
|
|
265
|
-
const petals = initPetals(petalCount, overlayW, overlayH)
|
|
266
|
-
|
|
267
191
|
const durationArg = args.get('--duration')
|
|
268
192
|
const durationMs = durationArg === true ? 2500 : parseInt(durationArg ?? '2500', 10) || 2500
|
|
269
193
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
let t = 0
|
|
274
|
-
while (running) {
|
|
275
|
-
const overlay = renderOverlay(petals, t, overlayW, overlayH)
|
|
276
|
-
const sparkleLine =
|
|
277
|
-
sakura.rose('✿') +
|
|
278
|
-
sakura.dim(' '.repeat(Math.max(0, overlayW - 4))) +
|
|
279
|
-
sakura.rose('✿')
|
|
280
|
-
|
|
281
|
-
logUpdate(`${overlay}\n${sparkleLine}\n${card}`)
|
|
282
|
-
stepPetals(petals, overlayW, overlayH)
|
|
283
|
-
t += frameMs
|
|
284
|
-
await sleep(frameMs)
|
|
285
|
-
}
|
|
194
|
+
cliCursor.hide()
|
|
195
|
+
process.stdout.write(ansiEscapes.clearScreen)
|
|
286
196
|
|
|
287
|
-
await
|
|
197
|
+
await runIntroAnimation(card, durationMs, fps)
|
|
288
198
|
|
|
289
199
|
logUpdate.clear()
|
|
290
|
-
|
|
200
|
+
cliCursor.show()
|
|
291
201
|
console.log(card)
|
|
292
202
|
}
|
|
293
203
|
|