yechancho 1.0.6 → 1.0.7
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 +61 -27
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,7 +6,6 @@ import chalk from 'chalk'
|
|
|
6
6
|
import gradient from 'gradient-string'
|
|
7
7
|
import figlet from 'figlet'
|
|
8
8
|
import terminalLink from 'terminal-link'
|
|
9
|
-
import logUpdate from 'log-update'
|
|
10
9
|
import ansiEscapes from 'ansi-escapes'
|
|
11
10
|
import cliCursor from 'cli-cursor'
|
|
12
11
|
|
|
@@ -26,7 +25,6 @@ const args = new Map(
|
|
|
26
25
|
|
|
27
26
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
|
|
28
27
|
|
|
29
|
-
// Sakura palette
|
|
30
28
|
const sakura = {
|
|
31
29
|
soft: chalk.hex('#FFD7E5'),
|
|
32
30
|
pink: chalk.hex('#FFB7C5'),
|
|
@@ -76,15 +74,7 @@ function makeBody() {
|
|
|
76
74
|
return left + right
|
|
77
75
|
}).join('\n')
|
|
78
76
|
|
|
79
|
-
return [
|
|
80
|
-
about,
|
|
81
|
-
'',
|
|
82
|
-
sectionTitle('links'),
|
|
83
|
-
linkLines,
|
|
84
|
-
'',
|
|
85
|
-
sectionTitle('now'),
|
|
86
|
-
NOW,
|
|
87
|
-
].join('\n')
|
|
77
|
+
return [about, '', sectionTitle('links'), linkLines, '', sectionTitle('now'), NOW].join('\n')
|
|
88
78
|
}
|
|
89
79
|
|
|
90
80
|
function makeCard() {
|
|
@@ -97,9 +87,10 @@ function makeCard() {
|
|
|
97
87
|
})
|
|
98
88
|
}
|
|
99
89
|
|
|
100
|
-
/* ----------------
|
|
90
|
+
/* ---------------- Intro Petal Animation (stable render) ---------------- */
|
|
101
91
|
|
|
102
|
-
|
|
92
|
+
// Use mostly single-width glyphs to avoid emoji-width jitter in overlay
|
|
93
|
+
const PETALS = ['✿', '❀', '·', '•', '*']
|
|
103
94
|
|
|
104
95
|
function rand(seed) {
|
|
105
96
|
const x = Math.sin(seed) * 10000
|
|
@@ -115,9 +106,9 @@ function initPetals(count, width, height) {
|
|
|
115
106
|
petals.push({
|
|
116
107
|
x: Math.floor(r1 * width),
|
|
117
108
|
y: Math.floor(r2 * height),
|
|
118
|
-
vy: 0.
|
|
119
|
-
drift: (r2 - 0.5) * 0.
|
|
120
|
-
sway: 0.
|
|
109
|
+
vy: 0.22 + r3 * 0.75,
|
|
110
|
+
drift: (r2 - 0.5) * 0.45,
|
|
111
|
+
sway: 0.7 + r1 * 1.2,
|
|
121
112
|
ch: PETALS[i % PETALS.length],
|
|
122
113
|
})
|
|
123
114
|
}
|
|
@@ -128,7 +119,7 @@ function renderOverlay(petals, t, width, height) {
|
|
|
128
119
|
const grid = Array.from({ length: height }, () => Array.from({ length: width }, () => ' '))
|
|
129
120
|
|
|
130
121
|
for (const p of petals) {
|
|
131
|
-
const sway = Math.sin((t /
|
|
122
|
+
const sway = Math.sin((t / 240) * p.sway) * 1.2
|
|
132
123
|
const x = Math.round(p.x + sway)
|
|
133
124
|
const y = Math.round(p.y)
|
|
134
125
|
|
|
@@ -137,8 +128,7 @@ function renderOverlay(petals, t, width, height) {
|
|
|
137
128
|
}
|
|
138
129
|
}
|
|
139
130
|
|
|
140
|
-
|
|
141
|
-
return sakura.soft(overlay)
|
|
131
|
+
return sakura.soft(grid.map((r) => r.join('')).join('\n'))
|
|
142
132
|
}
|
|
143
133
|
|
|
144
134
|
function stepPetals(petals, width, height) {
|
|
@@ -155,28 +145,68 @@ function stepPetals(petals, width, height) {
|
|
|
155
145
|
}
|
|
156
146
|
}
|
|
157
147
|
|
|
148
|
+
// Render without log-update: write to (0,0) and erase down. No scrolling.
|
|
149
|
+
function drawFrame(frame) {
|
|
150
|
+
process.stdout.write(ansiEscapes.cursorTo(0, 0) + ansiEscapes.eraseDown + frame)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function setupCleanup() {
|
|
154
|
+
const cleanup = () => {
|
|
155
|
+
try {
|
|
156
|
+
cliCursor.show()
|
|
157
|
+
process.stdout.write(ansiEscapes.cursorTo(0, 0) + ansiEscapes.eraseDown)
|
|
158
|
+
} catch {}
|
|
159
|
+
}
|
|
160
|
+
process.on('SIGINT', () => {
|
|
161
|
+
cleanup()
|
|
162
|
+
process.exit(0)
|
|
163
|
+
})
|
|
164
|
+
process.on('SIGTERM', () => {
|
|
165
|
+
cleanup()
|
|
166
|
+
process.exit(0)
|
|
167
|
+
})
|
|
168
|
+
process.on('exit', cleanup)
|
|
169
|
+
return cleanup
|
|
170
|
+
}
|
|
171
|
+
|
|
158
172
|
async function runIntroAnimation(card, durationMs, fps) {
|
|
159
173
|
const frameMs = Math.round(1000 / fps)
|
|
174
|
+
let petals = []
|
|
175
|
+
let overlayW = 60
|
|
176
|
+
let overlayH = 10
|
|
160
177
|
|
|
161
|
-
const
|
|
162
|
-
|
|
178
|
+
const computeSizes = () => {
|
|
179
|
+
const termW = process.stdout.columns ?? 80
|
|
180
|
+
const termH = process.stdout.rows ?? 24
|
|
163
181
|
|
|
164
|
-
|
|
165
|
-
|
|
182
|
+
// Important: keep overlay small enough so overlay + card fits without scrolling.
|
|
183
|
+
overlayW = clamp(termW - 2, 40, 110)
|
|
184
|
+
overlayH = clamp(Math.floor(termH * 0.35), 6, 14)
|
|
166
185
|
|
|
167
|
-
|
|
168
|
-
|
|
186
|
+
const petalCount = clamp(Math.floor(overlayW / 5), 10, 32)
|
|
187
|
+
petals = initPetals(petalCount, overlayW, overlayH)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
computeSizes()
|
|
191
|
+
|
|
192
|
+
// If user resizes terminal, recompute overlay
|
|
193
|
+
const onResize = () => computeSizes()
|
|
194
|
+
process.stdout.on('resize', onResize)
|
|
169
195
|
|
|
170
196
|
const start = Date.now()
|
|
171
197
|
let t = 0
|
|
172
198
|
|
|
173
199
|
while (Date.now() - start < durationMs) {
|
|
174
200
|
const overlay = renderOverlay(petals, t, overlayW, overlayH)
|
|
175
|
-
|
|
201
|
+
const frame = `${overlay}\n\n${card}`
|
|
202
|
+
drawFrame(frame)
|
|
203
|
+
|
|
176
204
|
stepPetals(petals, overlayW, overlayH)
|
|
177
205
|
t += frameMs
|
|
178
206
|
await sleep(frameMs)
|
|
179
207
|
}
|
|
208
|
+
|
|
209
|
+
process.stdout.off('resize', onResize)
|
|
180
210
|
}
|
|
181
211
|
|
|
182
212
|
async function main() {
|
|
@@ -191,12 +221,16 @@ async function main() {
|
|
|
191
221
|
const durationArg = args.get('--duration')
|
|
192
222
|
const durationMs = durationArg === true ? 2500 : parseInt(durationArg ?? '2500', 10) || 2500
|
|
193
223
|
|
|
224
|
+
setupCleanup()
|
|
194
225
|
cliCursor.hide()
|
|
226
|
+
|
|
227
|
+
// Clear once, then render frames from top-left
|
|
195
228
|
process.stdout.write(ansiEscapes.clearScreen)
|
|
196
229
|
|
|
197
230
|
await runIntroAnimation(card, durationMs, fps)
|
|
198
231
|
|
|
199
|
-
|
|
232
|
+
// Final static render (clean)
|
|
233
|
+
process.stdout.write(ansiEscapes.cursorTo(0, 0) + ansiEscapes.eraseDown)
|
|
200
234
|
cliCursor.show()
|
|
201
235
|
console.log(card)
|
|
202
236
|
}
|