UNPKG

js-draw

Version:

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

65 lines (64 loc) 2.41 kB
import { Mat33, Rect2, Path } from '@js-draw/math'; import { pathToRenderable } from '../../rendering/RenderablePathSpec.mjs'; import Stroke from '../Stroke.mjs'; import makeSnapToGridAutocorrect from './autocorrect/makeSnapToGridAutocorrect.mjs'; /** * Creates filled rectangles with sharp corners. * * Example: * [[include:doc-pages/inline-examples/changing-pen-types.md]] */ export const makeFilledRectangleBuilder = makeSnapToGridAutocorrect((initialPoint, viewport) => { return new RectangleBuilder(initialPoint, true, viewport); }); /** * Creates outlined rectangles with sharp corners. * * Example: * [[include:doc-pages/inline-examples/changing-pen-types.md]] */ export const makeOutlinedRectangleBuilder = makeSnapToGridAutocorrect((initialPoint, viewport) => { return new RectangleBuilder(initialPoint, false, viewport); }); export default class RectangleBuilder { constructor(startPoint, filled, viewport) { this.startPoint = startPoint; this.filled = filled; 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 canvasAngle = this.viewport.getRotationAngle(); const rotationMat = Mat33.zRotation(-canvasAngle); // Adjust startPoint and endPoint such that applying [rotationMat] to them // brings them to this.startPoint and this.endPoint. const startPoint = rotationMat.inverse().transformVec2(this.startPoint.pos); const endPoint = rotationMat.inverse().transformVec2(this.endPoint.pos); const rect = Rect2.fromCorners(startPoint, endPoint); const path = Path.fromRect(rect, this.filled ? null : this.endPoint.width) .transformedBy( // Rotate the canvas rectangle so that its rotation matches the screen rotationMat) .mapPoints((point) => this.viewport.roundPoint(point)); const preview = new Stroke([ pathToRenderable(path, { fill: this.endPoint.color, }), ]); return preview; } build() { return this.buildPreview(); } preview(renderer) { this.buildPreview().render(renderer); } addPoint(point) { this.endPoint = point; } }