UNPKG

@ue-too/board

Version:

<h1 align="center"> uē-tôo </h1> <p align="center"> pan, zoom, rotate, and more with your html canvas. </p>

179 lines (178 loc) 6.65 kB
import { Point } from "@ue-too/math"; /** * Draws an arrow from start to end point with an arrowhead. * * @param context - The canvas 2D rendering context * @param cameraZoomLevel - Current camera zoom level for scale-independent sizing * @param startPoint - Arrow tail position in world coordinates * @param endPoint - Arrow head position in world coordinates * @param width - Line width in world units (default: 1) * @param arrowRatio - Ratio of arrowhead size to total length (default: 0.3, unused in implementation) * * @remarks * The arrow consists of a line segment and a triangular arrowhead. The arrowhead * size is adaptive: * - Maximum 10 pixels in viewport space * - Minimum half the arrow length * * This ensures arrows look good at all zoom levels and lengths. * * The arrowhead is constructed perpendicular to the arrow direction, creating * a filled triangle at the end point. * * @example * ```typescript * const ctx = canvas.getContext('2d'); * const zoom = 1.5; * * // Draw a simple arrow * ctx.fillStyle = 'blue'; * ctx.strokeStyle = 'blue'; * drawArrow(ctx, zoom, { x: 0, y: 0 }, { x: 100, y: 50 }); * * // Draw a thicker arrow * ctx.fillStyle = 'red'; * ctx.strokeStyle = 'red'; * drawArrow(ctx, zoom, { x: 0, y: 0 }, { x: 100, y: -50 }, 3); * ``` * * @category Drawing Utilities */ export declare function drawArrow(context: CanvasRenderingContext2D, cameraZoomLevel: number, startPoint: Point, endPoint: Point, width?: number, arrowRatio?: number): void; /** * Length of major tick marks in pixels (viewport space). * @category Drawing Utilities */ export declare const MAJOR_TICK_LENGTH = 30; /** * Length of minor tick marks in pixels (viewport space). * @category Drawing Utilities */ export declare const MINOR_TICK_LENGTH: number; /** * Length of half-step tick marks in pixels (viewport space). * @category Drawing Utilities */ export declare const HALF_TICK_LENGTH: number; /** * Offset for major tick labels in pixels (viewport space). * @category Drawing Utilities */ export declare const TEXT_MAJOR_TICK_OFFSET = 10; /** * Offset for half-step tick labels in pixels (viewport space). * @category Drawing Utilities */ export declare const TEXT_HALF_TICK_OFFSET = 2.5; /** * Font size for major tick labels in pixels (viewport space). * @category Drawing Utilities */ export declare const TEXT_MAJOR_TICK_FONT_SIZE = 20; /** * Font size for half-step tick labels in pixels (viewport space). * @category Drawing Utilities */ export declare const TEXT_HALF_TICK_FONT_SIZE = 10; /** * Draws calibrated rulers along the edges of the viewport. * * @param context - The canvas 2D rendering context * @param topLeftCorner - Top-left corner of viewport in world coordinates * @param topRightCorner - Top-right corner of viewport in world coordinates * @param bottomLeftCorner - Bottom-left corner of viewport in world coordinates * @param alignCoordinateSystem - Whether coordinates align with canvas (y-down) or are mathematical (y-up) * @param cameraZoomLevel - Current camera zoom level * * @remarks * This function draws rulers with three levels of tick marks: * - Major ticks: At powers of 10 (1, 10, 100, etc.) with large labels * - Half ticks: At half-steps (5, 50, 500, etc.) with small labels * - Minor ticks: At 1/10 steps with no labels * * The ruler automatically adapts to the zoom level by calculating appropriate * tick spacing using {@link calculateOrderOfMagnitude} and {@link calculateTickValues}. * * Rulers are drawn along: * - Top edge (horizontal ruler, red) * - Left edge (vertical ruler, green) * * Tick positions are calibrated to align with round numbers in world space, * making it easy to read coordinates at any zoom level. * * @example * ```typescript * const ctx = canvas.getContext('2d'); * const zoom = 2.0; * * // Viewport corners in world space * const topLeft = { x: -100, y: 100 }; * const topRight = { x: 100, y: 100 }; * const bottomLeft = { x: -100, y: -100 }; * * drawRuler(ctx, topLeft, topRight, bottomLeft, false, zoom); * // Draws rulers with ticks at -100, -50, 0, 50, 100 * ``` * * @category Drawing Utilities * @see {@link calculateTickValues} for tick calculation logic * @see {@link calculateOrderOfMagnitude} for order of magnitude calculation */ export declare function drawRuler(context: CanvasRenderingContext2D, topLeftCorner: Point, topRightCorner: Point, bottomLeftCorner: Point, alignCoordinateSystem: boolean, cameraZoomLevel: number): void; /** * Calculates tick mark positions and spacing for a ruler. * * @param minValue - Minimum value on the ruler axis * @param maxValue - Maximum value on the ruler axis * @param orderOfMagnitude - Optional pre-calculated order of magnitude (for consistency across axes) * @returns Object containing tick positions and spacing for major, half, and minor ticks * * @remarks * This function determines where to place tick marks on a ruler to show round * numbers at appropriate intervals. It calculates three levels of ticks: * * 1. Major ticks: At powers of 10 (step = 10^n) * 2. Half ticks: At half the major step (step = 5×10^(n-1)) * 3. Minor ticks: At 1/10 the major step (step = 10^(n-1)) * * The calibration multiplier handles cases where the order of magnitude is very * small (< 1), ensuring tick positions are calculated correctly for zoomed-in views. * * For consistency between x and y axes, you can provide a pre-calculated * orderOfMagnitude. Otherwise, it's calculated from the range width. * * @example * ```typescript * // Ruler showing -100 to 100 * const ticks = calculateTickValues(-100, 100); * // Result: * // majorTickStep: 100 * // minMajorTickValue: -100, maxMajorTickValue: 100 * // halfTickStep: 50 * // minorTickStep: 10 * // calibrationMultiplier: 1 * * // Zoomed in view: 0.001 to 0.01 * const zoomedTicks = calculateTickValues(0.001, 0.01); * // Result: * // majorTickStep: 10 (calibrated) * // calibrationMultiplier: 0.001 (multiply tick values by this) * ``` * * @category Drawing Utilities * @see {@link calculateOrderOfMagnitude} for order calculation * @see {@link drawRuler} for usage in ruler drawing */ export declare function calculateTickValues(minValue: number, maxValue: number, orderOfMagnitude?: number): { minMajorTickValue: number; maxMajorTickValue: number; majorTickStep: number; minMinTickValue: number; maxMaxTickValue: number; minTickStep: number; minHalfTickValue: number; maxHalfTickValue: number; halfTickStep: number; calibrationMultiplier: number; normalizedOrderOfMagnitude: number; };