UNPKG

js-draw

Version:

Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript.

101 lines (100 loc) 3.75 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeArrowBuilder = void 0; const math_1 = require("@js-draw/math"); const Stroke_1 = __importDefault(require("../Stroke")); const makeSnapToGridAutocorrect_1 = __importDefault(require("./autocorrect/makeSnapToGridAutocorrect")); /** * Creates a stroke builder that generates arrows. * * Example: * [[include:doc-pages/inline-examples/changing-pen-types.md]] */ exports.makeArrowBuilder = (0, makeSnapToGridAutocorrect_1.default)((initialPoint, viewport) => { return new ArrowBuilder(initialPoint, viewport); }); class ArrowBuilder { constructor(startPoint, viewport) { this.startPoint = startPoint; this.viewport = viewport; this.endPoint = startPoint; } getLineWidth() { return Math.max(this.endPoint.width, this.startPoint.width); } getBBox() { const preview = this.buildPreview(); return preview.getBBox(); } buildPreview() { const lineStartPoint = this.startPoint.pos; const endPoint = this.endPoint.pos; const toEnd = endPoint.minus(lineStartPoint).normalized(); const arrowLength = endPoint.distanceTo(lineStartPoint); // Ensure that the arrow tip is smaller than the arrow. const arrowTipSize = Math.min(this.getLineWidth(), arrowLength / 2); const startSize = this.startPoint.width / 2; const endSize = this.endPoint.width / 2; const arrowTipBase = endPoint.minus(toEnd.times(arrowTipSize)); // Scaled normal vectors. const lineNormal = toEnd.orthog(); const scaledStartNormal = lineNormal.times(startSize); const scaledBaseNormal = lineNormal.times(endSize); const path = new math_1.Path(arrowTipBase.minus(scaledBaseNormal), [ // Stem { kind: math_1.PathCommandType.LineTo, point: lineStartPoint.minus(scaledStartNormal), }, { kind: math_1.PathCommandType.LineTo, point: lineStartPoint.plus(scaledStartNormal), }, { kind: math_1.PathCommandType.LineTo, point: arrowTipBase.plus(scaledBaseNormal), }, // Head { kind: math_1.PathCommandType.LineTo, point: arrowTipBase.plus(lineNormal.times(arrowTipSize).plus(scaledBaseNormal)), }, { kind: math_1.PathCommandType.LineTo, point: endPoint.plus(toEnd.times(endSize)), }, { kind: math_1.PathCommandType.LineTo, point: arrowTipBase.plus(lineNormal.times(-arrowTipSize).minus(scaledBaseNormal)), }, { kind: math_1.PathCommandType.LineTo, point: arrowTipBase.minus(scaledBaseNormal), }, // Round all points in the arrow (to remove unnecessary decimal places) ]).mapPoints((point) => this.viewport.roundPoint(point)); const preview = new Stroke_1.default([ { startPoint: path.startPoint, commands: path.parts, style: { fill: this.startPoint.color, }, }, ]); return preview; } build() { return this.buildPreview(); } preview(renderer) { this.buildPreview().render(renderer); } addPoint(point) { this.endPoint = point; } } exports.default = ArrowBuilder;