@thi.ng/geom-axidraw
Version:
Conversion and preparation of thi.ng/geom shapes & shape groups to/from AxiDraw pen plotter draw commands
91 lines (90 loc) • 2.19 kB
JavaScript
import { group } from "@thi.ng/geom/group";
import { points } from "@thi.ng/geom/points";
import { polyline } from "@thi.ng/geom/polyline";
import { add2 } from "@thi.ng/vectors/add";
import { copy } from "@thi.ng/vectors/copy";
const DEFAULT_ATTRIBS = {
paths: { stroke: "#000" },
rapids: { stroke: "#0ff" },
ups: { fill: "#0f0", stroke: "none" },
downs: { fill: "#f00", stroke: "none" }
};
const asGeometry = (src, opts = {}) => {
opts = {
rapids: true,
pen: true,
...opts,
attribs: { ...DEFAULT_ATTRIBS, ...opts.attribs }
};
const rapids = [];
const paths = [];
const downs = [];
const ups = [];
let penDown = false;
let pts = null;
let currPos = [0, 0];
const $move = (newPos) => {
if (penDown || opts.rapids) {
if (!pts) pts = [copy(currPos), newPos];
else pts.push(newPos);
}
currPos = newPos;
};
for (let cmd of src) {
switch (cmd[0]) {
// absolute
case "M":
$move(copy(cmd[1]));
break;
// relative
case "m":
$move(add2([], currPos, cmd[1]));
break;
case "u":
if (pts) {
if (penDown) paths.push(pts);
else if (opts.rapids) rapids.push(pts);
pts = null;
}
if (opts.pen) ups.push(copy(currPos));
penDown = false;
break;
case "d":
if (pts) {
if (!penDown) {
if (opts.rapids) rapids.push(pts);
} else paths.push(pts);
pts = null;
}
if (opts.pen) downs.push(copy(currPos));
penDown = true;
break;
case "home":
currPos = [0, 0];
if (!pts) pts = [currPos];
else pts.push(currPos);
break;
default:
console.log("skipping command", cmd);
}
}
if (pts) {
if (penDown) paths.push(pts);
else rapids.push(pts);
}
return {
paths: group(
opts.attribs.paths,
paths.map((pts2) => polyline(pts2))
),
rapids: group(
opts.attribs.rapids,
rapids.map((pts2) => polyline(pts2))
),
ups: points(ups, opts.attribs.ups),
downs: points(downs, opts.attribs.downs)
};
};
export {
asGeometry
};