@autumnsgrove/gossamer 0.0.1 → 0.1.0
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/animation.d.ts +80 -0
- package/dist/animation.d.ts.map +1 -0
- package/dist/characters.d.ts +49 -0
- package/dist/characters.d.ts.map +1 -0
- package/dist/index.d.ts +37 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1284 -2
- package/dist/index.js.map +1 -1
- package/dist/patterns.d.ts +100 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/renderer.d.ts +113 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/style.css +124 -0
- package/dist/svelte/GossamerBorder.svelte.d.ts +1 -0
- package/dist/svelte/GossamerClouds.svelte.d.ts +1 -0
- package/dist/svelte/GossamerImage.svelte.d.ts +1 -0
- package/dist/svelte/GossamerOverlay.svelte.d.ts +1 -0
- package/dist/svelte/GossamerText.svelte.d.ts +1 -0
- package/dist/svelte/index.d.ts +20 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +3651 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/svelte/presets.d.ts +38 -0
- package/dist/svelte/presets.d.ts.map +1 -0
- package/dist/utils/canvas.d.ts +73 -0
- package/dist/utils/canvas.d.ts.map +1 -0
- package/dist/utils/image.d.ts +74 -0
- package/dist/utils/image.d.ts.map +1 -0
- package/dist/utils/performance.d.ts +86 -0
- package/dist/utils/performance.d.ts.map +1 -0
- package/package.json +23 -5
- package/src/animation.test.ts +254 -0
- package/src/animation.ts +243 -0
- package/src/characters.test.ts +148 -0
- package/src/characters.ts +164 -0
- package/src/index.test.ts +115 -0
- package/src/index.ts +133 -11
- package/src/patterns.test.ts +273 -0
- package/src/patterns.ts +316 -0
- package/src/renderer.ts +309 -0
- package/src/svelte/GossamerBorder.svelte +326 -0
- package/src/svelte/GossamerClouds.svelte +269 -0
- package/src/svelte/GossamerImage.svelte +266 -0
- package/src/svelte/GossamerOverlay.svelte +232 -0
- package/src/svelte/GossamerText.svelte +239 -0
- package/src/svelte/index.ts +75 -0
- package/src/svelte/presets.ts +174 -0
- package/src/utils/canvas.ts +210 -0
- package/src/utils/image.ts +275 -0
- package/src/utils/performance.ts +282 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Gossamer - ASCII Visual Effects Library\n *\n * Threads of light. Delicate textures woven through your space.\n *\n * @packageDocumentation\n */\n\n/**\n * Core configuration for ASCII rendering\n */\nexport interface GossamerConfig {\n /** Character set for ASCII rendering (light to dark) */\n characters?: string;\n /** Cell width in pixels */\n cellWidth?: number;\n /** Cell height in pixels */\n cellHeight?: number;\n /** Foreground color */\n color?: string;\n /** Background color (transparent if not set) */\n backgroundColor?: string;\n /** Font family for ASCII characters */\n fontFamily?: string;\n /** Enable animation loop */\n animate?: boolean;\n /** Target FPS for animation */\n fps?: number;\n}\n\n/**\n * Default character set ordered from light to dark\n */\nexport const DEFAULT_CHARACTERS = ' .:-=+*#%@';\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<GossamerConfig> = {\n characters: DEFAULT_CHARACTERS,\n cellWidth: 8,\n cellHeight: 12,\n color: '#ffffff',\n backgroundColor: '',\n fontFamily: 'monospace',\n animate: false,\n fps: 30,\n};\n\n/**\n * Calculate brightness from RGB values using luminance formula\n * Uses the standard luminance coefficients: 0.21 R + 0.72 G + 0.07 B\n */\nexport function calculateBrightness(r: number, g: number, b: number): number {\n return 0.21 * r + 0.72 * g + 0.07 * b;\n}\n\n/**\n * Map a brightness value (0-255) to an ASCII character\n */\nexport function brightnessToChar(\n brightness: number,\n characters: string = DEFAULT_CHARACTERS\n): string {\n const index = Math.floor((brightness / 255) * (characters.length - 1));\n return characters[Math.min(index, characters.length - 1)];\n}\n\n/**\n * Gossamer v0.0.1 - Placeholder release\n *\n * Full implementation coming soon. This package will provide:\n * - 2D Canvas ASCII rendering\n * - Ambient pattern generation\n * - Image-to-ASCII conversion\n * - Animation loops\n * - Framework adapters (Svelte, React, Vue)\n *\n * @see https://github.com/AutumnsGrove/Gossamer\n */\nexport const VERSION = '0.0.1';\n"],"names":[],"mappings":"AAiCO,MAAM,qBAAqB;AAK3B,MAAM,iBAA2C;AAAA,EACtD,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,KAAK;AACP;AAMO,SAAS,oBAAoB,GAAW,GAAW,GAAmB;AAC3E,SAAO,OAAO,IAAI,OAAO,IAAI,OAAO;AACtC;AAKO,SAAS,iBACd,YACA,aAAqB,oBACb;AACR,QAAM,QAAQ,KAAK,MAAO,aAAa,OAAQ,WAAW,SAAS,EAAE;AACrE,SAAO,WAAW,KAAK,IAAI,OAAO,WAAW,SAAS,CAAC,CAAC;AAC1D;AAcO,MAAM,UAAU;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/renderer.ts","../src/patterns.ts","../src/characters.ts","../src/animation.ts","../src/utils/canvas.ts","../src/utils/image.ts","../src/utils/performance.ts","../src/index.ts"],"sourcesContent":["/**\n * Gossamer Core Renderer\n *\n * Canvas-based ASCII rendering engine. Converts image data to ASCII characters\n * by mapping brightness values to a character set.\n */\n\n// Define locally to avoid circular dependency with index.ts\nconst DEFAULT_CHARACTERS = ' .:-=+*#%@';\n\nfunction calculateBrightness(r: number, g: number, b: number): number {\n return 0.21 * r + 0.72 * g + 0.07 * b;\n}\n\n/**\n * Configuration for the Gossamer renderer\n */\nexport interface RenderConfig {\n /** Canvas element to render to */\n canvas: HTMLCanvasElement;\n /** Character set ordered from light to dark */\n characters: string;\n /** Width of each character cell in pixels */\n cellWidth: number;\n /** Height of each character cell in pixels */\n cellHeight: number;\n /** Color for rendering characters */\n color: string;\n /** Background color (empty string for transparent) */\n backgroundColor: string;\n /** Font family */\n fontFamily: string;\n /** Custom brightness calculation function */\n brightnessFunction: (r: number, g: number, b: number) => number;\n}\n\n/**\n * Default render configuration\n */\nconst DEFAULT_RENDER_CONFIG: Omit<RenderConfig, 'canvas'> = {\n characters: DEFAULT_CHARACTERS,\n cellWidth: 8,\n cellHeight: 12,\n color: '#ffffff',\n backgroundColor: '',\n fontFamily: 'monospace',\n brightnessFunction: calculateBrightness,\n};\n\n/**\n * Core ASCII renderer class\n *\n * Handles all canvas rendering operations for ASCII effects.\n * Supports both static rendering and animation loops.\n */\nexport class GossamerRenderer {\n private ctx: CanvasRenderingContext2D;\n private config: RenderConfig;\n private animationId: number | null = null;\n private lastFrameTime: number = 0;\n private isRunning: boolean = false;\n\n constructor(canvas: HTMLCanvasElement, config: Partial<Omit<RenderConfig, 'canvas'>> = {}) {\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Failed to get 2D rendering context');\n }\n\n this.ctx = context;\n this.config = {\n canvas,\n ...DEFAULT_RENDER_CONFIG,\n ...config,\n };\n\n this.setupCanvas();\n }\n\n /**\n * Set up the canvas with optimal rendering settings\n */\n private setupCanvas(): void {\n const { fontFamily, cellHeight } = this.config;\n\n // Set font for consistent character sizing\n this.ctx.font = `${cellHeight}px ${fontFamily}`;\n this.ctx.textBaseline = 'top';\n\n // Enable image smoothing for better quality\n this.ctx.imageSmoothingEnabled = true;\n this.ctx.imageSmoothingQuality = 'high';\n }\n\n /**\n * Update the renderer configuration\n */\n updateConfig(config: Partial<Omit<RenderConfig, 'canvas'>>): void {\n this.config = { ...this.config, ...config };\n this.setupCanvas();\n }\n\n /**\n * Resize the canvas to match new dimensions\n */\n resize(width: number, height: number): void {\n const { canvas } = this.config;\n canvas.width = width;\n canvas.height = height;\n this.setupCanvas();\n }\n\n /**\n * Get the current canvas dimensions\n */\n getDimensions(): { width: number; height: number } {\n return {\n width: this.config.canvas.width,\n height: this.config.canvas.height,\n };\n }\n\n /**\n * Calculate the number of cells that fit in the canvas\n */\n getCellCount(): { cols: number; rows: number } {\n const { width, height } = this.getDimensions();\n const { cellWidth, cellHeight } = this.config;\n\n return {\n cols: Math.ceil(width / cellWidth),\n rows: Math.ceil(height / cellHeight),\n };\n }\n\n /**\n * Clear the canvas\n */\n clear(): void {\n const { canvas, backgroundColor } = this.config;\n\n if (backgroundColor) {\n this.ctx.fillStyle = backgroundColor;\n this.ctx.fillRect(0, 0, canvas.width, canvas.height);\n } else {\n this.ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n }\n\n /**\n * Render a single frame from image data\n */\n renderFrame(imageData: ImageData): void {\n const { canvas, characters, cellWidth, cellHeight, color, brightnessFunction } = this.config;\n const { width, data } = imageData;\n\n this.clear();\n this.ctx.fillStyle = color;\n\n for (let y = 0; y < canvas.height; y += cellHeight) {\n for (let x = 0; x < canvas.width; x += cellWidth) {\n const brightness = this.getCellBrightness(data, x, y, width, cellWidth, cellHeight, brightnessFunction);\n const charIndex = Math.floor((brightness / 255) * (characters.length - 1));\n const char = characters[Math.min(charIndex, characters.length - 1)];\n\n if (char !== ' ') {\n this.ctx.fillText(char, x, y);\n }\n }\n }\n }\n\n /**\n * Render ASCII from a brightness grid (for pattern-based rendering)\n */\n renderFromBrightnessGrid(grid: number[][]): void {\n const { characters, cellWidth, cellHeight, color } = this.config;\n\n this.clear();\n this.ctx.fillStyle = color;\n\n for (let row = 0; row < grid.length; row++) {\n for (let col = 0; col < grid[row].length; col++) {\n const brightness = grid[row][col];\n const charIndex = Math.floor((brightness / 255) * (characters.length - 1));\n const char = characters[Math.min(charIndex, characters.length - 1)];\n\n if (char !== ' ') {\n this.ctx.fillText(char, col * cellWidth, row * cellHeight);\n }\n }\n }\n }\n\n /**\n * Render ASCII with per-cell colors (for colored image rendering)\n */\n renderWithColors(data: Array<{ char: string; color: string; x: number; y: number }>): void {\n this.clear();\n\n for (const { char, color, x, y } of data) {\n if (char !== ' ') {\n this.ctx.fillStyle = color;\n this.ctx.fillText(char, x, y);\n }\n }\n }\n\n /**\n * Calculate average brightness for a cell region\n */\n private getCellBrightness(\n data: Uint8ClampedArray,\n startX: number,\n startY: number,\n imageWidth: number,\n cellWidth: number,\n cellHeight: number,\n brightnessFunction: (r: number, g: number, b: number) => number\n ): number {\n let total = 0;\n let count = 0;\n\n for (let cy = 0; cy < cellHeight; cy++) {\n for (let cx = 0; cx < cellWidth; cx++) {\n const px = ((startY + cy) * imageWidth + (startX + cx)) * 4;\n if (px >= 0 && px + 2 < data.length) {\n total += brightnessFunction(data[px], data[px + 1], data[px + 2]);\n count++;\n }\n }\n }\n\n return count > 0 ? total / count : 0;\n }\n\n /**\n * Start an animation loop with FPS limiting\n */\n startAnimation(\n updateFn: (time: number, deltaTime: number) => ImageData | number[][],\n fps: number = 30\n ): void {\n if (this.isRunning) {\n this.stopAnimation();\n }\n\n this.isRunning = true;\n const frameInterval = 1000 / fps;\n this.lastFrameTime = performance.now();\n\n const animate = (currentTime: number): void => {\n if (!this.isRunning) return;\n\n const deltaTime = currentTime - this.lastFrameTime;\n\n if (deltaTime >= frameInterval) {\n const result = updateFn(currentTime, deltaTime);\n\n if (result instanceof ImageData) {\n this.renderFrame(result);\n } else {\n this.renderFromBrightnessGrid(result);\n }\n\n this.lastFrameTime = currentTime - (deltaTime % frameInterval);\n }\n\n this.animationId = requestAnimationFrame(animate);\n };\n\n this.animationId = requestAnimationFrame(animate);\n }\n\n /**\n * Stop the animation loop\n */\n stopAnimation(): void {\n this.isRunning = false;\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n this.animationId = null;\n }\n }\n\n /**\n * Check if animation is currently running\n */\n isAnimating(): boolean {\n return this.isRunning;\n }\n\n /**\n * Pause animation (can be resumed)\n */\n pause(): void {\n this.isRunning = false;\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n this.animationId = null;\n }\n }\n\n /**\n * Clean up and destroy the renderer\n */\n destroy(): void {\n this.stopAnimation();\n }\n}\n","/**\n * Gossamer Pattern Generators\n *\n * Provides noise and pattern generation functions for ambient ASCII effects.\n * Includes Perlin noise, wave patterns, and static noise.\n */\n\n/**\n * Configuration for pattern generation\n */\nexport interface PatternConfig {\n /** Pattern scale - higher values create finer detail */\n frequency: number;\n /** Pattern intensity multiplier */\n amplitude: number;\n /** Animation speed multiplier */\n speed: number;\n}\n\n/**\n * Default pattern configuration\n */\nexport const DEFAULT_PATTERN_CONFIG: PatternConfig = {\n frequency: 0.05,\n amplitude: 1.0,\n speed: 0.5,\n};\n\n// Permutation table for Perlin noise\nconst PERMUTATION = new Uint8Array(512);\nconst P = new Uint8Array([\n 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142,\n 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203,\n 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165,\n 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92,\n 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208,\n 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217,\n 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,\n 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155,\n 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218,\n 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249,\n 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4,\n 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156,\n 180,\n]);\n\n// Initialize permutation table\nfor (let i = 0; i < 256; i++) {\n PERMUTATION[i] = P[i];\n PERMUTATION[i + 256] = P[i];\n}\n\n/**\n * Fade function for smooth interpolation (6t^5 - 15t^4 + 10t^3)\n */\nfunction fade(t: number): number {\n return t * t * t * (t * (t * 6 - 15) + 10);\n}\n\n/**\n * Linear interpolation\n */\nfunction lerp(a: number, b: number, t: number): number {\n return a + t * (b - a);\n}\n\n/**\n * Gradient function for Perlin noise\n */\nfunction grad(hash: number, x: number, y: number): number {\n const h = hash & 3;\n const u = h < 2 ? x : y;\n const v = h < 2 ? y : x;\n return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);\n}\n\n/**\n * 2D Perlin noise function\n *\n * @param x - X coordinate\n * @param y - Y coordinate\n * @returns Noise value between -1 and 1\n */\nexport function perlinNoise2D(x: number, y: number): number {\n // Find unit square containing point\n const xi = Math.floor(x) & 255;\n const yi = Math.floor(y) & 255;\n\n // Find relative position in square\n const xf = x - Math.floor(x);\n const yf = y - Math.floor(y);\n\n // Fade curves\n const u = fade(xf);\n const v = fade(yf);\n\n // Hash coordinates of square corners\n const aa = PERMUTATION[PERMUTATION[xi] + yi];\n const ab = PERMUTATION[PERMUTATION[xi] + yi + 1];\n const ba = PERMUTATION[PERMUTATION[xi + 1] + yi];\n const bb = PERMUTATION[PERMUTATION[xi + 1] + yi + 1];\n\n // Blend results from 4 corners\n const x1 = lerp(grad(aa, xf, yf), grad(ba, xf - 1, yf), u);\n const x2 = lerp(grad(ab, xf, yf - 1), grad(bb, xf - 1, yf - 1), u);\n\n return lerp(x1, x2, v);\n}\n\n/**\n * Fractal Brownian Motion (fBm) using Perlin noise\n * Creates more organic-looking noise by layering multiple octaves\n *\n * @param x - X coordinate\n * @param y - Y coordinate\n * @param octaves - Number of noise layers (default: 4)\n * @param persistence - Amplitude decay per octave (default: 0.5)\n * @returns Noise value between -1 and 1\n */\nexport function fbmNoise(x: number, y: number, octaves: number = 4, persistence: number = 0.5): number {\n let total = 0;\n let frequency = 1;\n let amplitude = 1;\n let maxValue = 0;\n\n for (let i = 0; i < octaves; i++) {\n total += perlinNoise2D(x * frequency, y * frequency) * amplitude;\n maxValue += amplitude;\n amplitude *= persistence;\n frequency *= 2;\n }\n\n return total / maxValue;\n}\n\n/**\n * Wave pattern generator\n *\n * @param x - X coordinate\n * @param y - Y coordinate\n * @param time - Time value for animation\n * @param config - Pattern configuration\n * @returns Value between -1 and 1\n */\nexport function wavePattern(\n x: number,\n y: number,\n time: number,\n config: PatternConfig = DEFAULT_PATTERN_CONFIG\n): number {\n const { frequency, amplitude, speed } = config;\n const wave1 = Math.sin(x * frequency + time * speed);\n const wave2 = Math.cos(y * frequency + time * speed * 0.7);\n const wave3 = Math.sin((x + y) * frequency * 0.5 + time * speed * 0.5);\n\n return ((wave1 + wave2 + wave3) / 3) * amplitude;\n}\n\n/**\n * Ripple pattern (concentric waves from center)\n *\n * @param x - X coordinate\n * @param y - Y coordinate\n * @param centerX - Ripple center X\n * @param centerY - Ripple center Y\n * @param time - Time value for animation\n * @param config - Pattern configuration\n * @returns Value between -1 and 1\n */\nexport function ripplePattern(\n x: number,\n y: number,\n centerX: number,\n centerY: number,\n time: number,\n config: PatternConfig = DEFAULT_PATTERN_CONFIG\n): number {\n const { frequency, amplitude, speed } = config;\n const dx = x - centerX;\n const dy = y - centerY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n return Math.sin(distance * frequency - time * speed) * amplitude;\n}\n\n/**\n * Static noise generator (random values)\n *\n * @param seed - Optional seed for reproducible noise\n * @returns Value between 0 and 1\n */\nexport function staticNoise(seed?: number): number {\n if (seed !== undefined) {\n // Simple seeded random using sine\n const x = Math.sin(seed * 12.9898) * 43758.5453;\n return x - Math.floor(x);\n }\n return Math.random();\n}\n\n/**\n * Seeded 2D noise for reproducible patterns\n *\n * @param x - X coordinate\n * @param y - Y coordinate\n * @param seed - Seed value\n * @returns Value between 0 and 1\n */\nexport function seededNoise2D(x: number, y: number, seed: number = 0): number {\n const n = Math.sin(x * 12.9898 + y * 78.233 + seed) * 43758.5453;\n return n - Math.floor(n);\n}\n\n/**\n * Generate a brightness grid for pattern rendering\n *\n * @param cols - Number of columns\n * @param rows - Number of rows\n * @param pattern - Pattern type\n * @param time - Current time in seconds\n * @param config - Pattern configuration\n * @returns 2D array of brightness values (0-255)\n */\nexport function generateBrightnessGrid(\n cols: number,\n rows: number,\n pattern: 'perlin' | 'waves' | 'static' | 'ripple' | 'fbm',\n time: number = 0,\n config: PatternConfig = DEFAULT_PATTERN_CONFIG\n): number[][] {\n const grid: number[][] = [];\n const { frequency, amplitude, speed } = config;\n\n for (let row = 0; row < rows; row++) {\n grid[row] = [];\n for (let col = 0; col < cols; col++) {\n let value: number;\n\n switch (pattern) {\n case 'perlin':\n value = perlinNoise2D(\n col * frequency + time * speed * 0.1,\n row * frequency + time * speed * 0.05\n );\n break;\n\n case 'fbm':\n value = fbmNoise(\n col * frequency + time * speed * 0.1,\n row * frequency + time * speed * 0.05,\n 4,\n 0.5\n );\n break;\n\n case 'waves':\n value = wavePattern(col, row, time, config);\n break;\n\n case 'ripple':\n value = ripplePattern(col, row, cols / 2, rows / 2, time, config);\n break;\n\n case 'static':\n default:\n // For static, use time as seed for animated static\n value = seededNoise2D(col, row, Math.floor(time * speed * 10)) * 2 - 1;\n break;\n }\n\n // Normalize from [-1, 1] to [0, 255] with amplitude\n const normalized = (value + 1) * 0.5 * amplitude;\n const brightness = Math.max(0, Math.min(255, Math.floor(normalized * 255)));\n grid[row][col] = brightness;\n }\n }\n\n return grid;\n}\n\n/**\n * Generate ImageData from a brightness grid\n *\n * @param grid - 2D array of brightness values\n * @param cellWidth - Width of each cell\n * @param cellHeight - Height of each cell\n * @returns ImageData object\n */\nexport function gridToImageData(grid: number[][], cellWidth: number, cellHeight: number): ImageData {\n const rows = grid.length;\n const cols = grid[0]?.length || 0;\n const width = cols * cellWidth;\n const height = rows * cellHeight;\n const data = new Uint8ClampedArray(width * height * 4);\n\n for (let row = 0; row < rows; row++) {\n for (let col = 0; col < cols; col++) {\n const brightness = grid[row][col];\n\n // Fill cell region with brightness value\n for (let cy = 0; cy < cellHeight; cy++) {\n for (let cx = 0; cx < cellWidth; cx++) {\n const px = ((row * cellHeight + cy) * width + (col * cellWidth + cx)) * 4;\n data[px] = brightness; // R\n data[px + 1] = brightness; // G\n data[px + 2] = brightness; // B\n data[px + 3] = 255; // A\n }\n }\n }\n }\n\n return new ImageData(data, width, height);\n}\n\nexport type PatternType = 'perlin' | 'waves' | 'static' | 'ripple' | 'fbm';\n","/**\n * Gossamer Character Sets\n *\n * Predefined character sets for ASCII rendering, ordered from light to dark.\n * Character density determines which character represents each brightness level.\n */\n\n/**\n * Character set configuration\n */\nexport interface CharacterSet {\n /** Unique identifier for the character set */\n name: string;\n /** Description of the set's aesthetic */\n description: string;\n /** Characters ordered from lightest (space) to darkest */\n characters: string;\n /** Recommended use cases */\n bestFor: string[];\n}\n\n/**\n * Standard character sets for ASCII rendering\n */\nexport const CHARACTER_SETS: Record<string, CharacterSet> = {\n standard: {\n name: 'Standard',\n description: 'Classic ASCII art character set',\n characters: ' .:-=+*#%@',\n bestFor: ['general', 'images', 'patterns'],\n },\n\n dense: {\n name: 'Dense',\n description: 'High detail character set with many gradations',\n characters: \" .'`^\\\",:;Il!i><~+_-?][}{1)(|\\\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$\",\n bestFor: ['detailed images', 'portraits', 'high contrast'],\n },\n\n minimal: {\n name: 'Minimal',\n description: 'Clean and simple with few characters',\n characters: ' .:*#',\n bestFor: ['backgrounds', 'subtle effects', 'clean aesthetic'],\n },\n\n grove: {\n name: 'Grove',\n description: 'Organic, soft characters inspired by nature',\n characters: ' ·∙•◦○◉●',\n bestFor: ['organic patterns', 'soft backgrounds', 'nature themes'],\n },\n\n dots: {\n name: 'Dots',\n description: 'Braille-like dot patterns',\n characters: ' ⋅∘∙●',\n bestFor: ['stipple effects', 'pointillism', 'dotted textures'],\n },\n\n blocks: {\n name: 'Blocks',\n description: 'Block-based characters for sharp edges',\n characters: ' ░▒▓█',\n bestFor: ['retro effects', 'pixel art', 'bold patterns'],\n },\n\n lines: {\n name: 'Lines',\n description: 'Line-based characters for directional effects',\n characters: ' -─═╌│┃',\n bestFor: ['rain effects', 'streaks', 'motion blur'],\n },\n\n stars: {\n name: 'Stars',\n description: 'Star and sparkle characters',\n characters: ' ·✧✦✫✬✯★',\n bestFor: ['sparkle effects', 'night sky', 'magical themes'],\n },\n\n nature: {\n name: 'Nature',\n description: 'Nature-themed decorative characters',\n characters: ' .~≈∿⌇☘',\n bestFor: ['decorative', 'themed effects', 'organic patterns'],\n },\n\n weather: {\n name: 'Weather',\n description: 'Weather-related symbols',\n characters: ' ·.:*❄❅❆',\n bestFor: ['snow effects', 'weather simulations', 'seasonal themes'],\n },\n\n binary: {\n name: 'Binary',\n description: 'Digital-style binary characters',\n characters: ' 01',\n bestFor: ['digital effects', 'matrix style', 'tech themes'],\n },\n\n math: {\n name: 'Math',\n description: 'Mathematical symbols',\n characters: ' +-×÷=≠≈∞',\n bestFor: ['abstract patterns', 'tech themes', 'decorative'],\n },\n};\n\n/**\n * Get a character set by name\n */\nexport function getCharacterSet(name: string): CharacterSet | undefined {\n return CHARACTER_SETS[name];\n}\n\n/**\n * Get just the characters string from a named set\n */\nexport function getCharacters(name: string): string {\n return CHARACTER_SETS[name]?.characters || CHARACTER_SETS.standard.characters;\n}\n\n/**\n * List all available character set names\n */\nexport function getCharacterSetNames(): string[] {\n return Object.keys(CHARACTER_SETS);\n}\n\n/**\n * Create a custom character set\n */\nexport function createCharacterSet(\n name: string,\n characters: string,\n description: string = '',\n bestFor: string[] = []\n): CharacterSet {\n return {\n name,\n description,\n characters,\n bestFor,\n };\n}\n\n/**\n * Validate that a character string is suitable for ASCII rendering\n * (should start with space and have at least 2 characters)\n */\nexport function validateCharacterSet(characters: string): boolean {\n if (characters.length < 2) return false;\n if (characters[0] !== ' ') return false;\n return true;\n}\n\n/**\n * Reverse a character set (for inverted brightness mapping)\n */\nexport function invertCharacters(characters: string): string {\n return characters.split('').reverse().join('');\n}\n","/**\n * Gossamer Animation Utilities\n *\n * FPS limiting, animation loop management, and timing utilities.\n */\n\n/**\n * Animation state for tracking loop execution\n */\nexport interface AnimationState {\n /** Whether animation is currently running */\n isRunning: boolean;\n /** Current animation frame ID */\n frameId: number | null;\n /** Timestamp of last frame */\n lastFrameTime: number;\n /** Frame interval in ms (derived from FPS) */\n frameInterval: number;\n /** Total elapsed time in ms */\n elapsedTime: number;\n /** Current frame count */\n frameCount: number;\n}\n\n/**\n * Options for creating an animation loop\n */\nexport interface AnimationOptions {\n /** Target frames per second (default: 30) */\n fps?: number;\n /** Callback when animation starts */\n onStart?: () => void;\n /** Callback when animation stops */\n onStop?: () => void;\n /** Callback for each frame - return false to stop */\n onFrame: (time: number, deltaTime: number, frameCount: number) => boolean | void;\n}\n\n/**\n * Create a managed animation loop with FPS limiting\n */\nexport function createAnimationLoop(options: AnimationOptions): {\n start: () => void;\n stop: () => void;\n pause: () => void;\n resume: () => void;\n getState: () => AnimationState;\n} {\n const { fps = 30, onStart, onStop, onFrame } = options;\n\n const state: AnimationState = {\n isRunning: false,\n frameId: null,\n lastFrameTime: 0,\n frameInterval: 1000 / fps,\n elapsedTime: 0,\n frameCount: 0,\n };\n\n let pausedTime = 0;\n let isPaused = false;\n\n function animate(currentTime: number): void {\n if (!state.isRunning || isPaused) return;\n\n const deltaTime = currentTime - state.lastFrameTime;\n\n if (deltaTime >= state.frameInterval) {\n state.elapsedTime += deltaTime;\n state.frameCount++;\n\n const continueAnimation = onFrame(currentTime, deltaTime, state.frameCount);\n\n if (continueAnimation === false) {\n stop();\n return;\n }\n\n // Adjust for frame timing drift\n state.lastFrameTime = currentTime - (deltaTime % state.frameInterval);\n }\n\n state.frameId = requestAnimationFrame(animate);\n }\n\n function start(): void {\n if (state.isRunning) return;\n\n state.isRunning = true;\n state.lastFrameTime = performance.now();\n state.elapsedTime = 0;\n state.frameCount = 0;\n isPaused = false;\n\n onStart?.();\n state.frameId = requestAnimationFrame(animate);\n }\n\n function stop(): void {\n state.isRunning = false;\n isPaused = false;\n\n if (state.frameId !== null) {\n cancelAnimationFrame(state.frameId);\n state.frameId = null;\n }\n\n onStop?.();\n }\n\n function pause(): void {\n if (!state.isRunning || isPaused) return;\n\n isPaused = true;\n pausedTime = performance.now();\n\n if (state.frameId !== null) {\n cancelAnimationFrame(state.frameId);\n state.frameId = null;\n }\n }\n\n function resume(): void {\n if (!state.isRunning || !isPaused) return;\n\n isPaused = false;\n // Adjust lastFrameTime to account for paused duration\n state.lastFrameTime += performance.now() - pausedTime;\n state.frameId = requestAnimationFrame(animate);\n }\n\n function getState(): AnimationState {\n return { ...state };\n }\n\n return { start, stop, pause, resume, getState };\n}\n\n/**\n * Simple throttle function for limiting function execution\n */\nexport function throttle<T extends (...args: unknown[]) => unknown>(\n fn: T,\n limit: number\n): (...args: Parameters<T>) => void {\n let lastCall = 0;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return (...args: Parameters<T>): void => {\n const now = Date.now();\n\n if (now - lastCall >= limit) {\n lastCall = now;\n fn(...args);\n } else if (!timeout) {\n timeout = setTimeout(() => {\n lastCall = Date.now();\n timeout = null;\n fn(...args);\n }, limit - (now - lastCall));\n }\n };\n}\n\n/**\n * Debounce function for delaying execution until activity stops\n */\nexport function debounce<T extends (...args: unknown[]) => unknown>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return (...args: Parameters<T>): void => {\n if (timeout) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(() => {\n timeout = null;\n fn(...args);\n }, delay);\n };\n}\n\n/**\n * Calculate actual FPS from frame times\n */\nexport function calculateFPS(frameTimes: number[], sampleSize: number = 60): number {\n if (frameTimes.length < 2) return 0;\n\n const samples = frameTimes.slice(-sampleSize);\n const totalTime = samples[samples.length - 1] - samples[0];\n const frameCount = samples.length - 1;\n\n if (totalTime <= 0) return 0;\n\n return (frameCount / totalTime) * 1000;\n}\n\n/**\n * Easing functions for smooth animations\n */\nexport const easings = {\n /** Linear - no easing */\n linear: (t: number): number => t,\n\n /** Ease in - slow start */\n easeIn: (t: number): number => t * t,\n\n /** Ease out - slow end */\n easeOut: (t: number): number => t * (2 - t),\n\n /** Ease in/out - slow start and end */\n easeInOut: (t: number): number => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),\n\n /** Sine ease in */\n sineIn: (t: number): number => 1 - Math.cos((t * Math.PI) / 2),\n\n /** Sine ease out */\n sineOut: (t: number): number => Math.sin((t * Math.PI) / 2),\n\n /** Sine ease in/out */\n sineInOut: (t: number): number => -(Math.cos(Math.PI * t) - 1) / 2,\n\n /** Bounce at end */\n bounceOut: (t: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (t < 1 / d1) {\n return n1 * t * t;\n } else if (t < 2 / d1) {\n return n1 * (t -= 1.5 / d1) * t + 0.75;\n } else if (t < 2.5 / d1) {\n return n1 * (t -= 2.25 / d1) * t + 0.9375;\n } else {\n return n1 * (t -= 2.625 / d1) * t + 0.984375;\n }\n },\n};\n\nexport type EasingFunction = (t: number) => number;\n","/**\n * Canvas Utilities\n *\n * Helper functions for canvas creation, setup, and manipulation.\n */\n\n/**\n * Options for canvas creation\n */\nexport interface CanvasOptions {\n /** Canvas width in pixels */\n width?: number;\n /** Canvas height in pixels */\n height?: number;\n /** Whether to use high DPI scaling */\n highDPI?: boolean;\n /** CSS class to add to canvas */\n className?: string;\n /** Inline styles to apply */\n style?: Partial<CSSStyleDeclaration>;\n}\n\n/**\n * Create a canvas element with optimal settings\n */\nexport function createCanvas(options: CanvasOptions = {}): HTMLCanvasElement {\n const { width = 300, height = 150, highDPI = true, className, style } = options;\n\n const canvas = document.createElement('canvas');\n\n if (highDPI) {\n const dpr = window.devicePixelRatio || 1;\n canvas.width = width * dpr;\n canvas.height = height * dpr;\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.scale(dpr, dpr);\n }\n } else {\n canvas.width = width;\n canvas.height = height;\n }\n\n if (className) {\n canvas.className = className;\n }\n\n if (style) {\n Object.assign(canvas.style, style);\n }\n\n return canvas;\n}\n\n/**\n * Get the device pixel ratio\n */\nexport function getDevicePixelRatio(): number {\n return typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n}\n\n/**\n * Resize canvas to match container dimensions\n */\nexport function resizeCanvasToContainer(\n canvas: HTMLCanvasElement,\n container: HTMLElement,\n highDPI: boolean = true\n): { width: number; height: number } {\n const rect = container.getBoundingClientRect();\n const dpr = highDPI ? getDevicePixelRatio() : 1;\n\n const width = rect.width;\n const height = rect.height;\n\n canvas.width = width * dpr;\n canvas.height = height * dpr;\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n\n if (highDPI) {\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.scale(dpr, dpr);\n }\n }\n\n return { width, height };\n}\n\n/**\n * Create an offscreen canvas for buffer rendering\n */\nexport function createOffscreenCanvas(width: number, height: number): HTMLCanvasElement | OffscreenCanvas {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n\n // Fallback for environments without OffscreenCanvas\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Clear a canvas\n */\nexport function clearCanvas(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n width: number,\n height: number,\n backgroundColor?: string\n): void {\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, width, height);\n } else {\n ctx.clearRect(0, 0, width, height);\n }\n}\n\n/**\n * Get image data from a canvas region\n */\nexport function getImageData(\n ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n x: number = 0,\n y: number = 0,\n width?: number,\n height?: number\n): ImageData {\n const canvas = ctx.canvas;\n const w = width ?? canvas.width;\n const h = height ?? canvas.height;\n\n return ctx.getImageData(x, y, w, h);\n}\n\n/**\n * Set optimal rendering context settings\n */\nexport function optimizeContext(ctx: CanvasRenderingContext2D): void {\n // Disable image smoothing for crisp ASCII rendering\n ctx.imageSmoothingEnabled = false;\n\n // Use source-over for standard compositing\n ctx.globalCompositeOperation = 'source-over';\n}\n\n/**\n * Set text rendering options for ASCII display\n */\nexport function setupTextRendering(\n ctx: CanvasRenderingContext2D,\n fontSize: number,\n fontFamily: string = 'monospace',\n color: string = '#ffffff'\n): void {\n ctx.font = `${fontSize}px ${fontFamily}`;\n ctx.textBaseline = 'top';\n ctx.textAlign = 'left';\n ctx.fillStyle = color;\n}\n\n/**\n * Measure text width for a given font configuration\n */\nexport function measureTextWidth(\n ctx: CanvasRenderingContext2D,\n text: string,\n fontSize: number,\n fontFamily: string = 'monospace'\n): number {\n const originalFont = ctx.font;\n ctx.font = `${fontSize}px ${fontFamily}`;\n const metrics = ctx.measureText(text);\n ctx.font = originalFont;\n return metrics.width;\n}\n\n/**\n * Calculate optimal cell size for a given canvas and desired columns\n */\nexport function calculateCellSize(\n canvasWidth: number,\n canvasHeight: number,\n targetCols: number\n): { cellWidth: number; cellHeight: number; cols: number; rows: number } {\n const cellWidth = Math.floor(canvasWidth / targetCols);\n // Use a typical monospace aspect ratio of ~0.6\n const cellHeight = Math.floor(cellWidth * 1.5);\n const cols = Math.floor(canvasWidth / cellWidth);\n const rows = Math.floor(canvasHeight / cellHeight);\n\n return { cellWidth, cellHeight, cols, rows };\n}\n\n/**\n * Apply a CSS blend mode to canvas compositing\n */\nexport function setBlendMode(\n ctx: CanvasRenderingContext2D,\n mode: 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'soft-light' | 'hard-light' | 'difference' | 'exclusion'\n): void {\n ctx.globalCompositeOperation = mode === 'normal' ? 'source-over' : mode;\n}\n","/**\n * Image Utilities\n *\n * Image loading, processing, and pixel manipulation for ASCII conversion.\n */\n\n/**\n * Image loading options\n */\nexport interface ImageLoadOptions {\n /** Cross-origin setting for external images */\n crossOrigin?: 'anonymous' | 'use-credentials' | '';\n /** Maximum width to scale image to */\n maxWidth?: number;\n /** Maximum height to scale image to */\n maxHeight?: number;\n /** Whether to preserve aspect ratio when scaling */\n preserveAspectRatio?: boolean;\n}\n\n/**\n * Load an image from a URL\n */\nexport function loadImage(src: string, options: ImageLoadOptions = {}): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n\n if (options.crossOrigin !== undefined) {\n img.crossOrigin = options.crossOrigin;\n }\n\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(`Failed to load image: ${src}`));\n\n img.src = src;\n });\n}\n\n/**\n * Load and scale an image to fit within bounds\n */\nexport async function loadAndScaleImage(\n src: string,\n maxWidth: number,\n maxHeight: number,\n options: ImageLoadOptions = {}\n): Promise<{ image: HTMLImageElement; width: number; height: number }> {\n const img = await loadImage(src, options);\n\n let width = img.naturalWidth;\n let height = img.naturalHeight;\n\n // Scale down if needed\n if (width > maxWidth || height > maxHeight) {\n const widthRatio = maxWidth / width;\n const heightRatio = maxHeight / height;\n const scale = Math.min(widthRatio, heightRatio);\n\n width = Math.floor(width * scale);\n height = Math.floor(height * scale);\n }\n\n return { image: img, width, height };\n}\n\n/**\n * Draw an image to a canvas and get its pixel data\n */\nexport function imageToPixelData(\n image: HTMLImageElement | HTMLCanvasElement | ImageBitmap,\n width?: number,\n height?: number\n): ImageData {\n const w = width ?? (image instanceof HTMLImageElement ? image.naturalWidth : image.width);\n const h = height ?? (image instanceof HTMLImageElement ? image.naturalHeight : image.height);\n\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context');\n }\n\n ctx.drawImage(image, 0, 0, w, h);\n return ctx.getImageData(0, 0, w, h);\n}\n\n/**\n * Extract brightness values from image data\n */\nexport function extractBrightness(\n imageData: ImageData,\n brightnessFunction: (r: number, g: number, b: number) => number = (r, g, b) => 0.21 * r + 0.72 * g + 0.07 * b\n): number[] {\n const { data, width, height } = imageData;\n const brightness: number[] = new Array(width * height);\n\n for (let i = 0; i < data.length; i += 4) {\n brightness[i / 4] = brightnessFunction(data[i], data[i + 1], data[i + 2]);\n }\n\n return brightness;\n}\n\n/**\n * Sample image data at cell-based intervals\n */\nexport function sampleImageCells(\n imageData: ImageData,\n cellWidth: number,\n cellHeight: number,\n brightnessFunction: (r: number, g: number, b: number) => number = (r, g, b) => 0.21 * r + 0.72 * g + 0.07 * b\n): { brightness: number; color: string }[][] {\n const { data, width, height } = imageData;\n const cols = Math.ceil(width / cellWidth);\n const rows = Math.ceil(height / cellHeight);\n\n const result: { brightness: number; color: string }[][] = [];\n\n for (let row = 0; row < rows; row++) {\n result[row] = [];\n\n for (let col = 0; col < cols; col++) {\n const cellData = sampleCell(data, width, col * cellWidth, row * cellHeight, cellWidth, cellHeight);\n const brightness = brightnessFunction(cellData.r, cellData.g, cellData.b);\n\n result[row][col] = {\n brightness,\n color: `rgb(${Math.round(cellData.r)}, ${Math.round(cellData.g)}, ${Math.round(cellData.b)})`,\n };\n }\n }\n\n return result;\n}\n\n/**\n * Sample average color from a cell region\n */\nfunction sampleCell(\n data: Uint8ClampedArray,\n imageWidth: number,\n startX: number,\n startY: number,\n cellWidth: number,\n cellHeight: number\n): { r: number; g: number; b: number; a: number } {\n let totalR = 0;\n let totalG = 0;\n let totalB = 0;\n let totalA = 0;\n let count = 0;\n\n for (let y = startY; y < startY + cellHeight; y++) {\n for (let x = startX; x < startX + cellWidth; x++) {\n const px = (y * imageWidth + x) * 4;\n\n if (px >= 0 && px + 3 < data.length) {\n totalR += data[px];\n totalG += data[px + 1];\n totalB += data[px + 2];\n totalA += data[px + 3];\n count++;\n }\n }\n }\n\n if (count === 0) {\n return { r: 0, g: 0, b: 0, a: 0 };\n }\n\n return {\n r: totalR / count,\n g: totalG / count,\n b: totalB / count,\n a: totalA / count,\n };\n}\n\n/**\n * Convert RGB to hex color string\n */\nexport function rgbToHex(r: number, g: number, b: number): string {\n const toHex = (n: number) =>\n Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .padStart(2, '0');\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\n/**\n * Convert hex color to RGB\n */\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16),\n }\n : null;\n}\n\n/**\n * Adjust image brightness\n */\nexport function adjustBrightness(imageData: ImageData, amount: number): ImageData {\n const { data, width, height } = imageData;\n const adjusted = new Uint8ClampedArray(data.length);\n\n for (let i = 0; i < data.length; i += 4) {\n adjusted[i] = Math.min(255, Math.max(0, data[i] + amount));\n adjusted[i + 1] = Math.min(255, Math.max(0, data[i + 1] + amount));\n adjusted[i + 2] = Math.min(255, Math.max(0, data[i + 2] + amount));\n adjusted[i + 3] = data[i + 3];\n }\n\n return new ImageData(adjusted, width, height);\n}\n\n/**\n * Adjust image contrast\n */\nexport function adjustContrast(imageData: ImageData, amount: number): ImageData {\n const { data, width, height } = imageData;\n const adjusted = new Uint8ClampedArray(data.length);\n const factor = (259 * (amount + 255)) / (255 * (259 - amount));\n\n for (let i = 0; i < data.length; i += 4) {\n adjusted[i] = Math.min(255, Math.max(0, factor * (data[i] - 128) + 128));\n adjusted[i + 1] = Math.min(255, Math.max(0, factor * (data[i + 1] - 128) + 128));\n adjusted[i + 2] = Math.min(255, Math.max(0, factor * (data[i + 2] - 128) + 128));\n adjusted[i + 3] = data[i + 3];\n }\n\n return new ImageData(adjusted, width, height);\n}\n\n/**\n * Invert image colors\n */\nexport function invertColors(imageData: ImageData): ImageData {\n const { data, width, height } = imageData;\n const inverted = new Uint8ClampedArray(data.length);\n\n for (let i = 0; i < data.length; i += 4) {\n inverted[i] = 255 - data[i];\n inverted[i + 1] = 255 - data[i + 1];\n inverted[i + 2] = 255 - data[i + 2];\n inverted[i + 3] = data[i + 3];\n }\n\n return new ImageData(inverted, width, height);\n}\n\n/**\n * Convert image to grayscale\n */\nexport function toGrayscale(imageData: ImageData): ImageData {\n const { data, width, height } = imageData;\n const grayscale = new Uint8ClampedArray(data.length);\n\n for (let i = 0; i < data.length; i += 4) {\n const gray = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n grayscale[i] = gray;\n grayscale[i + 1] = gray;\n grayscale[i + 2] = gray;\n grayscale[i + 3] = data[i + 3];\n }\n\n return new ImageData(grayscale, width, height);\n}\n","/**\n * Performance Utilities\n *\n * Visibility detection, resource management, and optimization helpers.\n */\n\n/**\n * Visibility observer callback type\n */\nexport type VisibilityCallback = (isVisible: boolean, entry: IntersectionObserverEntry) => void;\n\n/**\n * Create an IntersectionObserver for visibility-based animation control\n *\n * @param element - Element to observe\n * @param callback - Called when visibility changes\n * @param threshold - Visibility threshold (0-1, default: 0.1)\n * @returns Cleanup function to disconnect observer\n */\nexport function createVisibilityObserver(\n element: Element,\n callback: VisibilityCallback,\n threshold: number = 0.1\n): () => void {\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n callback(entry.isIntersecting, entry);\n }\n },\n { threshold }\n );\n\n observer.observe(element);\n\n return () => {\n observer.disconnect();\n };\n}\n\n/**\n * Create a ResizeObserver for responsive canvas sizing\n *\n * @param element - Element to observe\n * @param callback - Called on resize with new dimensions\n * @param debounceMs - Debounce delay in ms (default: 100)\n * @returns Cleanup function to disconnect observer\n */\nexport function createResizeObserver(\n element: Element,\n callback: (width: number, height: number, entry: ResizeObserverEntry) => void,\n debounceMs: number = 100\n): () => void {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n const observer = new ResizeObserver((entries) => {\n if (timeout) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(() => {\n const entry = entries[0];\n if (entry) {\n const { width, height } = entry.contentRect;\n callback(width, height, entry);\n }\n }, debounceMs);\n });\n\n observer.observe(element);\n\n return () => {\n if (timeout) {\n clearTimeout(timeout);\n }\n observer.disconnect();\n };\n}\n\n/**\n * Check if the user prefers reduced motion\n */\nexport function prefersReducedMotion(): boolean {\n if (typeof window === 'undefined') return false;\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/**\n * Create a listener for reduced motion preference changes\n *\n * @param callback - Called when preference changes\n * @returns Cleanup function to remove listener\n */\nexport function onReducedMotionChange(callback: (prefersReduced: boolean) => void): () => void {\n if (typeof window === 'undefined') {\n return () => {};\n }\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n\n const handler = (event: MediaQueryListEvent) => {\n callback(event.matches);\n };\n\n mediaQuery.addEventListener('change', handler);\n\n // Call immediately with current value\n callback(mediaQuery.matches);\n\n return () => {\n mediaQuery.removeEventListener('change', handler);\n };\n}\n\n/**\n * Check if the browser is in a low-power mode or has reduced capabilities\n */\nexport function isLowPowerMode(): boolean {\n // Check for battery API (if available)\n if (typeof navigator !== 'undefined' && 'getBattery' in navigator) {\n // Battery API is async, so this is a simplified check\n // Real implementation would need to be async\n return false;\n }\n\n // Fallback: check for hardware concurrency\n if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) {\n return navigator.hardwareConcurrency <= 2;\n }\n\n return false;\n}\n\n/**\n * Get recommended FPS based on device capabilities\n */\nexport function getRecommendedFPS(): number {\n if (prefersReducedMotion()) {\n return 0; // No animation\n }\n\n if (isLowPowerMode()) {\n return 15; // Low power mode\n }\n\n // Default for capable devices\n return 30;\n}\n\n/**\n * Performance monitoring for debugging\n */\nexport interface PerformanceMetrics {\n fps: number;\n frameTime: number;\n droppedFrames: number;\n}\n\n/**\n * Create a simple FPS counter\n */\nexport function createFPSCounter(): {\n tick: () => void;\n getFPS: () => number;\n getMetrics: () => PerformanceMetrics;\n reset: () => void;\n} {\n const frameTimes: number[] = [];\n const maxSamples = 60;\n let droppedFrames = 0;\n let lastFrameTime = performance.now();\n\n function tick(): void {\n const now = performance.now();\n const delta = now - lastFrameTime;\n lastFrameTime = now;\n\n frameTimes.push(now);\n\n if (frameTimes.length > maxSamples) {\n frameTimes.shift();\n }\n\n // Count dropped frames (assuming 60fps target, frames taking >20ms are \"dropped\")\n if (delta > 20) {\n droppedFrames += Math.floor(delta / 16.67) - 1;\n }\n }\n\n function getFPS(): number {\n if (frameTimes.length < 2) return 0;\n\n const oldest = frameTimes[0];\n const newest = frameTimes[frameTimes.length - 1];\n const elapsed = newest - oldest;\n\n if (elapsed === 0) return 0;\n\n return ((frameTimes.length - 1) / elapsed) * 1000;\n }\n\n function getMetrics(): PerformanceMetrics {\n const fps = getFPS();\n const frameTime = fps > 0 ? 1000 / fps : 0;\n\n return {\n fps: Math.round(fps * 10) / 10,\n frameTime: Math.round(frameTime * 100) / 100,\n droppedFrames,\n };\n }\n\n function reset(): void {\n frameTimes.length = 0;\n droppedFrames = 0;\n lastFrameTime = performance.now();\n }\n\n return { tick, getFPS, getMetrics, reset };\n}\n\n/**\n * Request idle callback with fallback\n */\nexport function requestIdleCallback(\n callback: () => void,\n options?: { timeout?: number }\n): number {\n // Use globalThis for cross-environment compatibility\n const global = globalThis as typeof globalThis & {\n requestIdleCallback?: typeof window.requestIdleCallback;\n setTimeout: typeof setTimeout;\n };\n\n if (typeof global.requestIdleCallback === 'function') {\n return global.requestIdleCallback(callback, options);\n }\n\n // Fallback using setTimeout\n return global.setTimeout(callback, options?.timeout ?? 1) as unknown as number;\n}\n\n/**\n * Cancel idle callback with fallback\n */\nexport function cancelIdleCallback(id: number): void {\n // Use globalThis for cross-environment compatibility\n const global = globalThis as typeof globalThis & {\n cancelIdleCallback?: typeof window.cancelIdleCallback;\n clearTimeout: typeof clearTimeout;\n };\n\n if (typeof global.cancelIdleCallback === 'function') {\n global.cancelIdleCallback(id);\n } else {\n global.clearTimeout(id);\n }\n}\n\n/**\n * Check if we're running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Check if Canvas is supported\n */\nexport function isCanvasSupported(): boolean {\n if (!isBrowser()) return false;\n\n const canvas = document.createElement('canvas');\n return !!(canvas.getContext && canvas.getContext('2d'));\n}\n\n/**\n * Check if OffscreenCanvas is supported\n */\nexport function isOffscreenCanvasSupported(): boolean {\n return typeof OffscreenCanvas !== 'undefined';\n}\n","/**\n * Gossamer - ASCII Visual Effects Library\n *\n * Threads of light. Delicate textures woven through your space.\n *\n * @packageDocumentation\n */\n\n// =============================================================================\n// Core Types\n// =============================================================================\n\n/**\n * Core configuration for ASCII rendering\n */\nexport interface GossamerConfig {\n /** Character set for ASCII rendering (light to dark) */\n characters?: string;\n /** Cell width in pixels */\n cellWidth?: number;\n /** Cell height in pixels */\n cellHeight?: number;\n /** Foreground color */\n color?: string;\n /** Background color (transparent if not set) */\n backgroundColor?: string;\n /** Font family for ASCII characters */\n fontFamily?: string;\n /** Enable animation loop */\n animate?: boolean;\n /** Target FPS for animation */\n fps?: number;\n}\n\n/**\n * Preset configuration for effects\n */\nexport interface PresetConfig {\n /** Preset display name */\n name: string;\n /** Preset description */\n description: string;\n /** Character set */\n characters: string;\n /** Pattern type */\n pattern: 'perlin' | 'waves' | 'static' | 'ripple' | 'fbm';\n /** Pattern frequency */\n frequency: number;\n /** Pattern amplitude */\n amplitude: number;\n /** Animation speed */\n speed: number;\n /** Default opacity */\n opacity: number;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Default character set ordered from light to dark\n */\nexport const DEFAULT_CHARACTERS = ' .:-=+*#%@';\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<GossamerConfig> = {\n characters: DEFAULT_CHARACTERS,\n cellWidth: 8,\n cellHeight: 12,\n color: '#ffffff',\n backgroundColor: '',\n fontFamily: 'monospace',\n animate: false,\n fps: 30,\n};\n\n// =============================================================================\n// Core Functions\n// =============================================================================\n\n/**\n * Calculate brightness from RGB values using luminance formula\n * Uses the standard luminance coefficients: 0.21 R + 0.72 G + 0.07 B\n */\nexport function calculateBrightness(r: number, g: number, b: number): number {\n return 0.21 * r + 0.72 * g + 0.07 * b;\n}\n\n/**\n * Map a brightness value (0-255) to an ASCII character\n */\nexport function brightnessToChar(\n brightness: number,\n characters: string = DEFAULT_CHARACTERS\n): string {\n const index = Math.floor((brightness / 255) * (characters.length - 1));\n return characters[Math.min(index, characters.length - 1)];\n}\n\n// =============================================================================\n// Module Exports\n// =============================================================================\n\n// Renderer\nexport { GossamerRenderer } from './renderer';\nexport type { RenderConfig } from './renderer';\n\n// Patterns\nexport {\n perlinNoise2D,\n fbmNoise,\n wavePattern,\n ripplePattern,\n staticNoise,\n seededNoise2D,\n generateBrightnessGrid,\n gridToImageData,\n DEFAULT_PATTERN_CONFIG,\n} from './patterns';\nexport type { PatternConfig, PatternType } from './patterns';\n\n// Characters\nexport {\n CHARACTER_SETS,\n getCharacterSet,\n getCharacters,\n getCharacterSetNames,\n createCharacterSet,\n validateCharacterSet,\n invertCharacters,\n} from './characters';\nexport type { CharacterSet } from './characters';\n\n// Animation\nexport {\n createAnimationLoop,\n throttle,\n debounce,\n calculateFPS,\n easings,\n} from './animation';\nexport type { AnimationState, AnimationOptions, EasingFunction } from './animation';\n\n// Canvas Utilities\nexport {\n createCanvas,\n getDevicePixelRatio,\n resizeCanvasToContainer,\n createOffscreenCanvas,\n clearCanvas,\n getImageData,\n optimizeContext,\n setupTextRendering,\n measureTextWidth,\n calculateCellSize,\n setBlendMode,\n} from './utils/canvas';\nexport type { CanvasOptions } from './utils/canvas';\n\n// Image Utilities\nexport {\n loadImage,\n loadAndScaleImage,\n imageToPixelData,\n extractBrightness,\n sampleImageCells,\n rgbToHex,\n hexToRgb,\n adjustBrightness,\n adjustContrast,\n invertColors,\n toGrayscale,\n} from './utils/image';\nexport type { ImageLoadOptions } from './utils/image';\n\n// Performance Utilities\nexport {\n createVisibilityObserver,\n createResizeObserver,\n prefersReducedMotion,\n onReducedMotionChange,\n isLowPowerMode,\n getRecommendedFPS,\n createFPSCounter,\n requestIdleCallback,\n cancelIdleCallback,\n isBrowser,\n isCanvasSupported,\n isOffscreenCanvasSupported,\n} from './utils/performance';\nexport type { VisibilityCallback, PerformanceMetrics } from './utils/performance';\n\n// =============================================================================\n// Version\n// =============================================================================\n\n/**\n * Gossamer version\n */\nexport const VERSION = '0.1.0';\n"],"names":["DEFAULT_CHARACTERS","calculateBrightness"],"mappings":"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EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC9F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAI;AAAA,EAAI;AAAA,EAC7F;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAC5F;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAG;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC7F;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;AAAA,EAAG;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAI;AAAA,EAAI;AAAA,EAAK;AAAA,EAAK;AAAA,EAAI;AAAA,EAAK;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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gossamer Pattern Generators
|
|
3
|
+
*
|
|
4
|
+
* Provides noise and pattern generation functions for ambient ASCII effects.
|
|
5
|
+
* Includes Perlin noise, wave patterns, and static noise.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for pattern generation
|
|
9
|
+
*/
|
|
10
|
+
export interface PatternConfig {
|
|
11
|
+
/** Pattern scale - higher values create finer detail */
|
|
12
|
+
frequency: number;
|
|
13
|
+
/** Pattern intensity multiplier */
|
|
14
|
+
amplitude: number;
|
|
15
|
+
/** Animation speed multiplier */
|
|
16
|
+
speed: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Default pattern configuration
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_PATTERN_CONFIG: PatternConfig;
|
|
22
|
+
/**
|
|
23
|
+
* 2D Perlin noise function
|
|
24
|
+
*
|
|
25
|
+
* @param x - X coordinate
|
|
26
|
+
* @param y - Y coordinate
|
|
27
|
+
* @returns Noise value between -1 and 1
|
|
28
|
+
*/
|
|
29
|
+
export declare function perlinNoise2D(x: number, y: number): number;
|
|
30
|
+
/**
|
|
31
|
+
* Fractal Brownian Motion (fBm) using Perlin noise
|
|
32
|
+
* Creates more organic-looking noise by layering multiple octaves
|
|
33
|
+
*
|
|
34
|
+
* @param x - X coordinate
|
|
35
|
+
* @param y - Y coordinate
|
|
36
|
+
* @param octaves - Number of noise layers (default: 4)
|
|
37
|
+
* @param persistence - Amplitude decay per octave (default: 0.5)
|
|
38
|
+
* @returns Noise value between -1 and 1
|
|
39
|
+
*/
|
|
40
|
+
export declare function fbmNoise(x: number, y: number, octaves?: number, persistence?: number): number;
|
|
41
|
+
/**
|
|
42
|
+
* Wave pattern generator
|
|
43
|
+
*
|
|
44
|
+
* @param x - X coordinate
|
|
45
|
+
* @param y - Y coordinate
|
|
46
|
+
* @param time - Time value for animation
|
|
47
|
+
* @param config - Pattern configuration
|
|
48
|
+
* @returns Value between -1 and 1
|
|
49
|
+
*/
|
|
50
|
+
export declare function wavePattern(x: number, y: number, time: number, config?: PatternConfig): number;
|
|
51
|
+
/**
|
|
52
|
+
* Ripple pattern (concentric waves from center)
|
|
53
|
+
*
|
|
54
|
+
* @param x - X coordinate
|
|
55
|
+
* @param y - Y coordinate
|
|
56
|
+
* @param centerX - Ripple center X
|
|
57
|
+
* @param centerY - Ripple center Y
|
|
58
|
+
* @param time - Time value for animation
|
|
59
|
+
* @param config - Pattern configuration
|
|
60
|
+
* @returns Value between -1 and 1
|
|
61
|
+
*/
|
|
62
|
+
export declare function ripplePattern(x: number, y: number, centerX: number, centerY: number, time: number, config?: PatternConfig): number;
|
|
63
|
+
/**
|
|
64
|
+
* Static noise generator (random values)
|
|
65
|
+
*
|
|
66
|
+
* @param seed - Optional seed for reproducible noise
|
|
67
|
+
* @returns Value between 0 and 1
|
|
68
|
+
*/
|
|
69
|
+
export declare function staticNoise(seed?: number): number;
|
|
70
|
+
/**
|
|
71
|
+
* Seeded 2D noise for reproducible patterns
|
|
72
|
+
*
|
|
73
|
+
* @param x - X coordinate
|
|
74
|
+
* @param y - Y coordinate
|
|
75
|
+
* @param seed - Seed value
|
|
76
|
+
* @returns Value between 0 and 1
|
|
77
|
+
*/
|
|
78
|
+
export declare function seededNoise2D(x: number, y: number, seed?: number): number;
|
|
79
|
+
/**
|
|
80
|
+
* Generate a brightness grid for pattern rendering
|
|
81
|
+
*
|
|
82
|
+
* @param cols - Number of columns
|
|
83
|
+
* @param rows - Number of rows
|
|
84
|
+
* @param pattern - Pattern type
|
|
85
|
+
* @param time - Current time in seconds
|
|
86
|
+
* @param config - Pattern configuration
|
|
87
|
+
* @returns 2D array of brightness values (0-255)
|
|
88
|
+
*/
|
|
89
|
+
export declare function generateBrightnessGrid(cols: number, rows: number, pattern: 'perlin' | 'waves' | 'static' | 'ripple' | 'fbm', time?: number, config?: PatternConfig): number[][];
|
|
90
|
+
/**
|
|
91
|
+
* Generate ImageData from a brightness grid
|
|
92
|
+
*
|
|
93
|
+
* @param grid - 2D array of brightness values
|
|
94
|
+
* @param cellWidth - Width of each cell
|
|
95
|
+
* @param cellHeight - Height of each cell
|
|
96
|
+
* @returns ImageData object
|
|
97
|
+
*/
|
|
98
|
+
export declare function gridToImageData(grid: number[][], cellWidth: number, cellHeight: number): ImageData;
|
|
99
|
+
export type PatternType = 'perlin' | 'waves' | 'static' | 'ripple' | 'fbm';
|
|
100
|
+
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAIpC,CAAC;AAkDF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAwB1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,MAAU,EAAE,WAAW,GAAE,MAAY,GAAG,MAAM,CAcrG;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,aAAsC,GAC7C,MAAM,CAOR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,aAAsC,GAC7C,MAAM,CAOR;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU,GAAG,MAAM,CAG5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,EACzD,IAAI,GAAE,MAAU,EAChB,MAAM,GAAE,aAAsC,GAC7C,MAAM,EAAE,EAAE,CAiDZ;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,CAyBlG;AAED,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gossamer Core Renderer
|
|
3
|
+
*
|
|
4
|
+
* Canvas-based ASCII rendering engine. Converts image data to ASCII characters
|
|
5
|
+
* by mapping brightness values to a character set.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for the Gossamer renderer
|
|
9
|
+
*/
|
|
10
|
+
export interface RenderConfig {
|
|
11
|
+
/** Canvas element to render to */
|
|
12
|
+
canvas: HTMLCanvasElement;
|
|
13
|
+
/** Character set ordered from light to dark */
|
|
14
|
+
characters: string;
|
|
15
|
+
/** Width of each character cell in pixels */
|
|
16
|
+
cellWidth: number;
|
|
17
|
+
/** Height of each character cell in pixels */
|
|
18
|
+
cellHeight: number;
|
|
19
|
+
/** Color for rendering characters */
|
|
20
|
+
color: string;
|
|
21
|
+
/** Background color (empty string for transparent) */
|
|
22
|
+
backgroundColor: string;
|
|
23
|
+
/** Font family */
|
|
24
|
+
fontFamily: string;
|
|
25
|
+
/** Custom brightness calculation function */
|
|
26
|
+
brightnessFunction: (r: number, g: number, b: number) => number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Core ASCII renderer class
|
|
30
|
+
*
|
|
31
|
+
* Handles all canvas rendering operations for ASCII effects.
|
|
32
|
+
* Supports both static rendering and animation loops.
|
|
33
|
+
*/
|
|
34
|
+
export declare class GossamerRenderer {
|
|
35
|
+
private ctx;
|
|
36
|
+
private config;
|
|
37
|
+
private animationId;
|
|
38
|
+
private lastFrameTime;
|
|
39
|
+
private isRunning;
|
|
40
|
+
constructor(canvas: HTMLCanvasElement, config?: Partial<Omit<RenderConfig, 'canvas'>>);
|
|
41
|
+
/**
|
|
42
|
+
* Set up the canvas with optimal rendering settings
|
|
43
|
+
*/
|
|
44
|
+
private setupCanvas;
|
|
45
|
+
/**
|
|
46
|
+
* Update the renderer configuration
|
|
47
|
+
*/
|
|
48
|
+
updateConfig(config: Partial<Omit<RenderConfig, 'canvas'>>): void;
|
|
49
|
+
/**
|
|
50
|
+
* Resize the canvas to match new dimensions
|
|
51
|
+
*/
|
|
52
|
+
resize(width: number, height: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get the current canvas dimensions
|
|
55
|
+
*/
|
|
56
|
+
getDimensions(): {
|
|
57
|
+
width: number;
|
|
58
|
+
height: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Calculate the number of cells that fit in the canvas
|
|
62
|
+
*/
|
|
63
|
+
getCellCount(): {
|
|
64
|
+
cols: number;
|
|
65
|
+
rows: number;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Clear the canvas
|
|
69
|
+
*/
|
|
70
|
+
clear(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Render a single frame from image data
|
|
73
|
+
*/
|
|
74
|
+
renderFrame(imageData: ImageData): void;
|
|
75
|
+
/**
|
|
76
|
+
* Render ASCII from a brightness grid (for pattern-based rendering)
|
|
77
|
+
*/
|
|
78
|
+
renderFromBrightnessGrid(grid: number[][]): void;
|
|
79
|
+
/**
|
|
80
|
+
* Render ASCII with per-cell colors (for colored image rendering)
|
|
81
|
+
*/
|
|
82
|
+
renderWithColors(data: Array<{
|
|
83
|
+
char: string;
|
|
84
|
+
color: string;
|
|
85
|
+
x: number;
|
|
86
|
+
y: number;
|
|
87
|
+
}>): void;
|
|
88
|
+
/**
|
|
89
|
+
* Calculate average brightness for a cell region
|
|
90
|
+
*/
|
|
91
|
+
private getCellBrightness;
|
|
92
|
+
/**
|
|
93
|
+
* Start an animation loop with FPS limiting
|
|
94
|
+
*/
|
|
95
|
+
startAnimation(updateFn: (time: number, deltaTime: number) => ImageData | number[][], fps?: number): void;
|
|
96
|
+
/**
|
|
97
|
+
* Stop the animation loop
|
|
98
|
+
*/
|
|
99
|
+
stopAnimation(): void;
|
|
100
|
+
/**
|
|
101
|
+
* Check if animation is currently running
|
|
102
|
+
*/
|
|
103
|
+
isAnimating(): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Pause animation (can be resumed)
|
|
106
|
+
*/
|
|
107
|
+
pause(): void;
|
|
108
|
+
/**
|
|
109
|
+
* Clean up and destroy the renderer
|
|
110
|
+
*/
|
|
111
|
+
destroy(): void;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,kBAAkB,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACjE;AAeD;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,SAAS,CAAkB;gBAEvB,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAM;IAgBzF;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,GAAG,IAAI;IAKjE;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAO3C;;OAEG;IACH,aAAa,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAOlD;;OAEG;IACH,YAAY,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAU9C;;OAEG;IACH,KAAK,IAAI,IAAI;IAWb;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAoBvC;;OAEG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAmBhD;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAW1F;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;IACH,cAAc,CACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,MAAM,EAAE,EAAE,EACrE,GAAG,GAAE,MAAW,GACf,IAAI;IAgCP;;OAEG;IACH,aAAa,IAAI,IAAI;IAQrB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
|
package/dist/style.css
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
|
|
2
|
+
.gossamer-clouds.svelte-sqd1fq {
|
|
3
|
+
position: absolute;
|
|
4
|
+
inset: 0;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
pointer-events: none;
|
|
9
|
+
z-index: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.gossamer-canvas.svelte-sqd1fq {
|
|
13
|
+
display: block;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 100%;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.gossamer-image.svelte-1v5c3d1 {
|
|
19
|
+
position: relative;
|
|
20
|
+
display: inline-block;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.gossamer-image.hoverable.svelte-1v5c3d1 {
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.gossamer-canvas.svelte-1v5c3d1 {
|
|
29
|
+
display: block;
|
|
30
|
+
opacity: 1;
|
|
31
|
+
transition-property: opacity;
|
|
32
|
+
transition-timing-function: ease-in-out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.gossamer-canvas.hidden.svelte-1v5c3d1 {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.gossamer-original.svelte-1v5c3d1 {
|
|
40
|
+
position: absolute;
|
|
41
|
+
inset: 0;
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100%;
|
|
44
|
+
object-fit: cover;
|
|
45
|
+
opacity: 0;
|
|
46
|
+
transition-property: opacity;
|
|
47
|
+
transition-timing-function: ease-in-out;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.gossamer-original.visible.svelte-1v5c3d1 {
|
|
51
|
+
opacity: 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.gossamer-image-loading.svelte-1v5c3d1,
|
|
55
|
+
.gossamer-image-error.svelte-1v5c3d1 {
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
justify-content: center;
|
|
59
|
+
width: 100%;
|
|
60
|
+
height: 100%;
|
|
61
|
+
min-height: 100px;
|
|
62
|
+
color: currentColor;
|
|
63
|
+
opacity: 0.5;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.gossamer-image-error.svelte-1v5c3d1 {
|
|
67
|
+
color: #ef4444;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.gossamer-text.svelte-fd3qw5 {
|
|
71
|
+
position: relative;
|
|
72
|
+
display: inline-block;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.gossamer-canvas.svelte-fd3qw5 {
|
|
76
|
+
display: block;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.gossamer-text-sr.svelte-fd3qw5 {
|
|
80
|
+
position: absolute;
|
|
81
|
+
width: 1px;
|
|
82
|
+
height: 1px;
|
|
83
|
+
padding: 0;
|
|
84
|
+
margin: -1px;
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
clip: rect(0, 0, 0, 0);
|
|
87
|
+
white-space: nowrap;
|
|
88
|
+
border: 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.gossamer-overlay.svelte-1oexqwo {
|
|
92
|
+
position: absolute;
|
|
93
|
+
inset: 0;
|
|
94
|
+
width: 100%;
|
|
95
|
+
height: 100%;
|
|
96
|
+
overflow: hidden;
|
|
97
|
+
pointer-events: none;
|
|
98
|
+
z-index: 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.gossamer-canvas.svelte-1oexqwo {
|
|
102
|
+
display: block;
|
|
103
|
+
width: 100%;
|
|
104
|
+
height: 100%;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.gossamer-border.svelte-qe7ze6 {
|
|
108
|
+
position: relative;
|
|
109
|
+
display: block;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.gossamer-border-canvas.svelte-qe7ze6 {
|
|
113
|
+
position: absolute;
|
|
114
|
+
inset: 0;
|
|
115
|
+
width: 100%;
|
|
116
|
+
height: 100%;
|
|
117
|
+
pointer-events: none;
|
|
118
|
+
z-index: 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.gossamer-border-content.svelte-qe7ze6 {
|
|
122
|
+
position: relative;
|
|
123
|
+
z-index: 1;
|
|
124
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gossamer - Svelte 5 Components
|
|
3
|
+
*
|
|
4
|
+
* ASCII visual effects components for Svelte applications.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export { default as GossamerClouds } from './GossamerClouds.svelte';
|
|
9
|
+
export { default as GossamerImage } from './GossamerImage.svelte';
|
|
10
|
+
export { default as GossamerText } from './GossamerText.svelte';
|
|
11
|
+
export { default as GossamerOverlay } from './GossamerOverlay.svelte';
|
|
12
|
+
export { default as GossamerBorder } from './GossamerBorder.svelte';
|
|
13
|
+
export type { GossamerCloudsProps } from './GossamerClouds.svelte';
|
|
14
|
+
export type { GossamerImageProps } from './GossamerImage.svelte';
|
|
15
|
+
export type { GossamerTextProps } from './GossamerText.svelte';
|
|
16
|
+
export type { GossamerOverlayProps, BlendMode } from './GossamerOverlay.svelte';
|
|
17
|
+
export type { GossamerBorderProps, BorderStyle } from './GossamerBorder.svelte';
|
|
18
|
+
export { PRESETS, grovePresets, seasonalPresets, ambientPresets, getPreset, getPresetNames, getPresetsByCategory, } from './presets';
|
|
19
|
+
export { type GossamerConfig, type PresetConfig, type PatternConfig, type PatternType, type CharacterSet, DEFAULT_CHARACTERS, DEFAULT_CONFIG, CHARACTER_SETS, calculateBrightness, brightnessToChar, getCharacterSet, getCharacters, getCharacterSetNames, invertCharacters, prefersReducedMotion, VERSION, } from '../index';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAMpE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAChF,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMhF,OAAO,EACL,OAAO,EACP,YAAY,EACZ,eAAe,EACf,cAAc,EACd,SAAS,EACT,cAAc,EACd,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAMnB,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EAGjB,kBAAkB,EAClB,cAAc,EACd,cAAc,EAGd,mBAAmB,EACnB,gBAAgB,EAGhB,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAGhB,oBAAoB,EAGpB,OAAO,GACR,MAAM,UAAU,CAAC"}
|