@meebs/meeb 1.0.7 → 1.0.9

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 +113 -28
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -44,6 +44,20 @@ for (let i = 0; i < args.length; i++) {
44
44
  flags.diff = (args[i + 1] && !args[i + 1].startsWith('--')) ? args[++i] : true
45
45
  } else if (args[i] === '--animate') {
46
46
  flags.animate = (args[i + 1] && !args[i + 1].startsWith('--')) ? args[++i] : true
47
+ } else if (args[i] === '--pixelate' || args[i] === '--delay') {
48
+ const next = args[i + 1]?.toLowerCase()
49
+ if (next === 'entry' || next === 'exit') {
50
+ flags.delay = next
51
+ i++
52
+ } else {
53
+ flags.delay = true
54
+ }
55
+ // Check for hold duration (number in seconds)
56
+ const maybeNum = args[i + 1]
57
+ if (maybeNum && !isNaN(maybeNum) && Number(maybeNum) > 0) {
58
+ flags.hold = Number(maybeNum) * 1000
59
+ i++
60
+ }
47
61
  } else if (args[i].startsWith('--')) {
48
62
  flags[args[i].slice(2)] = true
49
63
  } else {
@@ -59,7 +73,7 @@ const flagWords = {
59
73
  theme: 'theme', animate: 'animate', motd: 'motd', calendar: 'calendar',
60
74
  commit: 'commit', ci: 'ci', gif: 'gif', png: 'png', svg: 'svg',
61
75
  stretch: 'stretch', squish: 'squish', stretchv: 'stretchv', squishv: 'squishv',
62
- white: 'white', label: 'label', delay: 'delay', slide: 'slide', fall: 'fall', shatter: 'shatter',
76
+ white: 'white', label: 'label', delay: 'delay', pixelate: 'delay', slide: 'slide', fall: 'fall', shatter: 'shatter',
63
77
  }
64
78
  const cleaned = []
65
79
  for (let i = 0; i < positional.length; i++) {
@@ -78,7 +92,21 @@ for (let i = 0; i < positional.length; i++) {
78
92
  words.push(positional[++i])
79
93
  }
80
94
  if (words.length) flags.label = words.join(' ')
81
- } else if (['tiny', 'hat', 'flip', 'fortune', 'motd', 'calendar', 'commit', 'ci', 'stretch', 'squish', 'stretchv', 'squishv', 'white', 'delay', 'slide', 'fall', 'shatter'].includes(key)) {
95
+ } else if (key === 'delay') {
96
+ const next = positional[i + 1]?.toLowerCase()
97
+ if (next === 'entry' || next === 'exit') {
98
+ flags.delay = next
99
+ i++
100
+ } else {
101
+ flags.delay = true
102
+ }
103
+ // Check for hold duration (number in seconds)
104
+ const maybeNum = positional[i + 1]
105
+ if (maybeNum && !isNaN(maybeNum) && Number(maybeNum) > 0) {
106
+ flags.hold = Number(maybeNum) * 1000
107
+ i++
108
+ }
109
+ } else if (['tiny', 'hat', 'flip', 'fortune', 'motd', 'calendar', 'commit', 'ci', 'stretch', 'squish', 'stretchv', 'squishv', 'white', 'slide', 'fall', 'shatter'].includes(key)) {
82
110
  flags[key] = true
83
111
  } else if (i + 1 < positional.length && !flagWords[positional[i + 1]?.toLowerCase()]) {
84
112
  flags[key] = positional[++i]
@@ -92,6 +120,27 @@ for (let i = 0; i < positional.length; i++) {
92
120
  positional.length = 0
93
121
  positional.push(...cleaned)
94
122
 
123
+ // If delay/pixelate is set, check for entry/exit and hold duration in leftover words
124
+ if (flags.delay) {
125
+ const entryExitIdx = positional.findIndex(w => w.toLowerCase() === 'entry' || w.toLowerCase() === 'exit')
126
+ if (entryExitIdx !== -1) {
127
+ flags.delay = positional[entryExitIdx].toLowerCase()
128
+ positional.splice(entryExitIdx, 1)
129
+ }
130
+ if (!flags.hold) {
131
+ const numIdx = positional.findIndex((w, i) => i > 0 && !isNaN(w) && Number(w) > 0)
132
+ if (numIdx !== -1) {
133
+ flags.hold = Number(positional[numIdx]) * 1000
134
+ positional.splice(numIdx, 1)
135
+ }
136
+ }
137
+ }
138
+
139
+ // If there are extra words after the animal name, treat them as --say
140
+ if (positional.length > 1 && !flags.say) {
141
+ flags.say = positional.slice(1).join(' ')
142
+ }
143
+
95
144
  const cmdWords = ['all', 'random', 'browse', 'list', 'count', 'help']
96
145
  const cmd = (cmdWords.includes(positional[0]) ? positional[0] : null)
97
146
  || Object.keys(flags).find(f => cmdWords.includes(f))
@@ -179,7 +228,7 @@ function drawCells(cells, artStartRow, offR, offC, termW, termH) {
179
228
  process.stdout.write(buf)
180
229
  }
181
230
 
182
- function delayReveal(art, label) {
231
+ function delayReveal(art, label, mode, holdMs) {
183
232
  if (!process.stdout.isTTY) {
184
233
  if (label) console.log(output(label))
185
234
  console.log(output(art))
@@ -187,38 +236,72 @@ function delayReveal(art, label) {
187
236
  }
188
237
 
189
238
  const { cells, height } = parseArtCells(art)
190
-
191
- // Fisher-Yates shuffle
192
- for (let i = cells.length - 1; i > 0; i--) {
193
- const j = Math.floor(Math.random() * (i + 1))
194
- ;[cells[i], cells[j]] = [cells[j], cells[i]]
195
- }
196
-
197
239
  const artStartRow = animSetup(label)
198
240
 
199
241
  const totalSteps = 20
200
242
  const batchSize = Math.max(1, Math.ceil(cells.length / totalSteps))
201
- let idx = 0
202
243
 
203
- function step() {
204
- const end = Math.min(idx + batchSize, cells.length)
205
- let buf = ''
206
- for (let i = idx; i < end; i++) {
207
- const c = cells[i]
208
- buf += `\x1b[${c.row + artStartRow};${c.col + 1}H${RESET}${c.style}${c.char}`
244
+ // Fisher-Yates shuffle
245
+ function shuffle() {
246
+ for (let i = cells.length - 1; i > 0; i--) {
247
+ const j = Math.floor(Math.random() * (i + 1))
248
+ ;[cells[i], cells[j]] = [cells[j], cells[i]]
209
249
  }
210
- buf += RESET
211
- process.stdout.write(buf)
212
- idx = end
213
- if (idx < cells.length) {
214
- setTimeout(step, 60)
215
- } else {
216
- animCleanup(height, artStartRow)
250
+ }
251
+
252
+ function runEntry(onDone) {
253
+ shuffle()
254
+ let idx = 0
255
+ function step() {
256
+ const end = Math.min(idx + batchSize, cells.length)
257
+ let buf = ''
258
+ for (let i = idx; i < end; i++) {
259
+ const c = cells[i]
260
+ buf += `\x1b[${c.row + artStartRow};${c.col + 1}H${RESET}${c.style}${c.char}`
261
+ }
262
+ buf += RESET
263
+ process.stdout.write(buf)
264
+ idx = end
265
+ if (idx < cells.length) setTimeout(step, 60)
266
+ else onDone()
217
267
  }
268
+ step()
218
269
  }
219
270
 
220
- process.on('SIGINT', () => { animCleanup(height, artStartRow); process.exit(0) })
221
- step()
271
+ function runExit(onDone) {
272
+ shuffle()
273
+ let idx = 0
274
+ function step() {
275
+ const end = Math.min(idx + batchSize, cells.length)
276
+ let buf = ''
277
+ for (let i = idx; i < end; i++) {
278
+ const c = cells[i]
279
+ buf += `\x1b[${c.row + artStartRow};${c.col + 1}H ${RESET}`
280
+ }
281
+ process.stdout.write(buf)
282
+ idx = end
283
+ if (idx < cells.length) setTimeout(step, 60)
284
+ else onDone()
285
+ }
286
+ step()
287
+ }
288
+
289
+ const done = () => animCleanup(height, artStartRow)
290
+
291
+ process.on('SIGINT', () => { done(); process.exit(0) })
292
+
293
+ const hold = holdMs || 800
294
+
295
+ if (mode === 'entry') {
296
+ runEntry(done)
297
+ } else if (mode === 'exit') {
298
+ // Draw full art first, then dissolve
299
+ drawCells(cells, artStartRow, 0, 0, null, null)
300
+ setTimeout(() => runExit(done), hold)
301
+ } else {
302
+ // Both: entry → hold → exit
303
+ runEntry(() => setTimeout(() => runExit(done), hold))
304
+ }
222
305
  }
223
306
 
224
307
  function slideReveal(art, label) {
@@ -399,7 +482,7 @@ function exportOrPrint(art, label) {
399
482
  if (exported.length > 0) {
400
483
  console.log(` saved to ${exported.join(', ')}`)
401
484
  } else if (flags.delay) {
402
- delayReveal(output(art), label ? output(label) : null)
485
+ delayReveal(output(art), label ? output(label) : null, typeof flags.delay === 'string' ? flags.delay : null, flags.hold || null)
403
486
  } else if (flags.slide) {
404
487
  slideReveal(output(art), label ? output(label) : null)
405
488
  } else if (flags.fall) {
@@ -515,7 +598,9 @@ if ((!cmd && Object.keys(flags).length === 0) || cmd === 'help') {
515
598
  console.log(' --squishv squish vertically (shorter)')
516
599
  console.log('')
517
600
  console.log(' Animations:')
518
- console.log(' --delay pixels materialize randomly')
601
+ console.log(' --delay/--pixelate pixels materialize then dissolve')
602
+ console.log(' entry/exit entry only or exit only')
603
+ console.log(' [seconds] hold duration (default 0.8)')
519
604
  console.log(' --slide slide in from the right')
520
605
  console.log(' --fall drop from the top with a bounce')
521
606
  console.log(' --shatter appear then explode with gravity')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meebs/meeb",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Cute ASCII art animals for your terminal",
5
5
  "bin": {
6
6
  "meeb": "./index.js"