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.
Files changed (2) hide show
  1. package/index.js +61 -27
  2. 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
- /* ---------------- Short Intro Petal Animation ---------------- */
90
+ /* ---------------- Intro Petal Animation (stable render) ---------------- */
101
91
 
102
- const PETALS = ['🌸', '❀', '✿', '·', '•']
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.25 + r3 * 0.85,
119
- drift: (r2 - 0.5) * 0.6,
120
- sway: 0.6 + r1 * 1.2,
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 / 220) * p.sway) * 1.5
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
- const overlay = grid.map((r) => r.join('')).join('\n')
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 termW = process.stdout.columns ?? 80
162
- const termH = process.stdout.rows ?? 24
178
+ const computeSizes = () => {
179
+ const termW = process.stdout.columns ?? 80
180
+ const termH = process.stdout.rows ?? 24
163
181
 
164
- const overlayW = clamp(termW - 2, 40, 120)
165
- const overlayH = clamp(Math.floor(termH / 2), 8, 18)
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
- const petalCount = clamp(Math.floor(overlayW / 4), 12, 40)
168
- const petals = initPetals(petalCount, overlayW, overlayH)
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
- logUpdate(`${overlay}\n\n${card}`)
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
- logUpdate.clear()
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yechancho",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "yechancho's terminal card",
5
5
  "main": "index.js",
6
6
  "type": "module",