ansimax 1.2.4 → 1.2.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/CHANGELOG.md CHANGED
@@ -3,6 +3,221 @@
3
3
  All notable changes to **ansimax** are documented in this file.
4
4
  This project follows [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [1.2.6] — ASCII module improvements
7
+
8
+ Patch release focused on ASCII module quality and feature additions. No
9
+ breaking changes — every 1.2.x program runs identically.
10
+
11
+ ### Added — 4 new built-in ramps
12
+
13
+ `ASCII_RAMPS` now includes 4 additional ramps for different aesthetic styles:
14
+
15
+ ```js
16
+ import { ASCII_RAMPS, ascii } from 'ansimax';
17
+
18
+ ASCII_RAMPS.binary // ' █' — pure 2-char ramp
19
+ ASCII_RAMPS.dots // ' ⠁⠃⠇⠧⠷⡷⣷⣿' — Unicode braille (sparse aesthetic)
20
+ ASCII_RAMPS.shades // ' ⠁⠃⠇⠧⠷⡷⣷⣿█' — combined shading
21
+ ASCII_RAMPS.ascii64 // 64-char printable ASCII — non-Unicode terminals
22
+
23
+ ascii.fromImage(pixels, { ramp: 'shades' });
24
+ ascii.fromImage(pixels, { ramp: 'binary', bgColor: true }); // photo-like effect
25
+ ```
26
+
27
+ ### Added — `bgColor` option in `fromImage`
28
+
29
+ Render the source pixel's color as the **background** instead of the foreground.
30
+ Pairs especially well with `ramp: 'binary'` for a photo-like effect where each
31
+ character cell becomes a colored block:
32
+
33
+ ```js
34
+ ascii.fromImage(pixels, {
35
+ width: 80,
36
+ bgColor: true, // colors go on background
37
+ ramp: 'binary', // chars are spaces/blocks
38
+ });
39
+ ```
40
+
41
+ Implies `color: true` — no need to set both.
42
+
43
+ ### Added — `brightness` and `contrast` in `fromImage`
44
+
45
+ Pre-adjust the image's tonal range without modifying the source pixels:
46
+
47
+ ```js
48
+ ascii.fromImage(pixels, {
49
+ width: 80,
50
+ brightness: 0.2, // [-1, 1] — positive = lighter, negative = darker
51
+ contrast: 0.3, // [-1, 1] — positive = boosted, negative = flattened
52
+ });
53
+ ```
54
+
55
+ Useful for tuning hard-to-read photos without re-processing the source.
56
+ Values are clamped to `[-1, 1]`. Default `0` (no change, identical to v1.2.5).
57
+
58
+ ### Added — `kerning` option in `figletText`
59
+
60
+ Control horizontal spacing between FIGfont glyphs:
61
+
62
+ ```js
63
+ ascii.figletText('HELLO', font, {
64
+ kerning: 1, // 1-space gap between each character glyph
65
+ });
66
+ ```
67
+
68
+ Default `0` (touching glyphs, matches previous behavior).
69
+
70
+ ### Added — Multi-line `figletText`
71
+
72
+ `figletText` now handles `\n` in input — each line renders as a separate
73
+ FIGfont block:
74
+
75
+ ```js
76
+ ascii.figletText('LINE 1\nLINE 2', font, {
77
+ lineSpacing: 1, // 1 blank line between rendered lines
78
+ });
79
+ ```
80
+
81
+ Single-line text takes a fast path (no behavior change for v1.2.5 callers).
82
+
83
+ ### Improved
84
+
85
+ - Better JSDoc on `ASCII_RAMPS` with `@example` showing every ramp
86
+ - Brightness/contrast use standard photo-editing formulas (linear stretch around midpoint)
87
+ - All 1958 + 25 new tests pass
88
+
89
+ ### Notes
90
+
91
+ - No new runtime dependencies — still zero
92
+ - Drop-in replacement for `1.2.5`
93
+
94
+ ---
95
+
96
+ ## [1.2.5] — Phase 3 closure: image-to-ASCII engine
97
+
98
+ Minor release closing the **ASCII engine roadmap (Phase 3)** with five
99
+ new capabilities. All additions are fully backwards-compatible — existing
100
+ code runs identically.
101
+
102
+ ### Added — `ascii.fromImage(pixels, opts)` — image-to-ASCII converter
103
+
104
+ Convert a `PixelGrid` (from `ansimax.images`) into ASCII art. Five
105
+ features in one call:
106
+
107
+ ```ts
108
+ import { ascii } from 'ansimax';
109
+
110
+ console.log(ascii.fromImage(pixels, {
111
+ width: 80,
112
+ ramp: 'detailed', // 'standard' | 'detailed' | 'blocks' | 'simple' | custom string
113
+ invert: false,
114
+ dither: 'floyd-steinberg', // 'none' | 'floyd-steinberg'
115
+ edgeDetect: 'sobel', // 'none' | 'sobel'
116
+ edgeThreshold: 40,
117
+ color: true, // preserve source colors
118
+ faceMode: false, // histogram stretch for portraits
119
+ }));
120
+ ```
121
+
122
+ **Aspect-ratio aware**: terminal cells are ~2× as tall as wide, so the
123
+ output height is auto-halved to maintain visual proportion (override
124
+ with `height`).
125
+
126
+ **Zero-dependency**: input is a `PixelGrid` (one Pixel per cell). Users
127
+ of `sharp`, `jimp`, or any decoder convert their output to `PixelGrid`
128
+ once, then call `ascii.fromImage()`.
129
+
130
+ ### Added — `ASCII_RAMPS` — pre-built character ramps
131
+
132
+ Four curated character ramps, ordered dark → light, exported as a
133
+ read-only object:
134
+
135
+ ```ts
136
+ ASCII_RAMPS.standard // ' .:-=+*#%@' — balanced 10-char (default)
137
+ ASCII_RAMPS.detailed // 70-char Paul Bourke — max detail
138
+ ASCII_RAMPS.blocks // ' ░▒▓█' — looks like a real photo
139
+ ASCII_RAMPS.simple // ' .+#' — minimal 4-char
140
+ ```
141
+
142
+ Or pass any custom string as the `ramp` option for full control.
143
+
144
+ ### Added — Sobel edge detection
145
+
146
+ Set `edgeDetect: 'sobel'` to render edges instead of luminance. Useful
147
+ for line-art effects or technical diagrams:
148
+
149
+ ```ts
150
+ console.log(ascii.fromImage(pixels, {
151
+ width: 100,
152
+ edgeDetect: 'sobel',
153
+ edgeThreshold: 50, // tune for noise/detail balance
154
+ ramp: 'blocks',
155
+ }));
156
+ ```
157
+
158
+ ### Added — Floyd-Steinberg dithering
159
+
160
+ Set `dither: 'floyd-steinberg'` for error-diffusion dithering. Produces
161
+ smoother tonal gradients in photos. Most useful with shorter ramps:
162
+
163
+ ```ts
164
+ ascii.fromImage(pixels, {
165
+ width: 80,
166
+ ramp: 'simple',
167
+ dither: 'floyd-steinberg',
168
+ });
169
+ ```
170
+
171
+ ### Added — Face mode
172
+
173
+ Set `faceMode: true` to apply histogram stretching ([10%, 90%] percentile
174
+ remap to [0, 255]). Boosts midtone contrast where facial features live,
175
+ producing better results on portraits:
176
+
177
+ ```ts
178
+ ascii.fromImage(portraitPixels, {
179
+ width: 60,
180
+ ramp: 'detailed',
181
+ faceMode: true,
182
+ });
183
+ ```
184
+
185
+ ### Added — Figlet (.flf) font support
186
+
187
+ Parse and render with community FIGfonts (250+ available at
188
+ [figlet.org](http://www.figlet.org/fontdb.cgi)):
189
+
190
+ ```ts
191
+ import { readFileSync } from 'node:fs';
192
+ import { parseFiglet, ascii } from 'ansimax';
193
+
194
+ const fontStr = readFileSync('./standard.flf', 'utf8');
195
+ const font = parseFiglet(fontStr);
196
+
197
+ console.log(ascii.figletText('Hello!', font, {
198
+ trim: true,
199
+ colorFn: (t) => t, // optional colorize
200
+ }));
201
+ ```
202
+
203
+ Returns a `FigletFont` object containing the parsed glyphs. Renders
204
+ ASCII 32-126; unknown chars fall back to space.
205
+
206
+ ### Added — Type exports
207
+
208
+ `AsciiRamp`, `FromImageOptions`, `FigletFont`, `FigletOptions` — all
209
+ exported from the main barrel.
210
+
211
+ ### Notes
212
+
213
+ - Phase 3 of the [roadmap](README.md#%EF%B8%8F-roadmap) is now **fully complete**.
214
+ - Image decoding (PNG/JPEG → PixelGrid) is intentionally **not** included;
215
+ users pair ansimax with `sharp`/`jimp`/`pngjs` to keep zero deps.
216
+ - 1914 + 30 new tests pass.
217
+ - No new runtime dependencies — still zero.
218
+
219
+ ---
220
+
6
221
  ## [1.2.4] — Gradient utilities + inspectability
7
222
 
8
223
  Patch release adding gradient inspection and manipulation utilities.
package/README.es.md CHANGED
@@ -7,7 +7,7 @@
7
7
  _Colores • Gradientes • Animaciones • ASCII Art • Pixel Art • Árboles • Componentes • Temas_
8
8
 
9
9
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square)](LICENSE)
10
- [![npm](https://img.shields.io/badge/npm-v1.2.4-cb3837.svg?style=flat-square)](https://www.npmjs.com/package/ansimax)
10
+ [![npm](https://img.shields.io/badge/npm-v1.2.6-cb3837.svg?style=flat-square)](https://www.npmjs.com/package/ansimax)
11
11
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6.svg?style=flat-square)](tsconfig.json)
12
12
  [![Coverage](https://img.shields.io/badge/coverage-98%25-brightgreen.svg?style=flat-square)](#testing)
13
13
  [![Tests](https://img.shields.io/badge/tests-1700%2B%20passing-brightgreen.svg?style=flat-square)](#testing)
@@ -49,7 +49,7 @@ Ansimax es una **librería de renderizado todo-en-uno** para construir interface
49
49
  npm install ansimax
50
50
  ```
51
51
 
52
- ```ts
52
+ ```js
53
53
  import { color, gradient, ascii, loader, sleep } from 'ansimax';
54
54
 
55
55
  console.log(ascii.banner('hola', {
@@ -122,7 +122,7 @@ yarn add ansimax
122
122
 
123
123
  ## ⚡ Ejemplo en 30 segundos
124
124
 
125
- ```ts
125
+ ```js
126
126
  import { color, gradient, loader, ascii, sleep } from 'ansimax';
127
127
 
128
128
  console.log(ascii.banner('deploy', {
@@ -140,7 +140,7 @@ console.log(color.green('✓') + ' Listo en ' + color.bold('1.4s'));
140
140
 
141
141
  ## 🚀 Inicio rápido
142
142
 
143
- ```ts
143
+ ```js
144
144
  import { configure, color, themes, gradient } from 'ansimax';
145
145
 
146
146
  // Configuración global
@@ -186,7 +186,7 @@ console.log(themes.primary('primary de cyberpunk'));
186
186
 
187
187
  <img src="media/colors.png" alt="Colores y gradientes" />
188
188
 
189
- ```ts
189
+ ```js
190
190
  import { color, gradient, rainbow } from 'ansimax';
191
191
 
192
192
  // Colores básicos
@@ -204,7 +204,7 @@ console.log(rainbow('preset rainbow integrado'));
204
204
 
205
205
  ### Gradientes animados (v1.2.0)
206
206
 
207
- ```ts
207
+ ```js
208
208
  import { animateGradient, sleep } from 'ansimax';
209
209
 
210
210
  // Animación de flujo de color — corre hasta llamar stop()
@@ -227,7 +227,7 @@ await animateGradient('¡Listo!', ['#50fa7b', '#bd93f9'], {
227
227
 
228
228
  <img src="media/easing_curves.png" alt="Colors and gradients" />
229
229
 
230
- ```ts
230
+ ```js
231
231
  import { gradient } from 'ansimax';
232
232
 
233
233
  const stops = ['#ff79c6', '#bd93f9', '#8be9fd'];
@@ -247,7 +247,7 @@ console.log(gradient('hola mundo', stops, { easing: (t) => t * t * t }));
247
247
 
248
248
  <img src="media/conic_gradients.png" alt="Colors and gradients" />
249
249
 
250
- ```ts
250
+ ```js
251
251
  import { gradientRect } from 'ansimax';
252
252
 
253
253
  // Barrido radial alrededor del centro — rueda arcoíris
@@ -262,7 +262,7 @@ console.log(gradientRect({
262
262
 
263
263
  ### Gradientes reusables (v1.2.3)
264
264
 
265
- ```ts
265
+ ```js
266
266
  import { createGradient, reverseGradient, ascii } from 'ansimax';
267
267
 
268
268
  // Pre-resuelve los stops de hex una vez — significativamente más rápido para uso repetido
@@ -294,7 +294,7 @@ for (let p = 0; p < 1; p += 0.05) {
294
294
 
295
295
  <img src="media/ascii_art.png" alt="ASCII art" />
296
296
 
297
- ```ts
297
+ ```js
298
298
  import { ascii, gradient } from 'ansimax';
299
299
 
300
300
  console.log(ascii.banner('HOLA', {
@@ -306,11 +306,80 @@ console.log(ascii.banner('HOLA', {
306
306
  console.log(ascii.box('¡Caja arcoiris!', { padding: 1, borderStyle: 'rounded' }));
307
307
  ```
308
308
 
309
+ ### Imagen → ASCII (v1.2.5)
310
+
311
+ ```js
312
+ import { ascii } from 'ansimax';
313
+ import sharp from 'sharp';
314
+
315
+ // Obtén píxeles RGB raw de cualquier librería de imágenes — ejemplo con `sharp`.
316
+ // Puedes usar jimp, pngjs, canvas, o cualquier decoder. Ansimax sigue sin deps.
317
+ const { data, info } = await sharp('./foto.png')
318
+ .raw()
319
+ .toBuffer({ resolveWithObject: true });
320
+
321
+ // Convierte el buffer RGB raw → PixelGrid (un array 2D de objetos { r, g, b })
322
+ const pixels = [];
323
+ for (let y = 0; y < info.height; y++) {
324
+ const row = [];
325
+ for (let x = 0; x < info.width; x++) {
326
+ const i = (y * info.width + x) * info.channels;
327
+ row.push({ r: data[i], g: data[i + 1], b: data[i + 2] });
328
+ }
329
+ pixels.push(row);
330
+ }
331
+
332
+ // Ahora usa ansimax — varias formas:
333
+
334
+ // Monocromo
335
+ console.log(ascii.fromImage(pixels, { width: 80 }));
336
+
337
+ // Color + dithering Floyd-Steinberg + ramp detallado
338
+ console.log(ascii.fromImage(pixels, {
339
+ width: 100,
340
+ color: true,
341
+ dither: 'floyd-steinberg',
342
+ ramp: 'detailed',
343
+ }));
344
+
345
+ // Modo detección de bordes (line art)
346
+ console.log(ascii.fromImage(pixels, {
347
+ width: 80,
348
+ edgeDetect: 'sobel',
349
+ edgeThreshold: 50,
350
+ ramp: 'blocks',
351
+ }));
352
+
353
+ // Modo rostro para retratos (mejora contraste de tonos medios)
354
+ console.log(ascii.fromImage(pixels, {
355
+ width: 60,
356
+ ramp: 'detailed',
357
+ faceMode: true,
358
+ }));
359
+ ```
360
+
361
+ ### Fuentes Figlet (v1.2.5)
362
+
363
+ ```js
364
+ import { readFileSync } from 'node:fs';
365
+ import { parseFiglet, ascii, gradient } from 'ansimax';
366
+
367
+ // Descarga fuentes desde http://www.figlet.org/fontdb.cgi
368
+ const font = parseFiglet(readFileSync('./standard.flf', 'utf8'));
369
+
370
+ console.log(ascii.figletText('¡Hola!', font));
371
+
372
+ // Con color
373
+ console.log(ascii.figletText('STYLE', font, {
374
+ colorFn: (t) => gradient(t, ['#ff79c6', '#bd93f9', '#8be9fd']),
375
+ }));
376
+ ```
377
+
309
378
  ### Árboles
310
379
 
311
380
  <img src="media/trees.png" alt="Árboles" />
312
381
 
313
- ```ts
382
+ ```js
314
383
  import { tree, color } from 'ansimax';
315
384
 
316
385
  const proyecto = tree({ label: 'mi-app', icon: '📦', color: color.bold });
@@ -329,7 +398,7 @@ console.log(proyecto.render({
329
398
 
330
399
  <img src="media/pixel_art.png" alt="Pixel art" />
331
400
 
332
- ```ts
401
+ ```js
333
402
  import { images, createCanvas, gradientRect, SPRITES } from 'ansimax';
334
403
 
335
404
  // Sprite integrado
@@ -355,7 +424,7 @@ c.print();
355
424
 
356
425
  <img src="media/components.png" alt="Componentes" />
357
426
 
358
- ```ts
427
+ ```js
359
428
  import { components, color } from 'ansimax';
360
429
 
361
430
  console.log(components.table([
@@ -365,7 +434,7 @@ console.log(components.table([
365
434
  ['loaders', color.green('● listo'), '100%'],
366
435
  ], { borderStyle: 'rounded' }));
367
436
 
368
- console.log(components.badge('VERSION', 'v1.2.4'));
437
+ console.log(components.badge('VERSION', 'v1.2.6'));
369
438
  console.log(components.badge('BUILD', 'passing'));
370
439
  ```
371
440
 
@@ -373,7 +442,7 @@ console.log(components.badge('BUILD', 'passing'));
373
442
 
374
443
  <img src="media/timeline.png" alt="Timeline" />
375
444
 
376
- ```ts
445
+ ```js
377
446
  import { components } from 'ansimax';
378
447
 
379
448
  console.log(components.timeline([
@@ -386,7 +455,7 @@ console.log(components.timeline([
386
455
 
387
456
  ### Loaders y Progreso
388
457
 
389
- ```ts
458
+ ```js
390
459
  import { loader, sleep } from 'ansimax';
391
460
 
392
461
  // Spinner con éxito/fallo
@@ -415,7 +484,7 @@ await loader.tasks([
415
484
 
416
485
  ### Animaciones
417
486
 
418
- ```ts
487
+ ```js
419
488
  import { animate, gradient, sleep } from 'ansimax';
420
489
 
421
490
  await animate.typewriter('Bienvenido al wizard de deployment...', {
@@ -437,7 +506,7 @@ await animate.parallel([
437
506
 
438
507
  <img src="media/themes.png" alt="Temas" />
439
508
 
440
- ```ts
509
+ ```js
441
510
  import { themes, createTheme } from 'ansimax';
442
511
 
443
512
  // Temas built-in
@@ -526,7 +595,7 @@ node examples/all-in-one.cjs
526
595
 
527
596
  La config global afecta cada módulo que la respeta (colores, temas, velocidad de animación, etc.):
528
597
 
529
- ```ts
598
+ ```js
530
599
  import { configure, getConfig, withConfig, onConfigKeyChange } from 'ansimax';
531
600
 
532
601
  configure({
@@ -579,7 +648,7 @@ El roadmap apunta intencionalmente — y busca superar — gaps que ni siquiera
579
648
  - [x] **Curvas de interpolación** — `linear` / `ease-in` / `ease-out` / `ease-in-out` / `cubic-bezier` / personalizado (v1.2.0)
580
649
  - [x] **Gradientes cónicos** — barrido radial con `style: 'conic'` (v1.2.0)
581
650
 
582
- ### 🟡 Fase 3 — Motor ASCII
651
+ ### Fase 3 — Motor ASCII
583
652
  - [x] Fuentes de bloque (`big`, `small`)
584
653
  - [x] Banner con gradiente + alineación + coloreado por carácter
585
654
  - [x] Dibujo de cajas (6 estilos de borde)
@@ -587,11 +656,12 @@ El roadmap apunta intencionalmente — y busca superar — gaps que ni siquiera
587
656
  - [x] Compositor de logos (gradiente + box wrapping)
588
657
  - [x] Registro de fuentes personalizadas (`registerFont`, `hasFont`, `listFonts`)
589
658
  - [x] API de stream (`ascii.stream()` con AbortSignal)
590
- - [ ] **Conversor Imagen → ASCII** (con detección de bordes, Sobel/Canny)
591
- - [ ] **Renderizado ASCII en color** (preservar colores de imagen)
592
- - [ ] **Dithering de imágenes** para mejor rango tonal (Floyd-Steinberg)
593
- - [ ] **ASCII optimizado para rostros** (modo de alto detalle para retratos)
594
- - [ ] **Soporte de fuentes figlet** (loader de archivos `.flf` 250+ fuentes de comunidad)
659
+ - [x] **Conversor Imagen → ASCII** — `ascii.fromImage()` con mapeo de luminancia (v1.2.5)
660
+ - [x] **Renderizado ASCII en color** preserva colores de imagen con `color: true` (v1.2.5)
661
+ - [x] **Dithering de imágenes** error diffusion Floyd-Steinberg (v1.2.5)
662
+ - [x] **ASCII optimizado para rostros** histogram stretching para retratos (v1.2.5)
663
+ - [x] **Soporte de fuentes figlet** parser + renderer `.flf` (`parseFiglet` + `ascii.figletText`) (v1.2.5)
664
+ - [x] **Detección de bordes** — operador Sobel integrado en `fromImage` (v1.2.5, bonus)
595
665
 
596
666
  ### ✅ Fase 4 — Primitivas TUI
597
667
  - [x] Tablas (filas irregulares, celdas multi-línea, conscientes de ANSI)
@@ -767,6 +837,74 @@ ansimax/
767
837
 
768
838
  ## 📝 Changelog
769
839
 
840
+ ### v1.2.6 — Mejoras del módulo ASCII
841
+
842
+ Release patch con mejoras al motor ASCII:
843
+
844
+ - 🎨 **4 ramps built-in nuevos** — `binary`, `dots`, `shades`, `ascii64`
845
+ - 🖼️ **Opción `bgColor`** en `fromImage` — colores van al background (excelente con `ramp: 'binary'` para efecto foto)
846
+ - 🔆 **`brightness` y `contrast`** pre-ajuste en `fromImage` — afina el rango tonal sin re-procesar
847
+ - 📏 **Opción `kerning`** en `figletText` — controla el espacio entre glyphs
848
+ - 📄 **`figletText` multi-línea** — input con `\n` renderiza múltiples bloques FIGfont con `lineSpacing` opcional
849
+
850
+ ```js
851
+ import { ascii, ASCII_RAMPS } from 'ansimax';
852
+
853
+ // Renderizado tipo-foto con bloques coloreados en background
854
+ console.log(ascii.fromImage(pixels, {
855
+ width: 80,
856
+ bgColor: true,
857
+ ramp: 'binary',
858
+ brightness: 0.1,
859
+ contrast: 0.2,
860
+ }));
861
+
862
+ // Figlet multi-línea con espaciado
863
+ console.log(ascii.figletText('TITULO\nSUBTITULO', font, {
864
+ kerning: 1,
865
+ lineSpacing: 1,
866
+ }));
867
+ ```
868
+
869
+ Drop-in replacement para `1.2.5`.
870
+
871
+ ### v1.2.5 — Fase 3 completa: motor de imagen-a-ASCII
872
+
873
+ Release minor que cierra el roadmap del motor ASCII con 5 features nuevas:
874
+
875
+ - 🖼️ **`ascii.fromImage(pixels, opts)`** — Conversor Imagen → ASCII (input: `PixelGrid`)
876
+ - 🎨 **Renderizado ASCII en color** — `color: true` preserva los colores fuente
877
+ - 📐 **Dithering Floyd-Steinberg** — `dither: 'floyd-steinberg'` para gradientes tonales más suaves
878
+ - 👤 **Modo optimizado para rostros** — `faceMode: true` mejora contraste de tonos medios en retratos
879
+ - 🔠 **Soporte Figlet (.flf)** — `parseFiglet()` + `ascii.figletText()` para 250+ fuentes de comunidad
880
+ - ⚡ **Bonus: detección de bordes Sobel** — `edgeDetect: 'sobel'` para efectos line-art
881
+
882
+ ```js
883
+ import { readFileSync } from 'node:fs';
884
+ import { ascii, parseFiglet } from 'ansimax';
885
+
886
+ // Construye un PixelGrid pequeño a mano (usa sharp/jimp/etc para imágenes
887
+ // reales — ver sección Imagen → ASCII arriba)
888
+ const pixels = [
889
+ [{ r: 255, g: 0, b: 0 }, { r: 0, g: 255, b: 0 }],
890
+ [{ r: 0, g: 0, b: 255 }, { r: 255, g: 255, b: 0 }],
891
+ ];
892
+
893
+ // Imagen a ASCII (input desde sharp/jimp/etc, sin dependencia de decoder)
894
+ console.log(ascii.fromImage(pixels, {
895
+ width: 80,
896
+ color: true,
897
+ dither: 'floyd-steinberg',
898
+ ramp: 'detailed',
899
+ }));
900
+
901
+ // Renderizado Figlet
902
+ const font = parseFiglet(readFileSync('./standard.flf', 'utf8'));
903
+ console.log(ascii.figletText('¡Hola!', font));
904
+ ```
905
+
906
+ Drop-in replacement para `1.2.4`.
907
+
770
908
  ### v1.2.4 — Utilidades de gradiente + inspectabilidad
771
909
 
772
910
  Release patch añadiendo metadata de inspección y un helper `reverseGradient()`:
@@ -775,7 +913,7 @@ Release patch añadiendo metadata de inspección y un helper `reverseGradient()`
775
913
  - 🔄 **Helper `reverseGradient()`** — invierte el orden de stops de un gradiente (funciona con arrays o `ReusableGradient`)
776
914
  - 🎯 **`presets` exportado con su nombre canónico** — junto al alias existente `colorPresets`
777
915
 
778
- ```ts
916
+ ```js
779
917
  import { createGradient, reverseGradient } from 'ansimax';
780
918
 
781
919
  const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
@@ -796,8 +934,8 @@ Release patch añadiendo una API orientada a performance:
796
934
  - 📖 Más JSDoc con ejemplos ejecutables
797
935
  - 🎯 Coincide con la firma `ColorFn` — funciona como `colorFn` en `ascii.banner`, themes, etc.
798
936
 
799
- ```ts
800
- import { createGradient } from 'ansimax';
937
+ ```js
938
+ import { createGradient, ascii } from 'ansimax';
801
939
 
802
940
  const fire = createGradient(['#ff5555', '#ffb86c', '#f1fa8c']);
803
941
  console.log(fire('¡Colores reusados!'));
@@ -826,7 +964,7 @@ Release minor que cierra el roadmap del motor de gradientes con tres features po
826
964
  - 📐 **Curvas de interpolación** — `linear` / `ease-in` / `ease-out` / `ease-in-out` / `cubic-bezier` / funciones personalizadas
827
965
  - ⭕ **Gradientes cónicos** — `gradientRect({ style: 'conic', startAngle })` para barridos radiales
828
966
 
829
- ```ts
967
+ ```js
830
968
  import { animateGradient } from 'ansimax';
831
969
 
832
970
  const ctrl = animateGradient('Cargando...', ['#ff79c6', '#bd93f9', '#8be9fd']);