asciify-engine 1.0.13 → 1.0.14

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/dist/index.d.cts CHANGED
@@ -251,6 +251,63 @@ declare function renderWaveBackground(ctx: CanvasRenderingContext2D, width: numb
251
251
  x: number;
252
252
  y: number;
253
253
  }, options?: WaveBackgroundOptions): void;
254
+ /**
255
+ * Renders a digital-rain ASCII background — independent columns of falling
256
+ * characters each with a glowing head and fading tail. Deterministic and
257
+ * stateless: derived entirely from elapsed time.
258
+ *
259
+ * @example
260
+ * ```ts
261
+ * asciiBackground('#hero', { type: 'rain' });
262
+ * ```
263
+ */
264
+ interface RainBackgroundOptions {
265
+ fontSize?: number;
266
+ /** Characters drawn in columns (one picked randomly per cell per frame). */
267
+ chars?: string;
268
+ /** Head / accent colour (default: '#d4ff00'). */
269
+ accentColor?: string;
270
+ /** Custom character colour (any CSS colour string). */
271
+ color?: string;
272
+ /** Global speed multiplier (default: 1). */
273
+ speed?: number;
274
+ /** Fraction of columns active at once 0-1 (default: 0.55). */
275
+ density?: number;
276
+ /** Number of cells in the fading tail (default: 14). */
277
+ tailLength?: number;
278
+ /** Light mode: dark chars on light background (default: false). */
279
+ lightMode?: boolean;
280
+ }
281
+ declare function renderRainBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: RainBackgroundOptions): void;
282
+ /**
283
+ * Renders a 3-D star-warp / hyperspace ASCII background — ASCII chars fly
284
+ * outward from a vanishing point that gently follows the mouse cursor.
285
+ * Stars scale up and brighten as they approach the screen edge.
286
+ *
287
+ * @example
288
+ * ```ts
289
+ * asciiBackground('#hero', { type: 'stars' });
290
+ * ```
291
+ */
292
+ interface StarsBackgroundOptions {
293
+ fontSize?: number;
294
+ /** Characters used as stars (sparse = more authentic). */
295
+ chars?: string;
296
+ /** Accent/trail colour for fast near-edge stars (default: '#d4ff00'). */
297
+ accentColor?: string;
298
+ /** Custom base colour (any CSS colour string). */
299
+ color?: string;
300
+ /** Global speed multiplier (default: 1). */
301
+ speed?: number;
302
+ /** Number of star particles (default: 180). */
303
+ count?: number;
304
+ /** Light mode (default: false). */
305
+ lightMode?: boolean;
306
+ }
307
+ declare function renderStarsBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
308
+ x: number;
309
+ y: number;
310
+ }, options?: StarsBackgroundOptions): void;
254
311
  /**
255
312
  * Drop-in helper that mounts an interactive ASCII wave background onto any
256
313
  * element. Injects a canvas, wires DPR resize, mouse tracking, and the RAF
@@ -273,7 +330,14 @@ declare function renderWaveBackground(ctx: CanvasRenderingContext2D, width: numb
273
330
  * useEffect(() => asciiBackground(ref.current).destroy, []);
274
331
  * ```
275
332
  */
276
- interface AsciiBackgroundOptions extends WaveBackgroundOptions {
333
+ interface AsciiBackgroundOptions extends WaveBackgroundOptions, RainBackgroundOptions, StarsBackgroundOptions {
334
+ /**
335
+ * Which background to render (default: 'wave').
336
+ * - 'wave' — interactive ASCII field with vortex, sparkles, breathe
337
+ * - 'rain' — digital column rain (Matrix-style falling characters)
338
+ * - 'stars' — 3D star-warp / hyperspace (chars fly toward the viewer)
339
+ */
340
+ type?: 'wave' | 'rain' | 'stars';
277
341
  /** CSS opacity applied to the canvas element (default: 0.2) */
278
342
  opacity?: number;
279
343
  /** Extra CSS class names added to the injected canvas */
@@ -283,14 +347,13 @@ interface AsciiBackgroundOptions extends WaveBackgroundOptions {
283
347
  /**
284
348
  * Colour scheme handling (default: 'auto').
285
349
  * - 'auto' — follows the system prefers-color-scheme and updates live
286
- * - 'dark' — always render dark-on-dark (bright chars on dark bg)
350
+ * - 'dark' — always render bright chars on dark background
287
351
  * - 'light' — always render dark chars on light background
288
352
  */
289
353
  colorScheme?: 'auto' | 'light' | 'dark';
290
354
  /**
291
355
  * Custom character colour. Accepts any CSS colour string: hex, rgb(), hsl().
292
- * When set, overrides the default white/black colour for the ASCII chars.
293
- * The accent colour remains separate — use `accentColor` to change it.
356
+ * Overrides the default white/black for the ASCII chars.
294
357
  * @example '#6b8700'
295
358
  */
296
359
  color?: string;
@@ -320,4 +383,4 @@ interface WebGLRenderer {
320
383
  */
321
384
  declare function tryCreateWebGLRenderer(canvas: HTMLCanvasElement): WebGLRenderer | null;
322
385
 
323
- export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciifySimpleOptions, CHARSETS, type CharsetKey, type ColorMode, DEFAULT_OPTIONS, HOVER_PRESETS, type HoverEffect, type HoverPreset, type MountWaveOptions, type RenderMode, type SourceType, type WaveBackgroundOptions, type WebGLRenderer, asciiBackground, asciify, asciifyGif, asciifyVideo, generateAnimatedEmbedCode, generateEmbedCode, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, renderFrameToCanvas, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
386
+ export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciifySimpleOptions, CHARSETS, type CharsetKey, type ColorMode, DEFAULT_OPTIONS, HOVER_PRESETS, type HoverEffect, type HoverPreset, type MountWaveOptions, type RainBackgroundOptions, type RenderMode, type SourceType, type StarsBackgroundOptions, type WaveBackgroundOptions, type WebGLRenderer, asciiBackground, asciify, asciifyGif, asciifyVideo, generateAnimatedEmbedCode, generateEmbedCode, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, renderFrameToCanvas, renderRainBackground, renderStarsBackground, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
package/dist/index.d.ts CHANGED
@@ -251,6 +251,63 @@ declare function renderWaveBackground(ctx: CanvasRenderingContext2D, width: numb
251
251
  x: number;
252
252
  y: number;
253
253
  }, options?: WaveBackgroundOptions): void;
254
+ /**
255
+ * Renders a digital-rain ASCII background — independent columns of falling
256
+ * characters each with a glowing head and fading tail. Deterministic and
257
+ * stateless: derived entirely from elapsed time.
258
+ *
259
+ * @example
260
+ * ```ts
261
+ * asciiBackground('#hero', { type: 'rain' });
262
+ * ```
263
+ */
264
+ interface RainBackgroundOptions {
265
+ fontSize?: number;
266
+ /** Characters drawn in columns (one picked randomly per cell per frame). */
267
+ chars?: string;
268
+ /** Head / accent colour (default: '#d4ff00'). */
269
+ accentColor?: string;
270
+ /** Custom character colour (any CSS colour string). */
271
+ color?: string;
272
+ /** Global speed multiplier (default: 1). */
273
+ speed?: number;
274
+ /** Fraction of columns active at once 0-1 (default: 0.55). */
275
+ density?: number;
276
+ /** Number of cells in the fading tail (default: 14). */
277
+ tailLength?: number;
278
+ /** Light mode: dark chars on light background (default: false). */
279
+ lightMode?: boolean;
280
+ }
281
+ declare function renderRainBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, options?: RainBackgroundOptions): void;
282
+ /**
283
+ * Renders a 3-D star-warp / hyperspace ASCII background — ASCII chars fly
284
+ * outward from a vanishing point that gently follows the mouse cursor.
285
+ * Stars scale up and brighten as they approach the screen edge.
286
+ *
287
+ * @example
288
+ * ```ts
289
+ * asciiBackground('#hero', { type: 'stars' });
290
+ * ```
291
+ */
292
+ interface StarsBackgroundOptions {
293
+ fontSize?: number;
294
+ /** Characters used as stars (sparse = more authentic). */
295
+ chars?: string;
296
+ /** Accent/trail colour for fast near-edge stars (default: '#d4ff00'). */
297
+ accentColor?: string;
298
+ /** Custom base colour (any CSS colour string). */
299
+ color?: string;
300
+ /** Global speed multiplier (default: 1). */
301
+ speed?: number;
302
+ /** Number of star particles (default: 180). */
303
+ count?: number;
304
+ /** Light mode (default: false). */
305
+ lightMode?: boolean;
306
+ }
307
+ declare function renderStarsBackground(ctx: CanvasRenderingContext2D, width: number, height: number, time: number, mousePos?: {
308
+ x: number;
309
+ y: number;
310
+ }, options?: StarsBackgroundOptions): void;
254
311
  /**
255
312
  * Drop-in helper that mounts an interactive ASCII wave background onto any
256
313
  * element. Injects a canvas, wires DPR resize, mouse tracking, and the RAF
@@ -273,7 +330,14 @@ declare function renderWaveBackground(ctx: CanvasRenderingContext2D, width: numb
273
330
  * useEffect(() => asciiBackground(ref.current).destroy, []);
274
331
  * ```
275
332
  */
276
- interface AsciiBackgroundOptions extends WaveBackgroundOptions {
333
+ interface AsciiBackgroundOptions extends WaveBackgroundOptions, RainBackgroundOptions, StarsBackgroundOptions {
334
+ /**
335
+ * Which background to render (default: 'wave').
336
+ * - 'wave' — interactive ASCII field with vortex, sparkles, breathe
337
+ * - 'rain' — digital column rain (Matrix-style falling characters)
338
+ * - 'stars' — 3D star-warp / hyperspace (chars fly toward the viewer)
339
+ */
340
+ type?: 'wave' | 'rain' | 'stars';
277
341
  /** CSS opacity applied to the canvas element (default: 0.2) */
278
342
  opacity?: number;
279
343
  /** Extra CSS class names added to the injected canvas */
@@ -283,14 +347,13 @@ interface AsciiBackgroundOptions extends WaveBackgroundOptions {
283
347
  /**
284
348
  * Colour scheme handling (default: 'auto').
285
349
  * - 'auto' — follows the system prefers-color-scheme and updates live
286
- * - 'dark' — always render dark-on-dark (bright chars on dark bg)
350
+ * - 'dark' — always render bright chars on dark background
287
351
  * - 'light' — always render dark chars on light background
288
352
  */
289
353
  colorScheme?: 'auto' | 'light' | 'dark';
290
354
  /**
291
355
  * Custom character colour. Accepts any CSS colour string: hex, rgb(), hsl().
292
- * When set, overrides the default white/black colour for the ASCII chars.
293
- * The accent colour remains separate — use `accentColor` to change it.
356
+ * Overrides the default white/black for the ASCII chars.
294
357
  * @example '#6b8700'
295
358
  */
296
359
  color?: string;
@@ -320,4 +383,4 @@ interface WebGLRenderer {
320
383
  */
321
384
  declare function tryCreateWebGLRenderer(canvas: HTMLCanvasElement): WebGLRenderer | null;
322
385
 
323
- export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciifySimpleOptions, CHARSETS, type CharsetKey, type ColorMode, DEFAULT_OPTIONS, HOVER_PRESETS, type HoverEffect, type HoverPreset, type MountWaveOptions, type RenderMode, type SourceType, type WaveBackgroundOptions, type WebGLRenderer, asciiBackground, asciify, asciifyGif, asciifyVideo, generateAnimatedEmbedCode, generateEmbedCode, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, renderFrameToCanvas, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
386
+ export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciifySimpleOptions, CHARSETS, type CharsetKey, type ColorMode, DEFAULT_OPTIONS, HOVER_PRESETS, type HoverEffect, type HoverPreset, type MountWaveOptions, type RainBackgroundOptions, type RenderMode, type SourceType, type StarsBackgroundOptions, type WaveBackgroundOptions, type WebGLRenderer, asciiBackground, asciify, asciifyGif, asciifyVideo, generateAnimatedEmbedCode, generateEmbedCode, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, renderFrameToCanvas, renderRainBackground, renderStarsBackground, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
package/dist/index.js CHANGED
@@ -830,7 +830,7 @@ async function asciifyVideo(source, canvas, { fontSize = 10, style = "classic",
830
830
  cancelAnimationFrame(animId);
831
831
  };
832
832
  }
833
- var EMBED_CDN_VERSION = "1.0.12";
833
+ var EMBED_CDN_VERSION = "1.0.14";
834
834
  function buildEmbedOpts(options, rows, cols, width, height, fps, animated) {
835
835
  const o = {
836
836
  r: rows,
@@ -997,6 +997,127 @@ function renderWaveBackground(ctx, width, height, time, mousePos = { x: 0.5, y:
997
997
  }
998
998
  }
999
999
  }
1000
+ function renderRainBackground(ctx, width, height, time, options = {}) {
1001
+ const {
1002
+ fontSize = 13,
1003
+ chars = "0123456789ABCDEF@#$&*+=/<>",
1004
+ accentColor = "#d4ff00",
1005
+ color,
1006
+ speed = 1,
1007
+ density = 0.55,
1008
+ tailLength = 14,
1009
+ lightMode = false
1010
+ } = options;
1011
+ const charW = fontSize * 0.62;
1012
+ const lineH = fontSize * 1.4;
1013
+ const cols = Math.ceil(width / charW);
1014
+ const rows = Math.ceil(height / lineH);
1015
+ ctx.clearRect(0, 0, width, height);
1016
+ ctx.font = `${fontSize}px monospace`;
1017
+ ctx.textBaseline = "top";
1018
+ let br = 255, bg = 255, bb = 255;
1019
+ if (lightMode) {
1020
+ br = 0;
1021
+ bg = 0;
1022
+ bb = 0;
1023
+ }
1024
+ if (color) {
1025
+ const p = _parseColor(color);
1026
+ if (p) {
1027
+ br = p.r;
1028
+ bg = p.g;
1029
+ bb = p.b;
1030
+ }
1031
+ }
1032
+ let acR = 212, acG = 255, acB = 0;
1033
+ const ap = _parseColor(accentColor);
1034
+ if (ap) {
1035
+ acR = ap.r;
1036
+ acG = ap.g;
1037
+ acB = ap.b;
1038
+ }
1039
+ const period = rows + tailLength;
1040
+ for (let c = 0; c < cols; c++) {
1041
+ if (_hash2(c * 17, 3) > density) continue;
1042
+ const colSpeed = (0.5 + _hash2(c * 31, 7) * 1.5) * speed;
1043
+ const phase = _hash2(c * 13, 11) * period;
1044
+ const headRow = Math.floor((time * colSpeed * 7 + phase) % period);
1045
+ const x = c * charW;
1046
+ for (let k = 0; k <= tailLength; k++) {
1047
+ const row = headRow - (tailLength - k);
1048
+ if (row < 0 || row >= rows) continue;
1049
+ const y = row * lineH;
1050
+ const charSeed = _hash2(c * 53 + Math.floor(time * 5 + k), row * 7);
1051
+ const ch = chars[Math.floor(charSeed * chars.length)];
1052
+ const t = k / tailLength;
1053
+ if (k === tailLength) {
1054
+ ctx.fillStyle = `rgba(${acR},${acG},${acB},${lightMode ? 0.7 : 0.85})`;
1055
+ } else {
1056
+ const alpha = lightMode ? t * 0.22 : t * 0.15;
1057
+ ctx.fillStyle = `rgba(${br},${bg},${bb},${alpha})`;
1058
+ }
1059
+ ctx.fillText(ch, x, y);
1060
+ }
1061
+ }
1062
+ }
1063
+ function renderStarsBackground(ctx, width, height, time, mousePos = { x: 0.5, y: 0.5 }, options = {}) {
1064
+ const {
1065
+ fontSize = 14,
1066
+ chars = " . \xB7 * + \xB0 \u2605",
1067
+ accentColor = "#d4ff00",
1068
+ color,
1069
+ speed = 1,
1070
+ count = 180,
1071
+ lightMode = false
1072
+ } = options;
1073
+ ctx.clearRect(0, 0, width, height);
1074
+ ctx.textBaseline = "middle";
1075
+ ctx.textAlign = "center";
1076
+ const cx = width * (0.2 + mousePos.x * 0.6);
1077
+ const cy = height * (0.2 + mousePos.y * 0.6);
1078
+ const maxR = Math.sqrt(width * width + height * height) * 0.65;
1079
+ let br = 255, bg = 255, bb = 255;
1080
+ if (lightMode) {
1081
+ br = 0;
1082
+ bg = 0;
1083
+ bb = 0;
1084
+ }
1085
+ if (color) {
1086
+ const p = _parseColor(color);
1087
+ if (p) {
1088
+ br = p.r;
1089
+ bg = p.g;
1090
+ bb = p.b;
1091
+ }
1092
+ }
1093
+ let acR = 212, acG = 255, acB = 0;
1094
+ const ap = _parseColor(accentColor);
1095
+ if (ap) {
1096
+ acR = ap.r;
1097
+ acG = ap.g;
1098
+ acB = ap.b;
1099
+ }
1100
+ const charArr = chars.replace(/ /g, "").split("");
1101
+ if (charArr.length === 0) return;
1102
+ for (let i = 0; i < count; i++) {
1103
+ const angle = _hash2(i * 17, 3) * Math.PI * 2;
1104
+ const baseSpd = 0.15 + _hash2(i * 31, 7) * 0.85;
1105
+ const phase = _hash2(i * 13, 11);
1106
+ const r = (time * baseSpd * speed * 0.22 + phase) % 1;
1107
+ const x = cx + Math.cos(angle) * r * maxR;
1108
+ const y = cy + Math.sin(angle) * r * maxR;
1109
+ if (x < -20 || x > width + 20 || y < -20 || y > height + 20) continue;
1110
+ const sz = Math.max(6, fontSize * (0.4 + r * 0.9));
1111
+ ctx.font = `${sz}px monospace`;
1112
+ const charIdx = Math.min(charArr.length - 1, Math.floor(r * charArr.length));
1113
+ const ch = charArr[charIdx];
1114
+ const isAccent = r > 0.72;
1115
+ const alpha = lightMode ? r * 0.28 : r * 0.2;
1116
+ ctx.fillStyle = isAccent ? `rgba(${acR},${acG},${acB},${Math.min(lightMode ? 0.45 : 0.32, alpha * 2.2)})` : `rgba(${br},${bg},${bb},${alpha})`;
1117
+ ctx.fillText(ch, x, y);
1118
+ }
1119
+ ctx.textAlign = "left";
1120
+ }
1000
1121
  function _parseColor(c) {
1001
1122
  const hex = c.match(/^#([0-9a-f]{3,8})$/i)?.[1];
1002
1123
  if (hex) {
@@ -1009,6 +1130,7 @@ function _parseColor(c) {
1009
1130
  }
1010
1131
  function asciiBackground(target, options = {}) {
1011
1132
  const {
1133
+ type = "wave",
1012
1134
  opacity = 0.2,
1013
1135
  className,
1014
1136
  zIndex = 0,
@@ -1048,16 +1170,31 @@ function asciiBackground(target, options = {}) {
1048
1170
  if (colorScheme === "dark") return false;
1049
1171
  return mq.matches;
1050
1172
  };
1051
- let parsedColor = null;
1052
- if (color) parsedColor = _parseColor(color);
1053
- const buildOpts = () => ({
1173
+ const parsedColor = color ? _parseColor(color) : null;
1174
+ const buildWaveOpts = () => ({
1054
1175
  ...renderOpts,
1055
1176
  lightMode: renderOpts.lightMode !== void 0 ? renderOpts.lightMode : isLight(),
1056
1177
  baseColor: parsedColor ? `rgba(${parsedColor.r},${parsedColor.g},${parsedColor.b},{a})` : renderOpts.baseColor
1057
1178
  });
1058
- const optsRef = { current: buildOpts() };
1179
+ const buildRainOpts = () => ({
1180
+ ...renderOpts,
1181
+ lightMode: renderOpts.lightMode !== void 0 ? renderOpts.lightMode : isLight(),
1182
+ color: color ?? renderOpts.color
1183
+ });
1184
+ const buildStarsOpts = () => ({
1185
+ ...renderOpts,
1186
+ lightMode: renderOpts.lightMode !== void 0 ? renderOpts.lightMode : isLight(),
1187
+ color: color ?? renderOpts.color
1188
+ });
1189
+ const optsRef = { current: buildWaveOpts() };
1190
+ const rebuildOpts = () => {
1191
+ if (type === "rain") optsRef.current = buildRainOpts();
1192
+ else if (type === "stars") optsRef.current = buildStarsOpts();
1193
+ else optsRef.current = buildWaveOpts();
1194
+ };
1195
+ rebuildOpts();
1059
1196
  const onSchemeChange = () => {
1060
- optsRef.current = buildOpts();
1197
+ rebuildOpts();
1061
1198
  };
1062
1199
  if (colorScheme === "auto") mq.addEventListener("change", onSchemeChange);
1063
1200
  const resize = () => {
@@ -1081,7 +1218,13 @@ function asciiBackground(target, options = {}) {
1081
1218
  smoothMouse.x += (mouse.x - smoothMouse.x) * 0.07;
1082
1219
  smoothMouse.y += (mouse.y - smoothMouse.y) * 0.07;
1083
1220
  const r = container.getBoundingClientRect();
1084
- renderWaveBackground(ctx, r.width, r.height, time, smoothMouse, optsRef.current);
1221
+ if (type === "rain") {
1222
+ renderRainBackground(ctx, r.width, r.height, time, optsRef.current);
1223
+ } else if (type === "stars") {
1224
+ renderStarsBackground(ctx, r.width, r.height, time, smoothMouse, optsRef.current);
1225
+ } else {
1226
+ renderWaveBackground(ctx, r.width, r.height, time, smoothMouse, optsRef.current);
1227
+ }
1085
1228
  time += 0.016;
1086
1229
  raf = requestAnimationFrame(tick);
1087
1230
  };
@@ -1547,6 +1690,6 @@ function tryCreateWebGLRenderer(canvas) {
1547
1690
  }
1548
1691
  }
1549
1692
 
1550
- export { ART_STYLE_PRESETS, CHARSETS, DEFAULT_OPTIONS, HOVER_PRESETS, asciiBackground, asciify, asciifyGif, asciifyVideo, generateAnimatedEmbedCode, generateEmbedCode, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, renderFrameToCanvas, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
1693
+ export { ART_STYLE_PRESETS, CHARSETS, DEFAULT_OPTIONS, HOVER_PRESETS, asciiBackground, asciify, asciifyGif, asciifyVideo, generateAnimatedEmbedCode, generateEmbedCode, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, renderFrameToCanvas, renderRainBackground, renderStarsBackground, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
1551
1694
  //# sourceMappingURL=index.js.map
1552
1695
  //# sourceMappingURL=index.js.map