Skip to content

Commit

Permalink
feat(geom): add PathBuilderOpts, update Path.toHiccup()
Browse files Browse the repository at this point in the history
- add support to disable auto-splitting paths in PathBuilder
- update toHiccup() impl to support multiple `M` cmds
  • Loading branch information
postspectacular committed Jul 13, 2020
1 parent ad72de3 commit deb9892
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 16 deletions.
23 changes: 12 additions & 11 deletions packages/geom/src/api/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ import { copyAttribs } from "../internal/copy-attribs";
import { copy } from "@thi.ng/vectors";

export class Path implements IHiccupShape {
segments: PathSegment[];
closed: boolean;
attribs?: Attribs;
closed = false;

constructor(segments?: PathSegment[], attribs?: Attribs) {
this.segments = segments || [];
this.attribs = attribs;
this.closed = false;
}
constructor(
public segments: PathSegment[] = [],
public attribs?: Attribs
) {}

get type() {
return Type.PATH;
Expand Down Expand Up @@ -51,9 +48,13 @@ export class Path implements IHiccupShape {
const segments = this.segments;
const n = segments.length;
if (n > 1) {
dest.push(["M", segments[0].point]);
for (let i = 1; i < n; i++) {
dest = dest.concat(segments[i].geo!.toHiccupPathSegments());
for (let i = 0; i < n; i++) {
const s = segments[i];
if (s.geo) {
dest = dest.concat(s.geo!.toHiccupPathSegments());
} else if (s.point) {
dest.push(["M", s.point]);
}
}
if (this.closed) {
dest.push(["Z"]);
Expand Down
27 changes: 22 additions & 5 deletions packages/geom/src/ctors/path-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,29 @@ import { Path } from "../api/path";
import { Quadratic } from "../api/quadratic";
import { arcFrom2Points } from "./arc";

export interface PathBuilderOpts {
/**
* If true (default), "move" commands will start a new path and
* {@link PathBuilder} might produce multiple {@link Path}s. In general,
* it's NOT recommended to disable this behavior since various path related
* operations will not function properly anymore. However, there're some use
* cases where auto-splitting is undesirable and this option primarily
* exists for those.
*/
autoSplit: boolean;
}

export class PathBuilder {
paths: Path[];
attribs?: Attribs;
protected curr!: Path;
protected currP!: Vec;
protected bezierP!: Vec;
protected startP!: Vec;

constructor(attribs?: Attribs) {
constructor(
public attribs?: Attribs,
public opts: Partial<PathBuilderOpts> = {}
) {
this.paths = [];
this.attribs = attribs;
this.newPath();
Expand All @@ -39,8 +53,8 @@ export class PathBuilder {
}

moveTo(p: Vec, relative = false): PathBuilder {
if (this.curr.segments.length > 0) {
this.curr = new Path();
if (this.opts.autoSplit !== false && this.curr.segments.length > 0) {
this.curr = new Path([], this.attribs);
this.paths.push(this.curr);
}
p = this.updateCurrent(p, relative);
Expand Down Expand Up @@ -184,4 +198,7 @@ export class PathBuilder {
}
}

export const pathBuilder = (attribs?: Attribs) => new PathBuilder(attribs);
export const pathBuilder = (
attribs?: Attribs,
opts?: Partial<PathBuilderOpts>
) => new PathBuilder(attribs, opts);

0 comments on commit deb9892

Please sign in to comment.