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
JavaScript
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;
}
}
;