UNPKG

gif-tools

Version:

A robust, zero-dependency TypeScript library for creating GIF files with support for both static and animated GIFs. Built with modern TypeScript features and designed to work in both Node.js and browser environments.

406 lines (405 loc) 13 kB
/** * GIF Result Wrapper * * Provides a rich wrapper around GIF binary data with convenient methods for * output in various formats across different environments (Node.js and browser). * This class abstracts platform differences and provides a unified API. */ /** * Rich wrapper around GIF binary data with cross-platform output methods. * * The GifResult class provides convenient methods for outputting GIF data in various * formats, with automatic platform detection and graceful fallbacks. Methods adapt * to the runtime environment (Node.js vs browser) to provide the most appropriate * output format. * * @example * ```typescript * import { createSolidColorGif } from 'gif-tools'; * * const gif = createSolidColorGif(100, 100, { red: 255, green: 0, blue: 0 }); * * // Raw data (works everywhere) * const data = gif.toUint8Array(); * * // Browser usage * const dataUrl = gif.toDataURL(); * document.body.innerHTML = `<img src="${dataUrl}">`; * gif.download('red-square.gif'); * * // Node.js usage * await gif.saveToFile('output.gif'); * const buffer = gif.toBuffer(); // Returns Node.js Buffer * ``` * * @example * ```typescript * // Properties and utilities * console.log(`GIF size: ${gif.sizeFormatted}`); // "2.1 KB" * console.log(`MIME type: ${gif.mimeType}`); // "image/gif" * console.log(`Valid GIF: ${gif.isValidGif()}`); // true * * // Get comprehensive info * const info = gif.getInfo(); * console.log(info); // { size, mimeType, extension, version, etc. } * ``` */ export declare class GifResult { private readonly data; /** * Creates a new GifResult wrapper around binary GIF data. * * @param data - Binary GIF data as Uint8Array * @throws {GifValidationError} When data is not a valid Uint8Array * * @example * ```typescript * const gifData = new Uint8Array([0x47, 0x49, 0x46, ...]); // GIF data * const result = new GifResult(gifData); * ``` */ constructor(data: Uint8Array); /** * Returns the raw GIF data as Uint8Array. * * This method always returns a Uint8Array and works in all environments. * Use this when you need the raw binary data or when working with APIs * that expect Uint8Array input. * * @returns The GIF data as Uint8Array * * @example * ```typescript * const gif = createSolidColorGif(100, 100, { red: 255, green: 0, blue: 0 }); * const data = gif.toUint8Array(); * * // Use with other APIs * await fetch('/upload', { * method: 'POST', * body: data, * headers: { 'Content-Type': 'image/gif' } * }); * ``` */ toUint8Array(): Uint8Array; /** * Returns the GIF data as Buffer (Node.js) or Uint8Array (browser). * * Automatically detects the runtime environment and returns the most appropriate * data type. In Node.js, returns a Buffer for maximum compatibility with Node.js * APIs. In browsers, gracefully falls back to Uint8Array. * * @returns Buffer in Node.js, Uint8Array in browsers * * @example * ```typescript * const gif = createSolidColorGif(100, 100, { red: 0, green: 255, blue: 0 }); * const buffer = gif.toBuffer(); * * // Node.js usage * if (typeof window === 'undefined') { * // This will be a Buffer in Node.js * await require('fs').promises.writeFile('output.gif', buffer); * } else { * // This will be a Uint8Array in browsers * console.log('Fallback to Uint8Array in browser'); * } * ``` */ toBuffer(): Uint8Array | unknown; /** * Converts the GIF data to a base64 data URL for use in HTML. * * Creates a data: URL that can be used directly in HTML img src attributes, * CSS background-image properties, or anywhere a URL is expected. The result * includes the proper MIME type for GIFs. * * @returns Data URL string in format 'data:image/gif;base64,<data>' * @throws {GifValidationError} When base64 encoding is not available * * @example * ```typescript * const gif = createGradientGif(200, 100, * { red: 255, green: 0, blue: 0 }, * { red: 0, green: 0, blue: 255 } * ); * * // Use in HTML * const dataUrl = gif.toDataURL(); * document.body.innerHTML = `<img src="${dataUrl}" alt="Gradient">`; * * // Use in CSS * document.body.style.backgroundImage = `url(${dataUrl})`; * ``` * * @example * ```typescript * // React usage * function MyComponent() { * const gif = createSolidColorGif(50, 50, { red: 0, green: 255, blue: 0 }); * return <img src={gif.toDataURL()} alt="Green square" />; * } * ``` */ toDataURL(): string; /** * Converts to base64 string */ toBase64(): string; /** * Converts the GIF data to a Blob object (browser only). * * Creates a Blob object that can be used with various browser APIs for file * operations, downloads, or object URLs. Only available in browser environments. * * @returns Blob object with MIME type 'image/gif' * @throws {GifValidationError} When Blob is not available (Node.js environment) * * @example * ```typescript * const gif = createNoiseGif(300, 200, { type: 'perlin' }); * * // Create blob for file operations * const blob = gif.toBlob(); * const file = new File([blob], 'noise.gif', { type: 'image/gif' }); * * // Upload using FormData * const formData = new FormData(); * formData.append('image', blob, 'noise.gif'); * await fetch('/upload', { method: 'POST', body: formData }); * ``` * * @example * ```typescript * // Use with object URL * const gif = createFractalGif(400, 400, { type: 'mandelbrot' }); * const blob = gif.toBlob(); * const url = URL.createObjectURL(blob); * * // Clean up when done * setTimeout(() => URL.revokeObjectURL(url), 1000); * ``` */ toBlob(): Blob; /** * Creates an object URL for the GIF data (browser only). * * Generates a blob: URL that can be used in HTML elements or for downloads. * The URL remains valid until explicitly revoked with URL.revokeObjectURL(). * Remember to revoke the URL when no longer needed to prevent memory leaks. * * @returns Object URL string in format 'blob:<uuid>' * @throws {GifValidationError} When URL.createObjectURL is not available * * @example * ```typescript * const gif = createGeometricGif(250, 250, { shape: 'hexagons' }); * const objectUrl = gif.toObjectURL(); * * // Use in image element * const img = document.createElement('img'); * img.src = objectUrl; * document.body.appendChild(img); * * // Clean up when done * img.onload = () => { * setTimeout(() => URL.revokeObjectURL(objectUrl), 100); * }; * ``` * * @example * ```typescript * // Use for download link * const gif = createSpiralGif(300, 300, { type: 'fibonacci' }); * const url = gif.toObjectURL(); * * const link = document.createElement('a'); * link.href = url; * link.download = 'fibonacci-spiral.gif'; * link.textContent = 'Download Spiral'; * document.body.appendChild(link); * ``` */ toObjectURL(): string; /** * Converts the GIF data to a ReadableStream (when available). * * Creates a ReadableStream that can be used with the Streams API for * streaming operations. Useful for piping data or working with stream-based APIs. * * @returns ReadableStream containing the GIF data * @throws {GifValidationError} When ReadableStream is not available * * @example * ```typescript * const gif = createAnimatedGradientGif(200, 100, * { red: 255, green: 0, blue: 0 }, * { red: 0, green: 255, blue: 0 }, * { animationType: 'pulse' } * ); * * // Use with fetch * const stream = gif.toStream(); * await fetch('/upload', { * method: 'POST', * body: stream, * headers: { 'Content-Type': 'image/gif' } * }); * ``` */ toStream(): ReadableStream<Uint8Array>; /** * Triggers a download of the GIF file in the browser. * * Creates a temporary download link and programmatically clicks it to trigger * the browser's download functionality. Only available in browser environments * with DOM access. * * @param filename - Name for the downloaded file (default: 'image.gif') * @throws {GifValidationError} When document/DOM is not available * * @example * ```typescript * const gif = createCheckerboardGif(200, 150, * { red: 255, green: 0, blue: 255 }, // Magenta * { red: 0, green: 255, blue: 255 } // Cyan * ); * * // Simple download * gif.download(); // Downloads as 'image.gif' * * // Custom filename * gif.download('my-checkerboard.gif'); * ``` * * @example * ```typescript * // Download button handler * document.getElementById('download-btn').addEventListener('click', () => { * const gif = createFractalGif(400, 400, { type: 'julia' }); * gif.download('julia-set-fractal.gif'); * }); * ``` */ download(filename?: string): void; /** * Saves the GIF to a file (Node.js only). * * Writes the GIF data to the specified file path using Node.js file system APIs. * Creates parent directories if they don't exist. Only available in Node.js environments. * * @param filepath - Path where the file should be saved * @throws {GifValidationError} When Node.js fs module is not available * * @example * ```typescript * const gif = createSolidColorGif(800, 600, { red: 70, green: 130, blue: 180 }); * * // Save to current directory * await gif.saveToFile('background.gif'); * * // Save to subdirectory * await gif.saveToFile('./output/steel-blue-bg.gif'); * * // Save with full path * await gif.saveToFile('/home/user/images/custom.gif'); * ``` * * @example * ```typescript * // Batch save multiple GIFs * const colors = [ * { red: 255, green: 0, blue: 0 }, * { red: 0, green: 255, blue: 0 }, * { red: 0, green: 0, blue: 255 } * ]; * * for (let i = 0; i < colors.length; i++) { * const gif = createSolidColorGif(100, 100, colors[i]); * await gif.saveToFile(`color-${i}.gif`); * } * ``` */ saveToFile(filepath: string): Promise<void>; /** * Gets the size of the GIF in bytes */ get size(): number; /** * Gets the MIME type */ get mimeType(): string; /** * Gets the file extension */ get extension(): string; /** * Returns a formatted size string */ get sizeFormatted(): string; /** * Validates that the data appears to be a valid GIF */ isValidGif(): boolean; /** * Manual base64 encoding fallback */ private manualBase64Encode; /** * Gets comprehensive information about the GIF. * * Returns an object containing detailed information about the GIF including * size, format, version, and other metadata. Useful for debugging or displaying * file information to users. * * @returns Object containing GIF metadata and properties * * @example * ```typescript * const gif = createAnimatedGradientGif(300, 200, * { red: 255, green: 100, blue: 0 }, * { red: 100, green: 0, blue: 255 }, * { frames: 30, delay: 50 } * ); * * const info = gif.getInfo(); * console.log(info); * // { * // size: 15420, * // sizeFormatted: "15.1 KB", * // mimeType: "image/gif", * // extension: "gif", * // isValid: true, * // version: "GIF89a", * // hasTransparency: false, * // isAnimated: true * // } * ``` * * @example * ```typescript * // Display file info to user * function displayGifInfo(gif: GifResult) { * const info = gif.getInfo(); * * const infoDiv = document.createElement('div'); * infoDiv.innerHTML = ` * <h3>GIF Information</h3> * <p>Size: ${info.sizeFormatted}</p> * <p>Version: ${info.version}</p> * <p>Valid: ${info.isValid ? 'Yes' : 'No'}</p> * <p>Animated: ${info.isAnimated ? 'Yes' : 'No'}</p> * `; * * document.body.appendChild(infoDiv); * } * ``` */ getInfo(): { size: number; sizeFormatted: string; isValid: boolean; mimeType: string; signature: string; }; }