import { Bezier } from 'bezier-js'; /** * Vertex position enum for warp region * * Used to identify the four vertex coordinates of the warp region. * * @enum {string} */ export declare enum VertexPosition { /** Top left vertex */ TOP_LEFT = "tl", /** Top right vertex */ TOP_RIGHT = "tr", /** Bottom left vertex */ BOTTOM_LEFT = "bl", /** Bottom right vertex */ BOTTOM_RIGHT = "br" } /** * Warp region boundary direction enum * * Used to identify the four boundary directions of the warp region. * * @enum {string} */ export declare enum Direction { TOP = "top", BOTTOM = "bottom", LEFT = "left", RIGHT = "right" } /** * Warp region type * * An object type that describes a rectangular warp region, containing coordinate information of the four vertices. * * @example * const region: Region = { * tl: { x: 0, y: 0 }, // Top-left coordinates * tr: { x: 100, y: 0 }, // Top-right coordinates * bl: { x: 0, y: 100 }, // Bottom-left coordinates * br: { x: 100, y: 100 } // Bottom-right coordinates * }; */ export type Region = Record; /** * Split point calculation strategy interface type * * Defines the strategy name and calculation method for grid split points, * which determines how to generate grid split points inside the warp region, * affecting the final warp effect. * * @property {string} name - Custom identifier name of the strategy * @property {Function} execute - Method to calculate split points under the warp strategy * @property {Warpvas} execute.warpvas - Current warpvas instance object * @property {Coord[][][]} execute.return - Returns a 3D array representing the grid point coordinates of each split region * [region row][region column][grid point coordinates] */ export type Strategy = { name: string; execute: (warpvas: Warpvas) => Coord[][][]; }; /** * Warpvas rendering configuration options * * Controls the rendering effects and debug view display of the warpvas. * By configuring these options, you can customize the appearance and performance of the warpvas. * * @example * const warpvas = new Warpvas(canvas); * warpvas.setRenderingConfig({ * padding: 10, // Set 10px padding * enableAntialias: true, // Enable anti-aliasing * enableSafeRendering: true, // Enable safe rendering mode * enableContentDisplay: true, // Display the warped content * enableGridDisplay: true, // Display the warp grid * enableGridVertexDisplay: false, // Display grid vertices * gridColor: { r: 0, g: 255, b: 0, a: 1 } // Use coral red grid * }); */ export interface RenderingConfig { /** * Padding around the warpvas (in pixels) * * Often used to provide some padding area to preserve overflowed warp content * @default 0 */ padding: number; /** * Whether to enable anti-aliasing * * When enabled, it makes image edges smoother, but may slightly affect performance. * The effect varies across different rendering modes. * @default true */ enableAntialias: boolean; /** * Whether to enable safe rendering mode * * When enabled, it will automatically fallback to Canvas 2D rendering if WebGL rendering fails, * preventing the warpvas from not being displayed due to errors. * @default true * @remarks Since WebGL rendering is used by default, it's recommended to keep this enabled in production. */ enableSafeRendering: boolean; /** * Whether to display the warped content * * @default true */ enableContentDisplay: boolean; /** * Whether to display the warp grid * * Used for debugging warp effects, visually showing the triangulated mesh of warp divisions * @default false */ enableGridDisplay: boolean; /** * Whether to display grid vertices * * Used for debugging the positions of grid vertices * @default false */ enableGridVertexDisplay: boolean; /** * Grid and grid vertex color configuration * @property {number} r - Red channel value (0-255) * @property {number} g - Green channel value (0-255) * @property {number} b - Blue channel value (0-255) * @property {number} a - Transparency (0-1) * @default { r: 255, g: 0, b: 0, a: 1 } // Default red * @remarks In WebGL rendering mode, changes in transparency may affect the rendering result. */ gridColor: { r: number; g: number; b: number; a: number; }; } /** * Warp deformation state data structure * * Contains core data required to describe the deformation state of a texture, * including split points and mesh deformation data. */ export type WarpState = { /** * List of relative positions of split points */ splitPoints: Coord[]; /** * Region boundary deformation data * * A 3D array storing the Bezier curve control points for the four edges of each split region: * - First dimension: Region row index * - Second dimension: Region column index * - Third dimension: Control points array for the four edges (top/right/bottom/left) of the region * * @example * // Example of boundary data for a 2x2 grid * regionBounds: [ * [ * { // Top-left region * top: [{x: 0, y: 0}, ...], // Control points for top edge * right: [{x: 0, y: 0}, ...], // Control points for right edge * bottom: [{x: 0, y: 0}, ...], // Control points for bottom edge * left: [{x: 0, y: 0}, ...] // Control points for left edge * }, * // ... Top-right region * ], * // ... Next row of regions * ] */ regionBounds: Record[][]; }; /** * Warp deformation class * * The warp deformation class can create corresponding deformation tool instances based on image sources, * and can apply deformation to images through internal methods to produce deformed graphic canvases. * * @example * const canvas = document.createElement('canvas'); * const ctx = canvas.getContext('2d'); * if (!ctx) return; * // Draw a rectangle * ctx.fillRect(0, 0, canvas.width, canvas.height); * * // Create a Warpvas instance, passing the canvas as the image source * const warpvas = new Warpvas(canvas); * * // Drag the top-left corner of the original canvas image to position (50, 50) * warpvas.updateVertexCoord(0, 0, 'tl', { x: 50, y: 50 }); * * // Generate the deformed canvas and add it to the document * const warpvasCanvas = warpvas.render(); * document.body.appendChild(warpvasCanvas); */ export declare class Warpvas { /** * Source canvas object * * Stores the canvas containing the original image data. If an HTMLImageElement instance is passed to the constructor, * a new canvas will be automatically created and the image will be drawn onto it to avoid modifying the original image. */ source: HTMLCanvasElement; /** * List of relative positions of split points * * Stores the relative coordinates (range 0-1) of canvas split points. These points divide the canvas into multiple deformable regions, * where each split point's coordinates are proportional values relative to the canvas dimensions, not actual pixel values. * * @remarks To add split points, do not directly manipulate this list. Instead, use the splitRegionByPoint method to add split points. * * @see splitRegionByPoint Learn how to add split points to achieve region segmentation */ splitPoints: Coord[]; /** * Pre-deformation regions * * 2D array storing the four vertex coordinates of each rectangular region before deformation. * * @remarks Array structure: [region row][region column], each region contains four vertices: * top-left (tl), top-right (tr), bottom-left (bl), bottom-right (br) * * @example * // Access top-left coordinate of the first region * const topLeft = warpvas.originalRegions[0][0].tl; */ originalRegions: Region[][]; /** * Original grid points * * 3D array storing the coordinates of grid points within each region before deformation. * These coordinates are in their original state and used as mapping data for subsequent deformation calculations. * * @remarks Array structure: [region row][region column][list of grid points] */ originalRegionPoints: Coord[][][]; /** * Region boundary curves * * Stores the Bezier curve objects for the four edges of each region. */ regionBoundaryCurves: Record[][]; /** * Deformed grid curves * * Stores the grid lines of each region after deformation, including both vertical and horizontal Bezier curves. * These curves determine the final deformation effect of the image. * * @remarks To perform deformation, do not directly manipulate this list. * Instead, use the updateRegionBoundCoords method to adjust specific curves for boundary deformation effects. * * @see updateRegionBoundCoords Learn how to adjust region boundary curves to achieve deformation effects */ regionCurves: { vertical: Bezier[]; horizontal: Bezier[]; }[][]; /** * Deformed grid points * * Stores the coordinates of grid points after deformation. The positions of these points are calculated by the split strategy, * and different strategies will produce different deformation effects. * * @remarks To perform deformation, do not directly manipulate this list. * Instead, use the updateVertexCoord/updateRegionBoundCoords methods to achieve deformation effects. * * @see Strategy Learn more about split strategies * @see updateVertexCoord Learn how to adjust region vertex coordinates for deformation * @see updateRegionBoundCoords Learn how to adjust region boundary curves for deformation */ regionPoints: Coord[][][]; /** * Grid split ratio * * Controls the density of the grid split, with a value range of 0-1. The smaller the value, * the denser the grid, resulting in finer deformation effects, but also increasing computation. * For example, when the value is 0.1, the maximum size of each grid is 10% of the image width. * * @default 0.05 Default value, meaning the maximum size of each grid is 5% of the image width. * * @see setSplitUnit Learn how to control the grid split ratio */ splitUnit: number; /** * Split point calculation strategy * * Defines how to calculate the grid point positions inside the deformation region. * The built-in warp strategy is used by default, and you can also set a custom strategy through the setSplitStrategy method. * * @see setSplitStrategy Learn how to configure the split calculation strategy */ splitStrategy: Strategy; /** * Rendering engine type * * Specifies the rendering method to use, supports '2d' or 'webgl'. * WebGL mode has better performance, and when safe rendering configuration is set, * it will automatically fallback to Canvas in environments where WebGL is not supported. * * @default 'webgl' * * @see setRenderingContext Learn how to switch rendering engines */ renderingContext: '2d' | 'webgl'; /** * Rendering options * Controls various parameters of the rendering process, including padding, anti-aliasing, debug grid display, etc. * These options can be dynamically modified through the setRenderingConfig method. * * @see RenderingConfig View all available rendering options * @see setRenderingConfig Learn how to configure rendering options */ renderingConfig: RenderingConfig; /** * Safe rendering mode activation flag * * Indicates whether safe rendering mode is activated. When the first WebGL * rendering failure occurs with safe mode configured, this flag enables * subsequent renders to automatically downgrade to Canvas 2D rendering. */ private _safeModeEnabled; /** * Image source dimensions cache * * Stores the current image source's dimension information, * triggers grid points recalculation when dimensions change. * * @private */ private _cacheSourceSize; /** * Source image data cache * * Stores the original image's pixel data to optimize performance during Web Worker rendering. * When using Web Workers for rendering, avoiding repeated image data retrieval can significantly improve performance. * * @private */ private _cacheSourceImageData; /** * Input canvas cache * * Stores the temporary canvas used for resizing input images. * Maintaining a separate cache canvas preserves the original image source and ensures data integrity. * * @private */ private _cacheInputCanvas; /** * Output canvas cache * * Stores the singleton canvas instance for rendering results. * Reusing the same canvas across multiple rendering operations reduces memory usage. * * @private * @see setRenderingCanvas Learn how to configure the output canvas in singleton mode */ private _cacheOutputCanvas; /** * Input size constraints * * Defines maximum dimensions allowed for input canvas. * Canvas exceeding these constraints will be proportionally scaled down to fit. * * @private * @see setInputLimitSize Learn how setting input size limits utilizes this cache */ private _inputLimitSize; /** * Input scaling ratio * * Records the actual scaling factor caused by input size constraints. * When input images require resizing, this value captures the applied scaling ratio. * * @private * @default 1 */ private _inputLimitScale; /** * Output size constraints * * Defines maximum dimensions allowed for output canvas. * Deformed results exceeding these constraints will be automatically scaled down proportionally to fit. * * @private * @see setOutputLimitSize Learn how to configure output size constraints * @remarks Proper configuration prevents performance issues and rendering failures caused by oversized canvases. */ private _outputLimitSize; /** * Output scaling ratio * * Records the actual scaling factor resulting from output size constraints. * Captures the applied ratio when output canvas requires resizing. * * @private * @default 1 */ private _outputLimitScale; /** * Warpvas constructor * * Creates a new warp deformation canvas instance. Accepts an image or canvas as source, * with optional initial grid division settings. * * @param source - Image source (HTMLImageElement or HTMLCanvasElement) * - For images: auto-creates canvas and draws image * - For canvases: uses directly as source * * @param rows - Initial horizontal divisions * - Must be integer ≥ 1 * - 1 = no horizontal division * - 2 = adds midline horizontal division * - Default: 1 * * @param columns - Initial vertical divisions * - Must be integer ≥ 1 * - 1 = no vertical division * - 2 = adds midline vertical division * - Default: 1 * * @example * // Create with image * const img = new Image(); * img.src = 'example.jpg'; * img.onload = () => new Warpvas(img); * * // Create with canvas and 2x2 grid * const canvas = document.createElement('canvas'); * new Warpvas(canvas, 2, 2); */ constructor(source: HTMLCanvasElement | HTMLImageElement, rows?: number, columns?: number); /** * Maximum split unit in pixels * * Calculates the maximum grid division size allowed for current texture in pixels. * This value is determined by splitUnit (division ratio) and image width. * * @returns {number} Maximum split unit in pixels * - When splitUnit is 0.1: returns 10% of image width * - When splitUnit is 0.05: returns 5% of image width * * @example * // Assuming image width is 1000px with splitUnit 0.1 * const maxSize = warpvas.maxSplitUnitPixel; // Returns 100px * * @see splitUnit See split ratio configuration */ get maxSplitUnitPixel(): number; /** * Actual scaling ratio of the canvas * * Returns the scaling ratio relative to original dimensions. * The ratio combines both input and output limitations: * - Input limitations: Automatic scaling when processing large images * - Output limitations: Prevents oversized canvas generation * * @returns {{ x: number, y: number }} Scaling ratios in x/y dimensions * - 1 = original size * - <1 = downscaled * - x/y always equal to prevent distortion * * @example * const { x, y } = warpvas.scale; * console.log(`Canvas scaled to ${x * 100}% of original size`); */ get scale(): { x: number; y: number; }; /** * Built-in default warp splitting strategy * * Default grid splitting strategy that generates grid points by calculating * midpoints between intersections of horizontal/vertical Bezier curves. * This strategy effectively demonstrates planar warp effects, particularly * suitable for: * - Image bending deformation * - Perspective transformation * - Wave effect simulations * * @param warpvas - Current warp canvas instance * @returns 3D array containing grid coordinates of all split regions * - 1st dimension: Region row index * - 2nd dimension: Region column index * - 3rd dimension: List of grid points in the region * * @example * // Default strategy is already applied, but can be explicitly set: * warpvas.setSplitStrategy({ * name: 'default', * execute: Warpvas.strategy * }); * * @remarks * Strategy workflow: * 1. Iterate through each split region * 2. Calculate intersections of horizontal/vertical Bezier curves within region * 3. Use midpoints of intersecting pairs as grid points * 4. Ensures uniform grid distribution that follows curve deformations */ static strategy(warpvas: Warpvas): Coord[][][]; /** * Serialize warp state data * * Compresses warp deformation data into base64 string format for transmission/storage. * The compressed data includes: * - Split points configuration * - Region boundary deformations * * @param warpState - Warp state object containing: * - splitPoints: Grid division coordinates * - regionBounds: Boundary deformation data * @returns base64 encoded string representing compressed warp state * * @example * // 1. Get current warp state * const warpState = warpvas.getWarpState(); * * // 2. Serialize data * const compressed = Warpvas.serializeWarpState(warpState); * * @see deserializeWarpState Restore compressed warp state * @see getWarpState Retrieve current deformation data */ static serializeWarpState(warpState: WarpState): string; /** * Deserialize compressed warp state * * Restores warp deformation data from base64 string generated by serializeWarpState. * The decompressed data can directly rebuild the texture's deformation state. * * @param base64String - base64 encoded string from serializeWarpState * @returns {Object} Decompressed warp state containing: * - splitPoints: Array of split coordinates (0-1 range) * - boundData: 2D array of boundary deformation data per region * * @example * // 1. Deserialize data * const { splitPoints, boundData } = Warpvas.deserializeWarpState(compressedData); * * // 2. Apply deformation state * warpvas.setWarpState(splitPoints, boundData); * * @see serializeWarpState Compress warp state * @see setWarpState Apply deformation configuration */ static deserializeWarpState(base64String: string): WarpState; /** * Initialize split ratio points * * Creates initial grid of split points using relative coordinates (0-1 range) * that partition the image into multiple deformable regions. * * @param rows - Horizontal divisions * - Integer ≥ 1 * - Actual split lines = rows - 1 * - Example: rows=2 adds mid horizontal line * - Default: 1 (no horizontal division) * * @param columns - Vertical divisions * - Integer ≥ 1 * - Actual split lines = columns - 1 * - Example: columns=2 adds mid vertical line * - Default: 1 (no vertical division) * * @returns Array of split coordinates as image size ratios (0-1) */ private _initializeSplitPoints; /** * Initialize original regions * * Partitions the image into multiple rectangular regions based on split ratio points. * Each region contains four vertex coordinates in actual pixel positions (not ratios). * * @returns 2D array containing all region information: * - 1st dimension: Row index * - 2nd dimension: Column index * - Each region contains four vertex coordinates (tl/tr/bl/br) */ private _initializeOriginalRegions; /** * Calculate sampling points for region boundaries * * Computes Bezier curve sampling positions based on region dimensions. * Automatically adjusts point density to balance deformation quality and performance. * * @param region - Target region containing four vertices: * - tl: Top-left * - tr: Top-right * - bl: Bottom-left * - br: Bottom-right * * @returns Object containing sampling positions in two dimensions: * - hts: Horizontal positions array (0-1 range) * - vts: Vertical positions array (0-1 range) * * @remarks * t-value in Bezier curves represents relative position: * - t = 0: Curve start point * - t = 1: Curve end point * - 0 < t < 1: Intermediate point along the curve */ private _calculateSamplingPoints; /** * Initialize grid points within partition regions * * Generates grid points based on initial partition regions. These points will be used for: * 1. Building reference grids during deformation * 2. Calculating texture mapping relationships * 3. Generating final deformation effects * * @returns 3D array containing all region grid points: * - 1st dimension: Region row index * - 2nd dimension: Region column index * - 3rd dimension: List of grid points within the region */ private _initializeOriginalRegionPoints; /** * Initialize boundary Bezier curve control points * * Creates cubic Bezier curve control points for four boundaries of each partition region. * Initial state produces straight-line curves, which can be bent by adjusting control points. * * @param regions - Array of partition regions, each containing four vertex coordinates * * @returns 3D array containing all boundary control points: * - 1st dimension: Region row index * - 2nd dimension: Region column index * - 3rd dimension: Directional control points array (top/right/bottom/left) * Each direction contains 4 points: start, first control, second control, end * * @remarks * Cubic Bezier curve control points roles: * - P0 (Start): Curve's initial position * - P1 (First control): Controls tangent direction and curvature at start * - P2 (Second control): Controls tangent direction and curvature at end * - P3 (End): Curve's terminal position */ private _initializeBoundaryControlPoints; /** * Generate partition curve mesh within regions * * Creates internal mesh curves based on boundary Bezier curves. These curves form the deformation framework: * 1. Establish deformation reference grids * 2. Calculate texture mapping reference points * 3. Achieve smooth deformation effects * * @param bounds - Bezier curve objects for region boundaries * @param hts - Horizontal sampling positions array (0-1 range) * @param vts - Vertical sampling positions array (0-1 range) * * @returns Object containing mesh curves in two orientations: * - vertical: Array of vertical Bezier curves * - horizontal: Array of horizontal Bezier curves * * @see _calculateSamplingPoints Calculate sampling positions */ private _generateRegionCurves; /** * Generate internal mesh curves for partition regions * * Creates internal grid curves based on boundary Bezier curves. These curves are used for: * 1. Building deformation reference grids * 2. Calculating texture mapping reference points * 3. Achieving smooth deformation effects * * @param regionBoundaryCurves - 3D array of region boundary curves * - 1st dimension: Row index * - 2nd dimension: Column index * - 3rd dimension: Four boundary Bezier curves per region (top/right/bottom/left) * * @returns 3D array containing all region mesh curves: * - 1st dimension: Row index * - 2nd dimension: Column index * - 3rd dimension: Bezier curves in two orientations * - vertical: Array of vertical curves * - horizontal: Array of horizontal curves * * @see _generateRegionCurves Generate mesh curves for individual regions * @see _calculateSamplingPoints Calculate sampling positions */ private _generateAllRegionCurves; /** * Set maximum ratio for deformation grid subdivision * * Controls the granularity of grid subdivision. Smaller values produce denser grids * for finer deformation effects, while increasing computational load. * * @param splitUnit - Maximum subdivision ratio value * - Range: Numerical value between 0-1 * - 0.1: Maximum grid unit equals 10% of image width * - 0.05: Maximum grid unit equals 5% of image width * - Values ≤0 or >1 will be reset to 1 * * @returns Instance itself for method chaining * * @example * // Set dense grid for finer deformation * warpvas.setSplitUnit(0.05); * * // Set sparse grid for better performance * warpvas.setSplitUnit(0.2); */ setSplitUnit(splitUnit: number): this; /** * Set calculation strategy for grid subdivision points * * Customizes grid subdivision point calculation method. Different strategies enable * various deformation effects through alternative subdivision approaches. * * @param strategy - Subdivision strategy configuration object * - name: Strategy identifier (customizable) * - execute: Execution function receiving Warpvas instance * * @returns Instance itself for method chaining * * @example * // Using custom strategy * warpvas.setSplitStrategy({ * name: 'custom', * execute: (warpvas) => { * // Return custom grid points calculation * return [[[{ x: 0, y: 0 }]]]; * } * }); * * @see Warpvas.strategy Default strategy implementation */ setSplitStrategy(strategy: Strategy): this; /** * Set size constraints for input canvas * * Restricts maximum dimensions of input canvas when processing large images. * System will automatically scale images proportionally within constraints to * improve performance and reduce memory consumption. * * @param limitSize - Size constraint configuration object * - width?: number - Maximum width in pixels * - height?: number - Maximum height in pixels * - Pass undefined to remove constraints * * @returns Instance itself for method chaining * * @example * // Constrain input to 1000x1000 pixels * warpvas.setInputLimitSize({ * width: 1000, * height: 1000 * }); * * // Remove size constraints * warpvas.setInputLimitSize(undefined); * * @remarks * Performance recommendations: * 1. For large images (>2000px), recommend setting appropriate constraints * 2. Images maintain original aspect ratio when scaled * 3. Uses cached canvas to avoid repeated scaling operations */ setInputLimitSize(limitSize: { width?: number; height?: number; } | undefined): this; /** * Set size constraints for output canvas * * Restricts maximum dimensions of output canvas after deformation. When deformation results * exceed size limits, system automatically scales output proportionally to prevent * rendering failures due to memory constraints. * * @param limitSize - Size constraint configuration object * - width?: number - Maximum width in pixels * - height?: number - Maximum height in pixels * - Pass undefined to remove constraints * * @returns Instance itself for method chaining * * @example * // Constrain output to 2000x2000 pixels * warpvas.setOutputLimitSize({ * width: 2000, * height: 2000 * }); * * // Remove size constraints (may cause large image rendering failures) * warpvas.setOutputLimitSize(undefined); * * @remarks * Performance recommendations: * 1. Unconstrained deformation may exceed browser's Canvas size limits, causing blank output * 2. Recommend setting appropriate constraints based on application scenarios * 3. Output dimensions significantly impact rendering performance and memory usage */ setOutputLimitSize(limitSize: { width?: number; height?: number; } | undefined): this; /** * Set rendering engine type * * Configures the rendering engine to use Canvas2D or WebGL mode. Mode comparison: * - Canvas2D: Better compatibility (supports most browsers) but slower performance * - WebGL: Better performance (GPU accelerated) for large images, but limited compatibility * * @returns Returns the instance itself for method chaining * * @remarks * In safe rendering mode, the system will automatically fall back to Canvas2D * when WebGL is unavailable or rendering fails * * @example * // Enable Canvas2D rendering * warpvas.setRenderingContext('2d'); * * // Enable WebGL rendering * warpvas.setRenderingContext('webgl'); */ setRenderingContext(ctx: '2d' | 'webgl'): this; /** * Set rendering output canvas * * Specifies a fixed canvas for rendering output. Reusing the same canvas across multiple * renders reduces memory allocation from canvas creation and improves performance. * * @param canvas - Target canvas element * * @returns Instance itself for method chaining * * @example * // Reuse canvas in animation loop * const canvas = document.createElement('canvas'); * warpvas.setRenderingCanvas(canvas); * * function animate() { * // Update content on the same canvas each frame * warpvas.render(); * requestAnimationFrame(animate); * } * * @remarks * WARNING: Avoid using the same canvas for both input and output, as this forces * creating a temporary canvas copy before each render, significantly degrading performance */ setRenderingCanvas(canvas: HTMLCanvasElement): this; /** * Set rendering configuration options * * Configures various parameters for texture mapping rendering. Allows partial * overriding of default configuration. * * @param options - Rendering configuration object * - padding: number - Padding around output (pixels), default 0 * - enableAntialias: boolean - Enable/disable anti-aliasing, default true * - enableSafeRendering: boolean - Safe rendering mode (WebGL only), * auto-fallback to Canvas2D on failure, default true * - enableContentDisplay: boolean - Show warped content, default true * - enableGridDisplay: boolean - Show deformation grid, default false * - enableGridVertexDisplay: boolean - Show grid vertices, default false * - gridColor: { r: number, g: number, b: number, a: number } - * Grid/vertex RGBA color object, default red (255,0,0,1) * * @returns Instance itself for method chaining * * @example * // Configure rendering parameters * warpvas.setRenderingConfig({ * padding: 10, // 10px padding * enableAntialias: true, // Enable anti-aliasing * enableSafeRendering: true, // Enable safe mode * enableContentDisplay: true, // Display warped content * enableGridDisplay: true, // Show deformation grid * gridColor: { r: 0, g: 255, b: 0, a: 1 } // Green grid color * }); * * @remarks * Performance recommendations: * 1. Maintain enableSafeRendering=true in production environments * 2. Padding helps prevent visual clipping during deformation */ setRenderingConfig(options: Partial): this; /** * Get bounding box information of warped image * * Calculates boundary dimensions and offsets after deformation. The values include * rendering configuration padding and can be used to properly size output canvas. * * @returns Bounding box information object containing: * @returns offsetX - X-axis offset in pixels * @returns offsetY - Y-axis offset in pixels * @returns width - Total width including padding (pixels) * @returns height - Total height including padding (pixels) * * @example * // Get warped image dimensions * const { width, height, offsetX, offsetY } = warpvas.getBoundingBoxInfo(); * * // Apply dimensions to canvas * canvas.width = width; * canvas.height = height; * * // Adjust rendering position * ctx.translate(offsetX, offsetY); */ getBoundingBoxInfo(): { offsetX: number; offsetY: number; width: number; height: number; }; /** * Clone source canvas element * * Creates a new canvas with identical dimensions and content from source canvas. * * @param canvas - Source canvas to clone * @param width - Optional width override (default: source canvas width) * @param height - Optional height override (default: source canvas height) * * @returns New canvas element with copied content */ private _cloneCanvas; /** * Create linear-like cubic Bezier curve * * Converts straight line between two points into cubic Bezier representation. * Evenly distributes control points along the line to maintain visual linearity * while preserving Bezier curve properties. * * @param p0 - Start point coordinates * @param p1 - End point coordinates * * @returns Array of 4 control points representing cubic Bezier curve: * [start, first control, second control, end] */ private _createLinearBezier; /** * Merge two Bezier curves * * Smoothly combines two adjacent Bezier curves into a single continuous curve. * Primarily used during split point removal operations to maintain smooth transitions * between merged curves. * * @param curve1Points - First curve's control points array [p0, p1, p2, p3] * @param curve2Points - Second curve's control points array [p0, p1, p2, p3] * * @returns Merged Bezier curve's control points array [p0, p1, p2, p3] */ private _mergeBezierCurves; /** * Find connected vertex in deformation grid * * Retrieves position information of adjacent vertex connected to current boundary vertex. * Essential for maintaining grid continuity during vertex manipulation operations. * * @param direction - Current edge direction * - 'top': Top edge * - 'bottom': Bottom edge * - 'left': Left edge * - 'right': Right edge * @param position - Position on the edge * - 'first': Start point of the edge * - 'last': End point of the edge * * @returns Connected vertex information containing: * - direction: Adjacent edge direction * - position: Corresponding position on adjacent edge * * @see updateVertexCoord Used for updating vertex coordinates while maintaining grid continuity */ private _findConnectedVertex; /** * Update coordinates for a single vertex * * Maintains grid continuity by updating both: * 1. Bezier curves on the vertex's two adjacent edges * 2. Connected vertex's edge curves in deformation grid * * @param rowIndex - Row index of target vertex * @param colIndex - Column index of target vertex * @param type - Vertex position type (tl/tr/bl/br) * @param coord - New coordinates { x, y } * @param redistribute - Control point redistribution flag * - true: Recalculate all control points (smooth transition) * - false: Only update endpoints (preserve original curvature) * - Default: true * * @see _findConnectedVertex Retrieve connected vertex information * @see _createLinearBezier Create Bezier curve control points */ private _setSingleRegionVertexCoord; /** * Update coordinates for a warped texture vertex * * Moves specified vertex and automatically synchronizes all connected vertices * to maintain grid continuity across deformation regions. * * @param rowIndex - Target region's row index (0-based) * @param colIndex - Target region's column index (0-based) * @param vertexPosition - Vertex position type * - 'tl': Top-left * - 'tr': Top-right * - 'bl': Bottom-left * - 'br': Bottom-right * @param coord - New vertex coordinates { x, y } * @param redistribute - Control point recalculation flag * - true: Recalculate for smooth transition (default) * - false: Preserve existing curve shape * * @returns Current instance for method chaining * * @example * // Move top-left vertex of region (0,0) to (100,100) * warpvas.updateVertexCoord( * 0, // rowIndex * 0, // colIndex * 'tl', // vertexPosition * { x: 100, y: 100 }, // New position * true // Recalculate curves * ); * * @remarks * Important considerations: * 1. Vertex movement affects all connected vertices and curves * 2. Setting redistribute=false preserves original curvature * 3. Invalid indices will be silently ignored */ updateVertexCoord(rowIndex: number, colIndex: number, vertexPosition: `${VertexPosition}`, coord: Coord, redistribute?: boolean): this; /** * Update boundary curve coordinates for specified direction * * Modifies Bezier curve shape of region boundary by setting new control points, * allowing curvature adjustments while maintaining grid continuity. * * @param rowIndex - Target region's row index (0-based) * @param colIndex - Target region's column index (0-based) * @param direction - Boundary direction to update * - 'top': Top boundary * - 'right': Right boundary * - 'bottom': Bottom boundary * - 'left': Left boundary * @param coords - Bezier curve control points array containing: * - p0: Start point coordinates * - pm0: First control point coordinates * - pm1: Second control point coordinates * - p1: End point coordinates * * @returns Current instance for method chaining * * @example * // Create S-shaped top boundary curve * warpvas.updateRegionBoundCoords( * 0, // rowIndex * 0, // colIndex * 'top', // direction * [ * { x: 0, y: 0 }, // Start point * { x: 30, y: 20 }, // Control point 1 * { x: 70, y: -20 }, // Control point 2 * { x: 100, y: 0 } // End point * ] * ); * * @see updateVertexCoord For updating individual vertices */ updateRegionBoundCoords(rowIndex: number, colIndex: number, direction: `${Direction}`, coords: [p0: Coord, pm0: Coord, pm1: Coord, p1: Coord]): this; /** * Retrieve boundary curve control points for all regions * * Exports Bezier curve control point data for all deformation regions' boundaries. * The returned data structure maintains full grid topology information for: * 1. Serializing/deserializing warp states * 2. Implementing undo/redo functionality * 3. Cross-instance deformation synchronization * * @param callback - Custom data processor (optional) * - rowIndex: Region's row index * - colIndex: Region's column index * - direction: Boundary direction ('top'|'right'|'bottom'|'left') * - bezier: Bezier curve object containing control points * - Default returns raw control point array * * @returns Three-dimensional array containing: * - 1st dimension: Row indices * - 2nd dimension: Column indices * - 3rd dimension: Control points for four boundaries * - top: Top boundary points [start, cp1, cp2, end] * - right: Right boundary points * - bottom: Bottom boundary points * - left: Left boundary points * * @example * // Get all boundary data with normalized coordinates * const normalizedData = warpvas.forEachRegionBoundCoords( * (row, col, dir, bezier) => bezier.points.map(p => ({ * x: p.x / sourceWidth, * y: p.y / sourceHeight * })) * ); * * @remarks * Return format specification: * [ * [ // Row 0 * { // Column 0 * top: [{x,y}, {x,y}, {x,y}, {x,y}], // 4 control points * right: [{x,y}, {x,y}, {x,y}, {x,y}], // 4 control points * bottom: [{x,y}, {x,y}, {x,y}, {x,y}], // 4 control points * left: [{x,y}, {x,y}, {x,y}, {x,y}] // 4 control points * }, * // More columns... * ], * // More rows... * ] * * @see updateRegionBoundCoords For modifying boundary curves */ forEachRegionBoundCoords(callback?: (rowIndex: number, colIndex: number, direction: Direction, bezier: Bezier) => Coord[]): Record[][]; /** * Initialize Bezier curve objects for region boundaries * * Converts boundary control point data into Bezier curve instances while * reusing shared boundary curves between adjacent regions. * * @param regionBoundsCoords - 3D array structure containing: * - 1st dimension: Row indices * - 2nd dimension: Column indices * - 3rd dimension: Control points for four boundaries: * - top: [start, cp1, cp2, end] * - right: [start, cp1, cp2, end] * - bottom: [start, cp1, cp2, end] * - left: [start, cp1, cp2, end] * * @returns Curves array mirroring input structure: * - 1st dimension: Row indices * - 2nd dimension: Column indices * - 3rd dimension: Four Bezier curve objects per region * * @see Bezier bezier-js library class for curve calculations */ private _initializeRegionBoundaryCurves; /** * Retrieve complete deformation state data * * @returns {WarpState} Deformation state object containing: * - splitPoints: Array of split points with normalized coordinates (0-1 range) * - regionBounds: 3D array of boundary control points for all regions * * @remarks * Data structure specifications: * - splitPoints: Normalized coordinates relative to original texture dimensions * - regionBounds: Hierarchical array structure [rows][columns][boundaryDirections] * - Each boundary contains exactly 4 control points in order: [p0, pm0, pm1, p1] * * @see setWarpState Apply saved deformation state * @see resetWarpState Restore default grid configuration */ getWarpState(): WarpState; /** * Apply saved deformation state configuration * * Updates texture deformation using provided warp data, supporting: * 1. State restoration from serialized data * 2. Cross-instance deformation replication * 3. Template-based warp applications * * @param splitPoints - Array of normalized split points (0-1 range) * @param regionBounds - Boundary curve data (optional) * - When provided: Directly sets boundary curves * - When null: Generates linear boundaries from split points * * @returns Current instance for method chaining * * @example * // 1. Apply complete warp state * const data = sourceWarpvas.getWarpState(); * sourceWarpvas.setWarpState(data.splitPoints, data.regionBounds); * * // 2. Reset to non-warped state with central split * warpvas.setWarpState([ * { x: 0.5, y: 0.5 } // Add central split point * ]); * * @remarks * Critical implementation details: * 1. Split points must be normalized (0-1 range) * 2. Automatic linear boundaries maintain grid continuity * 3. Control point order: [p0, pm0, pm1, p1] per boundary * * @see getWarpState Retrieve current deformation state * @see resetWarpState Restore default grid configuration */ setWarpState(splitPoints: Coord[], regionBounds?: Record[][] | null): this; /** * Restore default grid configuration * * Resets texture deformation to initial grid state by: * 1. Clearing all split points * 2. Recreating straight-line boundaries * 3. Rebuilding specified grid topology * * @param rows - Number of grid rows (default: 1) * @param columns - Number of grid columns (default: 1) * * @returns Current instance for method chaining * * @example * // 1. Reset to default 1x1 grid * warpvas.resetWarpState(); * * // 2. Reset to 3x2 grid * warpvas.resetWarpState(3, 2); * * @see setWarpState Apply custom deformation state * @see getWarpState Retrieve current deformation state */ resetWarpState(rows?: number, columns?: number): this; /** * Verify texture deformation status * * Determines if the texture is in its original undeformed state by checking: * 1. Absence of split points (empty splitPoints array) * 2. All boundaries remain linear (no Bezier curve deformation) * 3. Boundary positions match original texture edges * * @returns {boolean} * - true: Texture is in pristine undeformed state * - false: Texture has deformation or splits */ isUnwarped(): boolean; /** * Detect hit position in warped texture * * Determines if a coordinate point lies within the deformed texture area * and returns detailed positional metadata. Typical use cases include: * 1. Implementing mouse interaction features * 2. Validating click positions * 3. Retrieving region-specific details * * @param point - Coordinate to test * - x: X position in pixels * - y: Y position in pixels * * @returns Hit information object containing: * - rowIndex: Region row index * - colIndex: Region column index * - row: Grid row number * - col: Grid column number * - before: Original quad vertices [TL, TR, BR, BL] * - after: Deformed quad vertices [TL, TR, BR, BL] * - clickPart: Sub-region triangle identifier (0: upper, 1: lower) * Returns null if point is outside texture * * @example * // Detect canvas click position * canvas.addEventListener('click', (e) => { * const hitInfo = warpvas.getHitInfo({ * x: e.clientX - canvas.offsetLeft, * y: e.clientY - canvas.offsetTop * }); * }); */ getHitInfo(point: Coord): { rowIndex: number; colIndex: number; row: number; col: number; before: Coord[]; after: Coord[]; clickPart: 0 | 1; } | null; /** * Add split point to partition region * * Inserts a new split point in specified region to create sub-regions. * * @param rowIndex - Target region row index (0-based) * @param colIndex - Target region column index (0-based) * @param point - Split point coordinates in pixels * - x: Horizontal position * - y: Vertical position * @param tolerate - Tolerance threshold for boundary snapping (default: 0.05) * - Range: 0-1 (normalized) * - Points near boundaries within tolerance will snap to edges * - Higher values prevent tiny sub-regions near boundaries * * @example * // Split center of first region (0,0) with 10% tolerance * const region = warpvas.originalRegions[0][0]; * warpvas.splitRegionByPoint( * 0, // rowIndex * 0, // colIndex * { // Region center * x: (region.tl.x + region.br.x) / 2, * y: (region.tl.y + region.br.y) / 2 * }, * 0.1 // 10% tolerance * ); * * @remarks * Implementation notes: * 1. Split points modify adjacent region boundaries using Bezier curve blending * 2. Complex deformations may require recalculating neighboring regions * 3. Excessive split points may impact performance * * @see removeRegion Remove split points and merge regions */ splitRegionByPoint(rowIndex: number, colIndex: number, point: Coord, tolerate?: number): void; /** * Remove specified deformation regions * * Deletes one or more deformation regions while maintaining grid continuity * through automatic region merging. * * @param positions - Array of region positions to remove * - Each position contains row and column indices (0-based) * * @example * // Remove region at row 1, column 1 * warpvas.removeRegion( * { * row: 1, * column: 1 * } * ); * * @remarks * Implementation details: * 1. Removal is invalid for: * - Corner vertices of the image * - Positions outside valid region bounds * - Non-existent split points * * 2. Removal sequence: * - Merge rows (bottom to top) * - Merge columns (right to left) * - Automatically smooth boundary curve transitions * * 3. Performance considerations: * - Batch removal of multiple points is recommended over single-point operations */ removeRegion(...positions: { row: number; column: number; }[]): void; /** * Iterate through all quadrilateral cells in deformation grid * * Traverses each quadrilateral cell in the warped mesh and provides * their pre/post-deformation vertex information. * * @param handler - Callback function handling each quadrilateral * Receives parameters: * - newVertexs: Deformed vertices [TL, TR, BR, BL] * - oldVertexs: Original vertices [TL, TR, BR, BL] * - row: Row index within current region * - col: Column index within current region * - rowIndex: Parent region row index * - colIndex: Parent region column index * * @example * // Iterate through all grid cells and log position info * warpvas.forEachSplitRegion((newVertexs, oldVertexs, row, col, rowIndex, colIndex) => { * console.log(`Region[${rowIndex},${colIndex}] sub-grid[${row},${col}]:`); * console.log('Original:', oldVertexs); * console.log('Deformed:', newVertexs); * }); */ forEachSplitRegion(handler: (newVertexs: [leftTop: Coord, rightTop: Coord, bottomRight: Coord, bottomLeft: Coord], oldVertexs: [leftTop: Coord, rightTop: Coord, bottomRight: Coord, bottomLeft: Coord], row: number, col: number, rowIndex: number, colIndex: number) => void): void; /** * Generate rendering configuration parameters * * Processes the following aspects to prepare for texture rendering: * 1. Calculate deformation grid and split points * 2. Handle canvas size constraints and scaling * 3. Prepare rendering canvases and parameters * * @returns Configuration object containing: * - inputCanvas: Source canvas (original image or cached scaled version) * - outputCanvas: Target canvas instance (specified or null) * - options: Rendering parameters * - x: Horizontal rendering offset * - y: Vertical rendering offset * - width: Rendered width * - height: Rendered height * - sourceScale: Input canvas scaling factor * - destinationScale: Output canvas scaling factor */ private _generateRenderOptions; /** * Retrieve pixel data from input canvas * * Obtains raw pixel data for rendering calculations in Web Workers. * * @param caching - Whether to use cached pixel data (default: true) * * @returns {ImageData} Canvas pixel data object */ private _getInputCanvasImageData; /** * Render warped canvas * * Generates a new canvas or renders deformed image on specified canvas * based on current deformation parameters. * * @returns {HTMLCanvasElement} Newly created or specified canvas element * * @throws {Error} * - [Warpvas Error] When rendering fails without safe mode * - [Warpvas Error] When canvas creation fails * * @example * // Render and append to DOM * const canvas = warpvas.render(); * document.body.appendChild(canvas); * * @remarks * Performance recommendations: * 1. For frequent updates, reuse output canvas with setRenderingCanvas * 2. For large image deformation, consider: * - Switching to WebGL rendering backend * - Using worker-based async rendering * * @see setRenderingCanvas Configure reusable canvas * @see renderWithWorker Async rendering via Web Worker */ render(): HTMLCanvasElement; /** * Generate warped canvas asynchronously via Web Worker * * Executes deformation and rendering operations in a separate thread * to prevent blocking the main thread. * * @returns {Promise} Promise resolving to rendered warped canvas * * @throws {Error} * - [Warpvas Error] Failed to create Web Worker * - [Warpvas Error] Rendering failed without safe mode * - [Warpvas Error] Canvas creation failed * * @example * // Async rendering and awaiting result * try { * const canvas = await warpvas.renderWithWorker(); * document.body.appendChild(canvas); * } catch (error) { * console.error('Rendering failed:', error); * } * * @see setRenderingConfig Configure rendering options * @see render Synchronous rendering method */ renderWithWorker(caching?: boolean): Promise; /** * Dispose of Warpvas instance * * Clean up cached resources and references to free memory */ dispose(): void; }