feat(export): add export options (PNG, text, HTML)

This commit is contained in:
syntaxbullet
2026-02-09 22:37:53 +01:00
parent a137a98377
commit ea05b814b4
5 changed files with 289 additions and 17 deletions

View File

@@ -3,25 +3,13 @@
* Manages state, render loop, and grid calculations.
*/
import { CHAR_SETS, type CharSetKey, type AsciiOptions } from './ascii-shared';
import { CHAR_SETS, type CharSetKey, type AsciiOptions, type AsciiSettings } from './ascii-shared';
import { WebGLAsciiRenderer, type RenderOptions } from './webgl-ascii';
import { AsciiExporter } from './ascii-exporter';
// ============= Types =============
export interface AsciiSettings {
exposure: number;
contrast: number;
saturation: number;
gamma: number;
invert: boolean;
color: boolean;
dither: number;
denoise: boolean;
edgeMode: number;
overlayStrength: number;
resolution: number;
charSet: CharSetKey;
}
export interface GridCache {
widthCols: number;
@@ -426,6 +414,35 @@ export class AsciiController {
}
}
// ============= Export =============
savePNG(): void {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
AsciiExporter.downloadPNG(this.canvas, `ascii-art-${timestamp}.png`);
}
async copyText(): Promise<void> {
if (!this.cachedGrid.imgEl) return;
const text = AsciiExporter.generateText(
this.cachedGrid.imgEl,
this.settings,
this.cachedGrid.widthCols,
Math.floor(this.cachedGrid.heightRows)
);
await AsciiExporter.copyToClipboard(text);
}
async copyHTML(): Promise<void> {
if (!this.cachedGrid.imgEl) return;
const html = AsciiExporter.generateHTML(
this.cachedGrid.imgEl,
this.settings,
this.cachedGrid.widthCols,
Math.floor(this.cachedGrid.heightRows)
);
await AsciiExporter.copyToClipboard(html);
}
// ============= Utilities =============
private resolveImage(src: string): Promise<HTMLImageElement> {