UNPKG

js-draw

Version:

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

82 lines (81 loc) 3.39 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeOutlinedCircleBuilder = void 0; const math_1 = require("@js-draw/math"); const RenderablePathSpec_1 = require("../../rendering/RenderablePathSpec"); const Viewport_1 = __importDefault(require("../../Viewport")); const Stroke_1 = __importDefault(require("../Stroke")); const makeSnapToGridAutocorrect_1 = __importDefault(require("./autocorrect/makeSnapToGridAutocorrect")); /** * Creates a stroke builder that generates outlined circles. * * Example: * [[include:doc-pages/inline-examples/changing-pen-types.md]] */ exports.makeOutlinedCircleBuilder = (0, makeSnapToGridAutocorrect_1.default)((initialPoint, viewport) => { return new CircleBuilder(initialPoint, viewport); }); class CircleBuilder { constructor(startPoint, viewport) { this.startPoint = startPoint; this.viewport = viewport; // Initially, the start and end points are the same. this.endPoint = startPoint; } getBBox() { const preview = this.buildPreview(); return preview.getBBox(); } buildPreview() { const pathCommands = []; const numDivisions = 6; const stepSize = (Math.PI * 2) / numDivisions; // Round the stroke width so that when exported it doesn't have unnecessary trailing decimals. const strokeWidth = Viewport_1.default.roundPoint(this.endPoint.width, 5 / this.viewport.getScaleFactor()); const center = this.startPoint.pos.lerp(this.endPoint.pos, 0.5); const startEndDelta = this.endPoint.pos.minus(center); const radius = startEndDelta.length() - strokeWidth / 2; const startPoint = center.plus(math_1.Vec2.of(radius, 0)); for (let t = stepSize; t <= Math.PI * 2; t += stepSize) { const endPoint = math_1.Vec2.of(radius * Math.cos(t), -radius * Math.sin(t)).plus(center); // controlPointRadiusScale is selected to make the circles appear circular and // **does** depend on stepSize. const controlPointRadiusScale = 1.141; const controlPoint = math_1.Vec2.of(Math.cos(t - stepSize / 2), -Math.sin(t - stepSize / 2)) .times(radius * controlPointRadiusScale) .plus(center); pathCommands.push({ kind: math_1.PathCommandType.QuadraticBezierTo, controlPoint, endPoint, }); } pathCommands.push({ kind: math_1.PathCommandType.LineTo, point: startPoint, }); const path = new math_1.Path(startPoint, pathCommands).mapPoints((point) => this.viewport.roundPoint(point)); const preview = new Stroke_1.default([ (0, RenderablePathSpec_1.pathToRenderable)(path, { fill: math_1.Color4.transparent, stroke: { width: strokeWidth, color: this.endPoint.color, }, }), ]); return preview; } build() { return this.buildPreview(); } preview(renderer) { this.buildPreview().render(renderer); } addPoint(point) { this.endPoint = point; } }