asciify-engine 1.0.29 → 1.0.31

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
@@ -773,21 +773,4 @@ declare function recordAndDownload(canvas: HTMLCanvasElement, durationMs: number
773
773
  filename?: string;
774
774
  }): Promise<void>;
775
775
 
776
- interface WebGLRenderer {
777
- render(frame: AsciiFrame, options: AsciiOptions, displayW: number, displayH: number, time: number, hoverPos?: {
778
- x: number;
779
- y: number;
780
- intensity?: number;
781
- } | null): void;
782
- /** Call when options or the source frame has changed to invalidate cell data cache. */
783
- notifyDirty(): void;
784
- destroy(): void;
785
- }
786
- /**
787
- * Try to create a WebGL2 renderer for the given canvas.
788
- * Returns null if WebGL2 is unavailable (caller can then use Canvas2D).
789
- * On setup failure after context is claimed, returns a stub that clears to dark.
790
- */
791
- declare function tryCreateWebGLRenderer(canvas: HTMLCanvasElement): WebGLRenderer | null;
792
-
793
- export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciifySimpleOptions, type AuroraBackgroundOptions, CHARSETS, type CharsetKey, type CircuitBackgroundOptions, type ColorMode, DEFAULT_OPTIONS, type DnaBackgroundOptions, type FireBackgroundOptions, type GridBackgroundOptions, HOVER_PRESETS, type HoverEffect, type HoverPreset, type MorphBackgroundOptions, type MountWaveOptions, type NoiseBackgroundOptions, PALETTE_THEMES, type PaletteTheme, type PulseBackgroundOptions, type RainBackgroundOptions, type Recorder, type RecorderOptions, type RenderMode, type SilkBackgroundOptions, type SourceType, type StarsBackgroundOptions, type TerrainBackgroundOptions, type TextBackgroundOptions, type VoidBackgroundOptions, type WaveBackgroundOptions, type WebGLRenderer, asciiBackground, asciiText, asciiTextAnsi, asciify, asciifyGif, asciifyVideo, buildTextFrame, createRecorder, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, recordAndDownload, renderAuroraBackground, renderCircuitBackground, renderDnaBackground, renderFireBackground, renderFrameToCanvas, renderGridBackground, renderMorphBackground, renderNoiseBackground, renderPulseBackground, renderRainBackground, renderSilkBackground, renderStarsBackground, renderTerrainBackground, renderTextBackground, renderVoidBackground, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
776
+ export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciifySimpleOptions, type AuroraBackgroundOptions, CHARSETS, type CharsetKey, type CircuitBackgroundOptions, type ColorMode, DEFAULT_OPTIONS, type DnaBackgroundOptions, type FireBackgroundOptions, type GridBackgroundOptions, HOVER_PRESETS, type HoverEffect, type HoverPreset, type MorphBackgroundOptions, type MountWaveOptions, type NoiseBackgroundOptions, PALETTE_THEMES, type PaletteTheme, type PulseBackgroundOptions, type RainBackgroundOptions, type Recorder, type RecorderOptions, type RenderMode, type SilkBackgroundOptions, type SourceType, type StarsBackgroundOptions, type TerrainBackgroundOptions, type TextBackgroundOptions, type VoidBackgroundOptions, type WaveBackgroundOptions, asciiBackground, asciiText, asciiTextAnsi, asciify, asciifyGif, asciifyVideo, buildTextFrame, createRecorder, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, recordAndDownload, renderAuroraBackground, renderCircuitBackground, renderDnaBackground, renderFireBackground, renderFrameToCanvas, renderGridBackground, renderMorphBackground, renderNoiseBackground, renderPulseBackground, renderRainBackground, renderSilkBackground, renderStarsBackground, renderTerrainBackground, renderTextBackground, renderVoidBackground, renderWaveBackground, videoToAsciiFrames };
package/dist/index.d.ts CHANGED
@@ -773,21 +773,4 @@ declare function recordAndDownload(canvas: HTMLCanvasElement, durationMs: number
773
773
  filename?: string;
774
774
  }): Promise<void>;
775
775
 
776
- interface WebGLRenderer {
777
- render(frame: AsciiFrame, options: AsciiOptions, displayW: number, displayH: number, time: number, hoverPos?: {
778
- x: number;
779
- y: number;
780
- intensity?: number;
781
- } | null): void;
782
- /** Call when options or the source frame has changed to invalidate cell data cache. */
783
- notifyDirty(): void;
784
- destroy(): void;
785
- }
786
- /**
787
- * Try to create a WebGL2 renderer for the given canvas.
788
- * Returns null if WebGL2 is unavailable (caller can then use Canvas2D).
789
- * On setup failure after context is claimed, returns a stub that clears to dark.
790
- */
791
- declare function tryCreateWebGLRenderer(canvas: HTMLCanvasElement): WebGLRenderer | null;
792
-
793
- export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciifySimpleOptions, type AuroraBackgroundOptions, CHARSETS, type CharsetKey, type CircuitBackgroundOptions, type ColorMode, DEFAULT_OPTIONS, type DnaBackgroundOptions, type FireBackgroundOptions, type GridBackgroundOptions, HOVER_PRESETS, type HoverEffect, type HoverPreset, type MorphBackgroundOptions, type MountWaveOptions, type NoiseBackgroundOptions, PALETTE_THEMES, type PaletteTheme, type PulseBackgroundOptions, type RainBackgroundOptions, type Recorder, type RecorderOptions, type RenderMode, type SilkBackgroundOptions, type SourceType, type StarsBackgroundOptions, type TerrainBackgroundOptions, type TextBackgroundOptions, type VoidBackgroundOptions, type WaveBackgroundOptions, type WebGLRenderer, asciiBackground, asciiText, asciiTextAnsi, asciify, asciifyGif, asciifyVideo, buildTextFrame, createRecorder, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, recordAndDownload, renderAuroraBackground, renderCircuitBackground, renderDnaBackground, renderFireBackground, renderFrameToCanvas, renderGridBackground, renderMorphBackground, renderNoiseBackground, renderPulseBackground, renderRainBackground, renderSilkBackground, renderStarsBackground, renderTerrainBackground, renderTextBackground, renderVoidBackground, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
776
+ export { ART_STYLE_PRESETS, type AnimationStyle, type ArtStyle, type AsciiBackgroundOptions, type AsciiCell, type AsciiFrame, type AsciiOptions, type AsciiResult, type AsciifySimpleOptions, type AuroraBackgroundOptions, CHARSETS, type CharsetKey, type CircuitBackgroundOptions, type ColorMode, DEFAULT_OPTIONS, type DnaBackgroundOptions, type FireBackgroundOptions, type GridBackgroundOptions, HOVER_PRESETS, type HoverEffect, type HoverPreset, type MorphBackgroundOptions, type MountWaveOptions, type NoiseBackgroundOptions, PALETTE_THEMES, type PaletteTheme, type PulseBackgroundOptions, type RainBackgroundOptions, type Recorder, type RecorderOptions, type RenderMode, type SilkBackgroundOptions, type SourceType, type StarsBackgroundOptions, type TerrainBackgroundOptions, type TextBackgroundOptions, type VoidBackgroundOptions, type WaveBackgroundOptions, asciiBackground, asciiText, asciiTextAnsi, asciify, asciifyGif, asciifyVideo, buildTextFrame, createRecorder, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, recordAndDownload, renderAuroraBackground, renderCircuitBackground, renderDnaBackground, renderFireBackground, renderFrameToCanvas, renderGridBackground, renderMorphBackground, renderNoiseBackground, renderPulseBackground, renderRainBackground, renderSilkBackground, renderStarsBackground, renderTerrainBackground, renderTextBackground, renderVoidBackground, renderWaveBackground, videoToAsciiFrames };
package/dist/index.js CHANGED
@@ -2423,454 +2423,6 @@ async function recordAndDownload(canvas, durationMs, options = {}) {
2423
2423
  a.click();
2424
2424
  }
2425
2425
 
2426
- // src/webgl-engine.ts
2427
- var VERT_SRC = (
2428
- /* glsl */
2429
- `#version 300 es
2430
- precision highp float;
2431
- precision highp int;
2432
-
2433
- // Unit quad corners: (-0.5,-0.5) to (0.5,0.5) - TRIANGLE_STRIP, 4 verts
2434
- in vec2 a_corner;
2435
-
2436
- // Layout
2437
- uniform vec2 u_canvasSize;
2438
- uniform vec2 u_gridSize;
2439
- uniform vec2 u_cellSize;
2440
-
2441
- // Animation
2442
- uniform float u_time;
2443
- uniform float u_animSpeed;
2444
- uniform int u_animStyle;
2445
-
2446
- // Color
2447
- uniform int u_colorMode;
2448
- uniform vec3 u_accentColor;
2449
- uniform int u_invert;
2450
-
2451
- // Hover
2452
- uniform float u_hoverStrength;
2453
- uniform float u_hoverIntensity;
2454
- uniform vec2 u_hoverPos;
2455
- uniform float u_hoverRadius;
2456
- uniform int u_hoverEffect;
2457
- uniform vec3 u_hoverColor;
2458
-
2459
- // Render mode: 0=rect 1=dots
2460
- uniform int u_renderMode;
2461
- uniform float u_dotSizeRatio;
2462
-
2463
- // Cell data: RGBA8 texture (cols x rows)
2464
- // rgb = cell colour, a = source alpha
2465
- uniform sampler2D u_cellTex;
2466
-
2467
- out vec4 v_color;
2468
- out float v_alpha;
2469
- out vec2 v_localUv;
2470
-
2471
- #define PI 3.141592653589793
2472
-
2473
- float ss(float t) { return t * t * (3.0 - 2.0 * t); }
2474
-
2475
- float getAnim(float nx, float ny, float cx, float cy, float t) {
2476
- if (u_animStyle == 0) return 1.0;
2477
- if (u_animStyle == 1) { // wave
2478
- return 0.3 + 0.7 * (sin(nx * PI * 4.0 + t * 3.0) * 0.3 + 0.5
2479
- + sin(ny * PI * 3.0 + t * 2.0) * 0.2);
2480
- }
2481
- if (u_animStyle == 2) { // pulse
2482
- float d = length(vec2(nx - 0.5, ny - 0.5)) * 1.41421;
2483
- return 0.2 + 0.8 * (sin(d * PI * 6.0 - t * 4.0) * 0.5 + 0.5);
2484
- }
2485
- if (u_animStyle == 3) { // rain
2486
- float drop = sin(ny * PI * 8.0 - t * 5.0 + cx * 0.3) * 0.5 + 0.5;
2487
- return 0.1 + 0.9 * drop * (sin(nx * PI * 2.0 + t) * 0.3 + 0.7);
2488
- }
2489
- if (u_animStyle == 4) { // breathe
2490
- return clamp(sin(t * 2.0) * 0.3 + 0.7 + sin((cx + cy) * 0.1 + t) * 0.1, 0.1, 1.0);
2491
- }
2492
- if (u_animStyle == 5) { // sparkle
2493
- float sp = fract(sin(cx * 127.1 + cy * 311.7 + floor(t * 8.0) * 43758.5453) * 43758.5453);
2494
- return sp > 0.7 ? 1.0 : 0.15 + sp * 0.4;
2495
- }
2496
- if (u_animStyle == 6) { // glitch
2497
- float band = floor(cy / max(1.0, u_gridSize.y * 0.05));
2498
- float gv = fract(sin(band * 43.23 + floor(t * 6.0) * 17.89) * 43758.5453);
2499
- if (gv > 0.85) { float fl = sin(t * 30.0 + band) * 0.5 + 0.5; return fl < 0.3 ? 0.0 : fl; }
2500
- return 1.0;
2501
- }
2502
- if (u_animStyle == 7) { // spiral
2503
- float angle = atan(ny - 0.5, nx - 0.5);
2504
- float dist = length(vec2(nx - 0.5, ny - 0.5)) * 1.41421;
2505
- return 0.15 + 0.85 * (sin(angle * 3.0 + dist * PI * 8.0 - t * 3.0) * 0.5 + 0.5);
2506
- }
2507
- if (u_animStyle == 8) { // typewriter
2508
- float reveal = fract(t * 0.5) * u_gridSize.x * u_gridSize.y * 1.3;
2509
- float dist = cy * u_gridSize.x + cx - reveal;
2510
- if (dist > 0.0) return 0.0;
2511
- return clamp(1.0 + dist / (u_gridSize.x * u_gridSize.y * 0.15), 0.0, 1.0);
2512
- }
2513
- if (u_animStyle == 9) { // scatter
2514
- float d = length(vec2(nx - 0.5, ny - 0.5)) * 1.41421;
2515
- float phase = sin(t * 1.5) * 0.5 + 0.5;
2516
- if (d > phase) return max(0.0, 1.0 - (d - phase) * 3.0);
2517
- return 0.7 + 0.3 * sin(d * 10.0 - t * 2.0);
2518
- }
2519
- return 1.0;
2520
- }
2521
-
2522
- vec3 applyColorMode(vec3 rgb) {
2523
- float lum = dot(rgb, vec3(0.299, 0.587, 0.114));
2524
- if (u_colorMode == 0) return vec3(lum);
2525
- if (u_colorMode == 2) return vec3(0.0, lum, 0.0);
2526
- if (u_colorMode == 3) return lum * u_accentColor;
2527
- return rgb;
2528
- }
2529
-
2530
- void main() {
2531
- int cols = int(u_gridSize.x);
2532
- int rows = int(u_gridSize.y);
2533
- int cx = gl_InstanceID % cols;
2534
- int cy = gl_InstanceID / cols;
2535
-
2536
- float fnx = (float(cx) + 0.5) / float(cols);
2537
- float fny = (float(cy) + 0.5) / float(rows);
2538
-
2539
- // Sample cell data
2540
- vec4 cell = texture(u_cellTex, vec2(fnx, fny));
2541
- // cell.rgb = colour, cell.a = source alpha (0=transparent, 1=opaque)
2542
-
2543
- // Invisible cells (fully transparent source pixel)
2544
- if (cell.a < 0.004) {
2545
- gl_Position = vec4(2.0, 2.0, 0.0, 1.0); v_alpha = 0.0; return;
2546
- }
2547
-
2548
- // Char weight: 0=dark/space .. 1=dense/bright (luminance, matches luminanceToChar ordering)
2549
- float charW = dot(cell.rgb, vec3(0.299, 0.587, 0.114));
2550
-
2551
- float cellW = u_cellSize.x;
2552
- float cellH = u_cellSize.y;
2553
-
2554
- // Animation
2555
- float t = u_time * u_animSpeed;
2556
- float am = getAnim(fnx, fny, float(cx), float(cy), t);
2557
- if (am < 0.04) {
2558
- gl_Position = vec4(2.0, 2.0, 0.0, 1.0); v_alpha = 0.0; return;
2559
- }
2560
-
2561
- // Hover
2562
- float hoverScale = 1.0;
2563
- vec2 hoverOff = vec2(0.0);
2564
- float hoverGlow = 0.0;
2565
- float hoverBlend = 0.0;
2566
-
2567
- if (u_hoverStrength > 0.0 && u_hoverIntensity > 0.005) {
2568
- vec2 d = vec2(fnx - u_hoverPos.x, fny - u_hoverPos.y);
2569
- float r = 0.08 + u_hoverRadius * 0.35 + u_hoverStrength * 0.04;
2570
- float dist = length(d);
2571
- if (dist < r) {
2572
- float tv = 1.0 - dist / r;
2573
- float e = ss(tv) * u_hoverIntensity;
2574
- if (u_hoverEffect == 0) { // spotlight
2575
- hoverScale = 1.0 + e * u_hoverStrength * 1.8;
2576
- float ang = atan(d.y, d.x);
2577
- hoverOff = vec2(cos(ang), sin(ang)) * e * e * u_hoverStrength * 0.6 * vec2(cellW, cellH);
2578
- hoverGlow = e * u_hoverStrength * 0.4;
2579
- hoverBlend = e * e * u_hoverStrength * 0.25;
2580
- } else if (u_hoverEffect == 1) { // magnify
2581
- hoverScale = 1.0 + e * u_hoverStrength * 2.5;
2582
- hoverGlow = e * u_hoverStrength * 0.15;
2583
- } else if (u_hoverEffect == 2) { // repel
2584
- hoverScale = 1.0 + e * u_hoverStrength * 0.3;
2585
- float ang = atan(d.y, d.x);
2586
- hoverOff = vec2(cos(ang), sin(ang)) * e * e * u_hoverStrength * 1.2 * vec2(cellW, cellH);
2587
- } else if (u_hoverEffect == 3) { // glow
2588
- hoverGlow = e * u_hoverStrength * 0.8;
2589
- hoverBlend = e * u_hoverStrength * 0.4;
2590
- } else { // colorShift
2591
- hoverScale = 1.0 + e * u_hoverStrength * 0.4;
2592
- hoverGlow = e * u_hoverStrength * 0.2;
2593
- hoverBlend = e * u_hoverStrength * 0.7;
2594
- }
2595
- }
2596
- }
2597
-
2598
- // Final colour
2599
- vec3 rgb = (u_invert == 1) ? (1.0 - cell.rgb) : cell.rgb;
2600
- vec3 baseColor = applyColorMode(rgb);
2601
- v_color = vec4(mix(baseColor, u_hoverColor, hoverBlend), 1.0);
2602
-
2603
- // Quad size & alpha
2604
- vec2 quadSize;
2605
- float finalAlpha;
2606
-
2607
- if (u_renderMode == 1) { // dots: radius driven by char weight (bright=big dot)
2608
- float maxR = min(cellW, cellH) * 0.5 * u_dotSizeRatio;
2609
- float radius = maxR * charW * am * hoverScale;
2610
- if (radius < 0.3) { gl_Position = vec4(2.0, 2.0, 0.0, 1.0); v_alpha = 0.0; return; }
2611
- quadSize = vec2(radius * 2.0);
2612
- finalAlpha = min(1.0, cell.a * am * (1.0 + hoverGlow));
2613
- } else { // rect: size proportional to luminance \u2014 dark=tiny, bright=full (ASCII density look)
2614
- if (charW < 0.01) { gl_Position = vec4(2.0, 2.0, 0.0, 1.0); v_alpha = 0.0; return; }
2615
- quadSize = vec2(cellW * charW * hoverScale, cellH * charW * hoverScale);
2616
- finalAlpha = min(1.0, am * (1.0 + hoverGlow));
2617
- }
2618
-
2619
- v_alpha = finalAlpha;
2620
- v_localUv = a_corner;
2621
-
2622
- // NDC position (Y flipped: WebGL bottom-up, canvas top-down)
2623
- float px = float(cx) * cellW + cellW * 0.5 + hoverOff.x;
2624
- float py = float(cy) * cellH + cellH * 0.5 + hoverOff.y;
2625
- vec2 pos = vec2(px, py) + a_corner * quadSize;
2626
- vec2 ndc = pos / u_canvasSize * 2.0 - 1.0;
2627
- ndc.y = -ndc.y;
2628
- gl_Position = vec4(ndc, 0.0, 1.0);
2629
- }
2630
- `
2631
- );
2632
- var FRAG_SRC = (
2633
- /* glsl */
2634
- `#version 300 es
2635
- precision mediump float;
2636
- precision highp int;
2637
-
2638
- in vec4 v_color;
2639
- in float v_alpha;
2640
- in vec2 v_localUv;
2641
-
2642
- uniform int u_renderMode;
2643
-
2644
- out vec4 outColor;
2645
-
2646
- void main() {
2647
- if (v_alpha < 0.01) discard;
2648
- if (u_renderMode == 1) {
2649
- // Dots: circle SDF clip
2650
- if (length(v_localUv) > 0.5) discard;
2651
- }
2652
- outColor = vec4(v_color.rgb, v_alpha);
2653
- }
2654
- `
2655
- );
2656
- function compileShader(gl, type, src) {
2657
- const sh = gl.createShader(type);
2658
- gl.shaderSource(sh, src);
2659
- gl.compileShader(sh);
2660
- if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
2661
- const info = gl.getShaderInfoLog(sh) ?? "unknown";
2662
- gl.deleteShader(sh);
2663
- throw new Error(`Shader compile error: ${info}`);
2664
- }
2665
- return sh;
2666
- }
2667
- function linkProgram(gl, vert, frag) {
2668
- const prog = gl.createProgram();
2669
- gl.attachShader(prog, vert);
2670
- gl.attachShader(prog, frag);
2671
- gl.linkProgram(prog);
2672
- if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
2673
- const info = gl.getProgramInfoLog(prog) ?? "unknown";
2674
- gl.deleteProgram(prog);
2675
- throw new Error(`Program link error: ${info}`);
2676
- }
2677
- return prog;
2678
- }
2679
- function makeTexture(gl, filter = gl.NEAREST) {
2680
- const t = gl.createTexture();
2681
- gl.bindTexture(gl.TEXTURE_2D, t);
2682
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
2683
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
2684
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
2685
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
2686
- return t;
2687
- }
2688
- var ANIM_STYLES = ["none", "wave", "pulse", "rain", "breathe", "sparkle", "glitch", "spiral", "typewriter", "scatter", "waveField", "ripple", "melt", "orbit", "cellular"];
2689
- var HOVER_EFFECTS = ["spotlight", "magnify", "repel", "glow", "colorShift", "attract", "shatter", "trail"];
2690
- var COLOR_MODES = ["grayscale", "fullcolor", "matrix", "accent"];
2691
- function tryCreateWebGLRenderer(canvas) {
2692
- const glOrNull = canvas.getContext("webgl2", {
2693
- alpha: true,
2694
- antialias: false,
2695
- premultipliedAlpha: false,
2696
- preserveDrawingBuffer: false
2697
- });
2698
- if (!glOrNull) return null;
2699
- const gl = glOrNull;
2700
- try {
2701
- let render2 = function(frame, options, displayW, displayH, time, hoverPos) {
2702
- const rows = frame.length;
2703
- if (rows === 0) return;
2704
- const cols = frame[0].length;
2705
- if (cols === 0) return;
2706
- gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
2707
- let hasTransparency = false;
2708
- const sy = Math.max(1, rows >> 2), sx = Math.max(1, cols >> 2);
2709
- outer: for (let iy = 0; iy < rows; iy += sy)
2710
- for (let ix = 0; ix < cols; ix += sx)
2711
- if (frame[iy][ix].a < 200) {
2712
- hasTransparency = true;
2713
- break outer;
2714
- }
2715
- gl.clearColor(
2716
- hasTransparency ? 0 : 0.0392,
2717
- hasTransparency ? 0 : 0.0392,
2718
- hasTransparency ? 0 : 0.0392,
2719
- hasTransparency ? 0 : 1
2720
- );
2721
- gl.clear(gl.COLOR_BUFFER_BIT);
2722
- if (cols !== lastCols || rows !== lastRows) {
2723
- cellBuf = new Uint8Array(cols * rows * 4);
2724
- lastCols = cols;
2725
- lastRows = rows;
2726
- cellDataDirty = true;
2727
- }
2728
- if (cellDataDirty) {
2729
- for (let y = 0; y < rows; y++) {
2730
- const row = frame[y];
2731
- for (let x = 0; x < cols; x++) {
2732
- const cell = row[x];
2733
- const i = (y * cols + x) * 4;
2734
- cellBuf[i] = cell.r;
2735
- cellBuf[i + 1] = cell.g;
2736
- cellBuf[i + 2] = cell.b;
2737
- cellBuf[i + 3] = cell.a;
2738
- }
2739
- }
2740
- gl.activeTexture(gl.TEXTURE0);
2741
- gl.bindTexture(gl.TEXTURE_2D, cellTex);
2742
- gl.texImage2D(
2743
- gl.TEXTURE_2D,
2744
- 0,
2745
- gl.RGBA,
2746
- cols,
2747
- rows,
2748
- 0,
2749
- gl.RGBA,
2750
- gl.UNSIGNED_BYTE,
2751
- cellBuf
2752
- );
2753
- cellDataDirty = false;
2754
- }
2755
- gl.activeTexture(gl.TEXTURE0);
2756
- gl.bindTexture(gl.TEXTURE_2D, cellTex);
2757
- gl.useProgram(prog);
2758
- gl.bindVertexArray(vao);
2759
- const cellW = displayW / cols;
2760
- const cellH = displayH / rows;
2761
- gl.uniform2f(u.canvasSize, displayW, displayH);
2762
- gl.uniform2f(u.gridSize, cols, rows);
2763
- gl.uniform2f(u.cellSize, cellW, cellH);
2764
- gl.uniform1f(u.time, time);
2765
- gl.uniform1f(u.animSpeed, options.animationSpeed);
2766
- gl.uniform1i(u.animStyle, ANIM_STYLES.indexOf(options.animationStyle));
2767
- gl.uniform1i(u.colorMode, COLOR_MODES.indexOf(options.colorMode));
2768
- const acHex = (options.accentColor || "#ffffff").replace("#", "");
2769
- gl.uniform3f(
2770
- u.accentColor,
2771
- parseInt(acHex.slice(0, 2), 16) / 255,
2772
- parseInt(acHex.slice(2, 4), 16) / 255,
2773
- parseInt(acHex.slice(4, 6), 16) / 255
2774
- );
2775
- gl.uniform1i(u.invert, options.invert ? 1 : 0);
2776
- const totalCells = rows * cols;
2777
- const animActive = options.animationStyle !== "none";
2778
- const suppressHover = animActive && totalCells > 5e3;
2779
- const hoverActive = !suppressHover && !!hoverPos && options.hoverStrength > 0;
2780
- const radiusScale = totalCells > 3e4 ? 0.25 : totalCells > 15e3 ? 0.4 : totalCells > 5e3 ? 0.6 : 1;
2781
- gl.uniform1f(u.hoverStrength, hoverActive ? options.hoverStrength : 0);
2782
- gl.uniform1f(u.hoverIntensity, hoverActive ? hoverPos?.intensity ?? 0 : 0);
2783
- gl.uniform2f(u.hoverPos, hoverPos?.x ?? 0.5, hoverPos?.y ?? 0.5);
2784
- gl.uniform1f(u.hoverRadius, options.hoverRadius * radiusScale);
2785
- gl.uniform1i(u.hoverEffect, HOVER_EFFECTS.indexOf(options.hoverEffect));
2786
- const hc = options.hoverColor || "#ffffff";
2787
- gl.uniform3f(
2788
- u.hoverColor,
2789
- parseInt(hc.slice(1, 3), 16) / 255,
2790
- parseInt(hc.slice(3, 5), 16) / 255,
2791
- parseInt(hc.slice(5, 7), 16) / 255
2792
- );
2793
- gl.uniform1i(u.renderMode, options.renderMode === "dots" ? 1 : 0);
2794
- gl.uniform1f(u.dotSizeRatio, options.dotSizeRatio);
2795
- gl.uniform1i(u.cellTexU, 0);
2796
- gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, cols * rows);
2797
- gl.bindVertexArray(null);
2798
- };
2799
- var render = render2;
2800
- const vert = compileShader(gl, gl.VERTEX_SHADER, VERT_SRC);
2801
- const frag = compileShader(gl, gl.FRAGMENT_SHADER, FRAG_SRC);
2802
- const prog = linkProgram(gl, vert, frag);
2803
- gl.deleteShader(vert);
2804
- gl.deleteShader(frag);
2805
- const vao = gl.createVertexArray();
2806
- gl.bindVertexArray(vao);
2807
- const corners = new Float32Array([-0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5]);
2808
- const vbo = gl.createBuffer();
2809
- gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
2810
- gl.bufferData(gl.ARRAY_BUFFER, corners, gl.STATIC_DRAW);
2811
- const aCorner = gl.getAttribLocation(prog, "a_corner");
2812
- gl.enableVertexAttribArray(aCorner);
2813
- gl.vertexAttribPointer(aCorner, 2, gl.FLOAT, false, 0, 0);
2814
- gl.bindVertexArray(null);
2815
- const cellTex = makeTexture(gl);
2816
- const g = (n) => gl.getUniformLocation(prog, n);
2817
- const u = {
2818
- canvasSize: g("u_canvasSize"),
2819
- gridSize: g("u_gridSize"),
2820
- cellSize: g("u_cellSize"),
2821
- time: g("u_time"),
2822
- animSpeed: g("u_animSpeed"),
2823
- animStyle: g("u_animStyle"),
2824
- colorMode: g("u_colorMode"),
2825
- accentColor: g("u_accentColor"),
2826
- invert: g("u_invert"),
2827
- hoverStrength: g("u_hoverStrength"),
2828
- hoverIntensity: g("u_hoverIntensity"),
2829
- hoverPos: g("u_hoverPos"),
2830
- hoverRadius: g("u_hoverRadius"),
2831
- hoverEffect: g("u_hoverEffect"),
2832
- hoverColor: g("u_hoverColor"),
2833
- renderMode: g("u_renderMode"),
2834
- dotSizeRatio: g("u_dotSizeRatio"),
2835
- cellTexU: g("u_cellTex")
2836
- };
2837
- let lastCols = 0;
2838
- let lastRows = 0;
2839
- let cellBuf = new Uint8Array(0);
2840
- let cellDataDirty = true;
2841
- gl.enable(gl.BLEND);
2842
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
2843
- return {
2844
- render: render2,
2845
- notifyDirty() {
2846
- cellDataDirty = true;
2847
- },
2848
- destroy() {
2849
- gl.deleteProgram(prog);
2850
- gl.deleteVertexArray(vao);
2851
- gl.deleteBuffer(vbo);
2852
- gl.deleteTexture(cellTex);
2853
- }
2854
- };
2855
- } catch (err) {
2856
- console.error("[asciify] WebGL renderer setup FAILED (returning stub):", err);
2857
- const stub = {
2858
- render() {
2859
- try {
2860
- gl.clearColor(0.039, 0.039, 0.039, 1);
2861
- gl.clear(gl.COLOR_BUFFER_BIT);
2862
- } catch {
2863
- }
2864
- },
2865
- notifyDirty() {
2866
- },
2867
- destroy() {
2868
- }
2869
- };
2870
- return stub;
2871
- }
2872
- }
2873
-
2874
- export { ART_STYLE_PRESETS, CHARSETS, DEFAULT_OPTIONS, HOVER_PRESETS, PALETTE_THEMES, asciiBackground, asciiText, asciiTextAnsi, asciify, asciifyGif, asciifyVideo, buildTextFrame, createRecorder, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, recordAndDownload, renderAuroraBackground, renderCircuitBackground, renderDnaBackground, renderFireBackground, renderFrameToCanvas, renderGridBackground, renderMorphBackground, renderNoiseBackground, renderPulseBackground, renderRainBackground, renderSilkBackground, renderStarsBackground, renderTerrainBackground, renderTextBackground, renderVoidBackground, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
2426
+ export { ART_STYLE_PRESETS, CHARSETS, DEFAULT_OPTIONS, HOVER_PRESETS, PALETTE_THEMES, asciiBackground, asciiText, asciiTextAnsi, asciify, asciifyGif, asciifyVideo, buildTextFrame, createRecorder, gifToAsciiFrames, imageToAsciiFrame, mountWaveBackground, recordAndDownload, renderAuroraBackground, renderCircuitBackground, renderDnaBackground, renderFireBackground, renderFrameToCanvas, renderGridBackground, renderMorphBackground, renderNoiseBackground, renderPulseBackground, renderRainBackground, renderSilkBackground, renderStarsBackground, renderTerrainBackground, renderTextBackground, renderVoidBackground, renderWaveBackground, videoToAsciiFrames };
2875
2427
  //# sourceMappingURL=index.js.map
2876
2428
  //# sourceMappingURL=index.js.map