or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

additional-components.mdcanvas-operations.mdimage-manipulation.mdindex.mdjavascript-api.mdselection-management.mdutility-functions.md
tile.json

selection-management.mddocs/

Selection Management

Crop selection areas with precise control over dimensions, aspect ratios, and interactive handles. The CropperSelection element defines the crop area and provides methods for positioning, resizing, and exporting the selected region.

Capabilities

CropperSelection Element

Selection area element that defines crop boundaries with interactive controls.

/**
 * Selection area element for defining crop boundaries
 * Extends CropperElement with selection-specific functionality
 */
class CropperSelection extends CropperElement {
  /**
   * X position of the selection in pixels
   * @default 0
   */
  x: number;
  
  /**
   * Y position of the selection in pixels
   * @default 0
   */
  y: number;
  
  /**
   * Width of the selection in pixels
   * @default 0
   */
  width: number;
  
  /**
   * Height of the selection in pixels
   * @default 0
   */
  height: number;
  
  /**
   * Current aspect ratio constraint (width/height)
   * Set to 0 for no constraint
   * @default 0
   */
  aspectRatio: number;
  
  /**
   * Initial aspect ratio when selection is created
   * @default 0
   */
  initialAspectRatio: number;
  
  /**
   * Initial coverage percentage (0-1) of the container
   * @default 0.5
   */
  initialCoverage: number;
  
  /**
   * Whether the selection is currently active
   * @default false
   */
  active: boolean;
  
  /**
   * Whether the selection updates dynamically during interactions
   * @default true
   */
  dynamic: boolean;
  
  /**
   * Whether the selection can be moved
   * @default true
   */
  movable: boolean;
  
  /**
   * Whether the selection can be resized
   * @default true
   */
  resizable: boolean;
  
  /**
   * Whether the selection can be zoomed
   * @default true
   */
  zoomable: boolean;
  
  /**
   * Whether multiple selections are allowed
   * @default false
   */
  multiple: boolean;
  
  /**
   * Whether keyboard controls are enabled
   * @default true
   */
  keyboard: boolean;
  
  /**
   * Whether selection has an outline
   * @default false
   */
  outlined: boolean;
  
  /**
   * Whether to use precise positioning
   * @default false
   */
  precise: boolean;
}

Selection Positioning

Position and move selection areas within the cropper canvas.

/**
 * Center the selection within the container
 * @returns This instance for method chaining
 */
$center(): this;

/**
 * Move the selection by a relative offset
 * @param x - Horizontal offset in pixels
 * @param y - Vertical offset in pixels (defaults to 0)
 * @returns This instance for method chaining
 */
$move(x: number, y?: number): this;

/**
 * Move the selection to an absolute position
 * @param x - Horizontal position in pixels
 * @param y - Vertical position in pixels (defaults to 0)
 * @returns This instance for method chaining
 */
$moveTo(x: number, y?: number): this;

Usage Examples:

const selection = cropper.getCropperSelection();

// Center the selection
selection.$center();

// Move by offset
selection.$move(25, 15);  // Move right 25px, down 15px
selection.$move(-10, 20); // Move left 10px, down 20px

// Move to absolute position
selection.$moveTo(100, 80);  // Position at (100, 80)
selection.$moveTo(200, 150); // Position at (200, 150)

// Chain operations
selection.$center().$move(0, -20); // Center then move up 20px

Selection Resizing

Resize selection areas with precise control and aspect ratio constraints.

/**
 * Resize the selection from a specific action point
 * @param action - Resize action (direction: 'n-resize', 'se-resize', etc.)
 * @param offsetX - Horizontal resize offset
 * @param offsetY - Vertical resize offset (defaults to 0)
 * @param aspectRatio - Aspect ratio to maintain during resize (optional)
 * @returns This instance for method chaining
 */
$resize(action: string, offsetX?: number, offsetY?: number, aspectRatio?: number): this;

/**
 * Zoom the selection by a scale factor
 * @param scale - Scale factor (1.0 = no change, 2.0 = double size)
 * @param x - Center X coordinate for scaling (defaults to selection center)
 * @param y - Center Y coordinate for scaling (defaults to selection center)
 * @returns This instance for method chaining
 */
$zoom(scale: number, x?: number, y?: number): this;

Usage Examples:

const selection = cropper.getCropperSelection();

// Resize from different directions
selection.$resize('se-resize', 50, 30);    // Resize from southeast corner
selection.$resize('n-resize', 0, -20);     // Resize from north edge
selection.$resize('w-resize', -15);        // Resize from west edge

// Resize with aspect ratio constraint
selection.$resize('se-resize', 50, 0, 16/9); // Maintain 16:9 aspect ratio

// Zoom selection
selection.$zoom(1.5);          // 150% size
selection.$zoom(0.8);          // 80% size
selection.$zoom(2.0, 200, 150); // Double size around point (200, 150)

Selection Management

Modify selection dimensions and state with comprehensive control.

/**
 * Change selection dimensions and position
 * @param x - X position in pixels
 * @param y - Y position in pixels
 * @param width - Width in pixels (optional)
 * @param height - Height in pixels (optional)
 * @param aspectRatio - Aspect ratio to maintain (optional)
 * @param _force - Internal parameter for forcing updates
 * @returns This instance for method chaining
 */
$change(x: number, y: number, width?: number, height?: number, aspectRatio?: number, _force?: boolean): this;

/**
 * Reset selection to initial state
 * @returns This instance for method chaining
 */
$reset(): this;

/**
 * Clear the selection (set dimensions to zero)
 * @returns This instance for method chaining
 */
$clear(): this;

/**
 * Render/update the selection display
 * @returns This instance for method chaining
 */
$render(): this;

Usage Examples:

const selection = cropper.getCropperSelection();

// Set specific dimensions and position  
selection.$change(50, 30, 200, 150);        // Position (50,30), size 200x150
selection.$change(100, 100, 300, 200, 16/9); // With 16:9 aspect ratio

// Change only position
selection.$change(75, 60);                   // Move to (75, 60), keep size

// Reset to original state
selection.$reset();

// Clear selection
selection.$clear();

// Force re-render
selection.$render();

// Common workflow
selection
  .$clear()                    // Start fresh
  .$change(50, 50, 200, 150)   // Set initial size/position
  .$center()                   // Center it
  .$render();                  // Update display

Selection Export

Generate canvas output from the selected area.

/**
 * Generate a canvas containing only the selected area
 * @param options - Canvas generation options
 * @returns Promise resolving to canvas with the selected region
 */
$toCanvas(options?: CanvasOptions): Promise<HTMLCanvasElement>;

/**
 * Options for selection canvas generation
 */
interface CanvasOptions {
  /**
   * Width of the output canvas
   * If not specified, uses the selection width
   */
  width?: number;
  
  /**
   * Height of the output canvas
   * If not specified, uses the selection height
   */
  height?: number;
  
  /**
   * Callback called before drawing
   * Useful for custom backgrounds or effects
   */
  beforeDraw?: (context: CanvasRenderingContext2D, canvas: HTMLCanvasElement) => void;
}

Usage Examples:

const selection = cropper.getCropperSelection();

// Export selection at original size
const canvas = await selection.$toCanvas();
document.body.appendChild(canvas);

// Export at specific size
const thumbnail = await selection.$toCanvas({
  width: 150,
  height: 100
});

// Export with custom background
const exportCanvas = await selection.$toCanvas({
  width: 400,
  height: 300,
  beforeDraw: (context, canvas) => {
    // Add gradient background
    const gradient = context.createLinearGradient(0, 0, canvas.width, canvas.height);
    gradient.addColorStop(0, '#f0f0f0');
    gradient.addColorStop(1, '#ffffff');
    context.fillStyle = gradient;
    context.fillRect(0, 0, canvas.width, canvas.height);
  }
});

// Export for different use cases
async function exportForWeb() {
  return await selection.$toCanvas({
    width: 800,
    height: 600
  });
}

async function exportThumbnail() {
  return await selection.$toCanvas({
    width: 200,
    height: 150
  });
}

Aspect Ratio Management

Control aspect ratio constraints and behavior.

const selection = cropper.getCropperSelection();

// Set aspect ratio constraints
selection.aspectRatio = 16/9;        // Widescreen
selection.aspectRatio = 4/3;         // Traditional photo
selection.aspectRatio = 1;           // Square
selection.aspectRatio = 3/4;         // Portrait
selection.aspectRatio = 0;           // No constraint

// Configure initial aspect ratio
selection.initialAspectRatio = 16/9;  // Default ratio for new selections

// Common aspect ratios
const ASPECT_RATIOS = {
  square: 1,
  widescreen: 16/9,
  ultrawide: 21/9,
  photo: 4/3,
  portrait: 3/4,
  golden: 1.618
};

// Apply with resize
selection.aspectRatio = ASPECT_RATIOS.widescreen;
selection.$change(50, 50, 320, 180); // Will maintain 16:9 ratio

Multiple Selections

Handle multiple selection areas when enabled.

const cropper = new Cropper('#image');
const selections = cropper.getCropperSelections();

if (selections && selections.length > 1) {
  // Process multiple selections
  Array.from(selections).forEach((selection, index) => {
    console.log(`Selection ${index}:`, {
      x: selection.x,
      y: selection.y,
      width: selection.width,
      height: selection.height,
      aspectRatio: selection.aspectRatio
    });
    
    // Configure each selection
    selection.movable = true;
    selection.resizable = true;
    selection.outlined = true;
  });
}

// Export all selections
async function exportAllSelections() {
  const selections = cropper.getCropperSelections();
  const canvases = [];
  
  if (selections) {
    for (const selection of selections) {
      const canvas = await selection.$toCanvas();
      canvases.push(canvas);
    }
  }
  
  return canvases;
}

Selection Interface

Type definition for selection data.

/**
 * Selection data interface
 */
interface Selection {
  /** X position in pixels */
  x: number;
  /** Y position in pixels */
  y: number;
  /** Width in pixels */
  width: number;
  /** Height in pixels */  
  height: number;
}

Resize Action Constants

// Resize actions for the $resize method
const ACTION_RESIZE_NORTH: string;     // 'n-resize'
const ACTION_RESIZE_EAST: string;      // 'e-resize'  
const ACTION_RESIZE_SOUTH: string;     // 's-resize'
const ACTION_RESIZE_WEST: string;      // 'w-resize'
const ACTION_RESIZE_NORTHEAST: string; // 'ne-resize'
const ACTION_RESIZE_NORTHWEST: string; // 'nw-resize'
const ACTION_RESIZE_SOUTHEAST: string; // 'se-resize'
const ACTION_RESIZE_SOUTHWEST: string; // 'sw-resize'

Event Handling

Selection elements emit events during user interactions:

const selection = cropper.getCropperSelection();

// Listen for selection changes
selection.addEventListener('change', (event) => {
  console.log('Selection changed:', {
    x: selection.x,
    y: selection.y,
    width: selection.width,
    height: selection.height
  });
});

// Listen for selection activation
selection.addEventListener('actionstart', (event) => {
  selection.active = true;
  console.log('Selection activated');
});

selection.addEventListener('actionend', (event) => {
  selection.active = false;
  console.log('Selection deactivated');
});

Error Handling

Selection operations may have constraints and validation:

const selection = cropper.getCropperSelection();

// Check capabilities before operations
if (selection.movable) {
  selection.$move(50, 30);
} else {
  console.log('Selection movement is disabled');
}

if (selection.resizable) {
  selection.$resize('se-resize', 50, 30);
} else {
  console.log('Selection resizing is disabled');
}

// Validate aspect ratio constraints
if (selection.aspectRatio > 0) {
  console.log('Aspect ratio is constrained to:', selection.aspectRatio);
}