UNPKG

@avolutions/canvas-painter

Version:

CanvasPainter.js is a simple yet powerful JavaScript library for drawing basic shapes (rectangles, circles, etc.) on HTML5 Canvas with ease. Perfect for creating 2D graphics in your web projects.

166 lines (165 loc) 6.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Line = void 0; const InvalidConstructorArgumentsError_js_1 = require("../errors/InvalidConstructorArgumentsError.js"); const LineDefinition_js_1 = require("../definitions/LineDefinition.js"); const LineOptions_js_1 = require("../options/LineOptions.js"); const LineStyle_js_1 = require("../styles/LineStyle.js"); const Point_js_1 = require("../types/Point.js"); const Shape_js_1 = require("./Shape.js"); /** * Represents a line shape that extends the generic Shape class. * It uses LineDefinition for defining the start and end points, * LineStyle for styling, and LineOptions for additional options. */ class Line extends Shape_js_1.Shape { /** * Creates an instance of the `Line` class. * * The `Line` can be created either by passing two `Point` objects representing the start and end of the line, * or by providing the individual coordinates for the start and end points. * * @throws {@link InvalidConstructorArgumentsError} if invalid arguments are passed. */ constructor(arg1, arg2, arg3, arg4, arg5, arg6) { let definition; let style; let options; if (typeof arg1 === 'number' && typeof arg2 === 'number' && typeof arg3 === 'number' && typeof arg4 === 'number') { // Constructor with coordinates const start = new Point_js_1.Point(arg1, arg2); const end = new Point_js_1.Point(arg3, arg4); definition = new LineDefinition_js_1.LineDefinition(start, end); style = arg5; options = arg6; } else if (arg1 instanceof Point_js_1.Point && arg2 instanceof Point_js_1.Point) { // Constructor with Point objects definition = new LineDefinition_js_1.LineDefinition(arg1, arg2); style = arg3; options = arg4; } else { throw new InvalidConstructorArgumentsError_js_1.InvalidConstructorArgumentsError(); } super(definition, new LineStyle_js_1.LineStyle(style), new LineOptions_js_1.LineOptions(options)); } // Getters /** * Gets the starting point of the line. * * @returns The starting point of the line. */ get start() { return this._definition.start; } /** * Gets the ending point of the line. * * @returns The ending point of the line. */ get end() { return this._definition.end; } // Setters /** * Sets the starting point of the line. * * @param start - The new starting point of the line. */ set start(start) { this._definition.start = start; } /** * Sets the ending point of the line. * * @param end - The new ending point of the line. */ set end(end) { this._definition.end = end; } /** * Moves the start point of the line by the specified deltas along the x and y axes. * * @param deltaX - The amount to move the start point along the x-axis. * @param deltaY - The amount to move the start point along the y-axis. */ moveStart(deltaX = 0, deltaY = 0) { this.start.move(deltaX, deltaY); } /** * Moves the end point of the line by the specified deltas along the x and y axes. * * @param deltaX - The amount to move the end point along the x-axis. * @param deltaY - The amount to move the end point along the y-axis. */ moveEnd(deltaX = 0, deltaY = 0) { this.end.move(deltaX, deltaY); } /** * Moves the start & end point of the line by the specified deltas along the x and y axes. * * @param deltaX - The amount to move the start & end point along the x-axis. * @param deltaY - The amount to move the start & end point along the y-axis. */ move(deltaX = 0, deltaY = 0) { this.moveStart(deltaX, deltaY); this.moveEnd(deltaX, deltaY); } /** * Renders the line on a canvas context. * * @param context - The canvas rendering context to draw the line. */ render(context) { context.save(); // Save the current canvas state context.lineWidth = this.stateStyle.width; context.strokeStyle = this.stateStyle.color; context.beginPath(); context.moveTo(this.start.x, this.start.y); context.lineTo(this.end.x, this.end.y); context.stroke(); context.restore(); // Restore the canvas state to before the transformations } /** * Determines if the mouse is currently over the shape. * * @param mousePosition - The current mouse position. * @returns True if the mouse is over the shape, false otherwise. */ isMouseOver(mousePosition) { // Get the line width and calculate the tolerance distance const lineWidth = this.stateStyle.width / 2; // Calculate the vector components for the line and the point-to-start vector const dx = this.end.x - this.start.x; const dy = this.end.y - this.start.y; const lengthSquared = dx * dx + dy * dy; // If the line is effectively a point (start and end are the same), just check distance to the point if (lengthSquared === 0) { const distanceToStart = Math.hypot(mousePosition.x - this.start.x, mousePosition.y - this.start.y); return distanceToStart <= lineWidth; } // Project the mouse position onto the line to find the closest point const t = ((mousePosition.x - this.start.x) * dx + (mousePosition.y - this.start.y) * dy) / lengthSquared; // Ensure t is within the segment [0, 1] to restrict the closest point to the line segment if (t < 0 || t > 1) { return false; } // Calculate the closest point on the line segment to the mouse position const closestX = this.start.x + t * dx; const closestY = this.start.y + t * dy; // Calculate the distance from the mouse position to the closest point const distanceToLine = Math.hypot(mousePosition.x - closestX, mousePosition.y - closestY); // Check if this distance is within the tolerance (half the line width) return distanceToLine <= lineWidth; } /** * Handles the drag operation by applying the given delta to the current position. * * @param delta - The change in position represented as a `Point`. */ onDrag(delta) { this.move(delta.x, delta.y); } } exports.Line = Line;