mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-30 11:40:27 +02:00
renamed graphics-element dir
This commit is contained in:
226
docs/js/graphics-element/lib/bezierjs/normalise-svg.js
Normal file
226
docs/js/graphics-element/lib/bezierjs/normalise-svg.js
Normal file
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* Normalise an SVG path to absolute coordinates
|
||||
* and full commands, rather than relative coordinates
|
||||
* and/or shortcut commands.
|
||||
*/
|
||||
export default function normalizePath(d) {
|
||||
// preprocess "d" so that we have spaces between values
|
||||
d = d
|
||||
.replace(/,/g, " ") // replace commas with spaces
|
||||
.replace(/-/g, " - ") // add spacing around minus signs
|
||||
.replace(/-\s+/g, "-") // remove spacing to the right of minus signs.
|
||||
.replace(/([a-zA-Z])/g, " $1 ");
|
||||
|
||||
// set up the variables used in this function
|
||||
const instructions = d.replace(/([a-zA-Z])\s?/g, "|$1").split("|"),
|
||||
instructionLength = instructions.length;
|
||||
|
||||
let i,
|
||||
instruction,
|
||||
op,
|
||||
lop,
|
||||
args = [],
|
||||
alen,
|
||||
a,
|
||||
sx = 0,
|
||||
sy = 0,
|
||||
x = 0,
|
||||
y = 0,
|
||||
cx = 0,
|
||||
cy = 0,
|
||||
cx2 = 0,
|
||||
cy2 = 0,
|
||||
rx = 0,
|
||||
ry = 0,
|
||||
xrot = 0,
|
||||
lflag = 0,
|
||||
sweep = 0,
|
||||
normalized = "";
|
||||
|
||||
// we run through the instruction list starting at 1, not 0,
|
||||
// because we split up "|M x y ...." so the first element will
|
||||
// always be an empty string. By design.
|
||||
for (i = 1; i < instructionLength; i++) {
|
||||
// which instruction is this?
|
||||
instruction = instructions[i];
|
||||
op = instruction.substring(0, 1);
|
||||
lop = op.toLowerCase();
|
||||
|
||||
// what are the arguments? note that we need to convert
|
||||
// all strings into numbers, or + will do silly things.
|
||||
args = instruction.replace(op, "").trim().split(" ");
|
||||
args = args
|
||||
.filter(function (v) {
|
||||
return v !== "";
|
||||
})
|
||||
.map(parseFloat);
|
||||
alen = args.length;
|
||||
|
||||
// we could use a switch, but elaborate code in a "case" with
|
||||
// fallthrough is just horrid to read. So let's use ifthen
|
||||
// statements instead.
|
||||
|
||||
// moveto command (plus possible lineto)
|
||||
if (lop === "m") {
|
||||
normalized += "M ";
|
||||
if (op === "m") {
|
||||
x += args[0];
|
||||
y += args[1];
|
||||
} else {
|
||||
x = args[0];
|
||||
y = args[1];
|
||||
}
|
||||
// records start position, for dealing
|
||||
// with the shape close operator ('Z')
|
||||
sx = x;
|
||||
sy = y;
|
||||
normalized += x + " " + y + " ";
|
||||
if (alen > 2) {
|
||||
for (a = 0; a < alen; a += 2) {
|
||||
if (op === "m") {
|
||||
x += args[a];
|
||||
y += args[a + 1];
|
||||
} else {
|
||||
x = args[a];
|
||||
y = args[a + 1];
|
||||
}
|
||||
normalized += "L " + x + " " + y + " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// lineto commands
|
||||
else if (lop === "l") {
|
||||
for (a = 0; a < alen; a += 2) {
|
||||
if (op === "l") {
|
||||
x += args[a];
|
||||
y += args[a + 1];
|
||||
} else {
|
||||
x = args[a];
|
||||
y = args[a + 1];
|
||||
}
|
||||
normalized += "L " + x + " " + y + " ";
|
||||
}
|
||||
} else if (lop === "h") {
|
||||
for (a = 0; a < alen; a++) {
|
||||
if (op === "h") {
|
||||
x += args[a];
|
||||
} else {
|
||||
x = args[a];
|
||||
}
|
||||
normalized += "L " + x + " " + y + " ";
|
||||
}
|
||||
} else if (lop === "v") {
|
||||
for (a = 0; a < alen; a++) {
|
||||
if (op === "v") {
|
||||
y += args[a];
|
||||
} else {
|
||||
y = args[a];
|
||||
}
|
||||
normalized += "L " + x + " " + y + " ";
|
||||
}
|
||||
}
|
||||
|
||||
// quadratic curveto commands
|
||||
else if (lop === "q") {
|
||||
for (a = 0; a < alen; a += 4) {
|
||||
if (op === "q") {
|
||||
cx = x + args[a];
|
||||
cy = y + args[a + 1];
|
||||
x += args[a + 2];
|
||||
y += args[a + 3];
|
||||
} else {
|
||||
cx = args[a];
|
||||
cy = args[a + 1];
|
||||
x = args[a + 2];
|
||||
y = args[a + 3];
|
||||
}
|
||||
normalized += "Q " + cx + " " + cy + " " + x + " " + y + " ";
|
||||
}
|
||||
} else if (lop === "t") {
|
||||
for (a = 0; a < alen; a += 2) {
|
||||
// reflect previous cx/cy over x/y
|
||||
cx = x + (x - cx);
|
||||
cy = y + (y - cy);
|
||||
// then get real end point
|
||||
if (op === "t") {
|
||||
x += args[a];
|
||||
y += args[a + 1];
|
||||
} else {
|
||||
x = args[a];
|
||||
y = args[a + 1];
|
||||
}
|
||||
normalized += "Q " + cx + " " + cy + " " + x + " " + y + " ";
|
||||
}
|
||||
}
|
||||
|
||||
// cubic curveto commands
|
||||
else if (lop === "c") {
|
||||
for (a = 0; a < alen; a += 6) {
|
||||
if (op === "c") {
|
||||
cx = x + args[a];
|
||||
cy = y + args[a + 1];
|
||||
cx2 = x + args[a + 2];
|
||||
cy2 = y + args[a + 3];
|
||||
x += args[a + 4];
|
||||
y += args[a + 5];
|
||||
} else {
|
||||
cx = args[a];
|
||||
cy = args[a + 1];
|
||||
cx2 = args[a + 2];
|
||||
cy2 = args[a + 3];
|
||||
x = args[a + 4];
|
||||
y = args[a + 5];
|
||||
}
|
||||
normalized += "C " + cx + " " + cy + " " + cx2 + " " + cy2 + " " + x + " " + y + " ";
|
||||
}
|
||||
} else if (lop === "s") {
|
||||
for (a = 0; a < alen; a += 4) {
|
||||
// reflect previous cx2/cy2 over x/y
|
||||
cx = x + (x - cx2);
|
||||
cy = y + (y - cy2);
|
||||
// then get real control and end point
|
||||
if (op === "s") {
|
||||
cx2 = x + args[a];
|
||||
cy2 = y + args[a + 1];
|
||||
x += args[a + 2];
|
||||
y += args[a + 3];
|
||||
} else {
|
||||
cx2 = args[a];
|
||||
cy2 = args[a + 1];
|
||||
x = args[a + 2];
|
||||
y = args[a + 3];
|
||||
}
|
||||
normalized += "C " + cx + " " + cy + " " + cx2 + " " + cy2 + " " + x + " " + y + " ";
|
||||
}
|
||||
}
|
||||
|
||||
// rx ry x-axis-rotation large-arc-flag sweep-flag x y
|
||||
// a 25,25 -30 0, 1 50,-25
|
||||
|
||||
// arc command
|
||||
else if (lop === "a") {
|
||||
for (a = 0; a < alen; a += 7) {
|
||||
rx = args[a];
|
||||
ry = args[a + 1];
|
||||
xrot = args[a + 2];
|
||||
lflag = args[a + 3];
|
||||
sweep = args[a + 4];
|
||||
if (op === "a") {
|
||||
x += args[a + 5];
|
||||
y += args[a + 6];
|
||||
} else {
|
||||
x = args[a + 5];
|
||||
y = args[a + 6];
|
||||
}
|
||||
normalized += "A " + rx + " " + ry + " " + xrot + " " + lflag + " " + sweep + " " + x + " " + y + " ";
|
||||
}
|
||||
} else if (lop === "z") {
|
||||
normalized += "Z ";
|
||||
// not unimportant: path closing changes the current x/y coordinate
|
||||
x = sx;
|
||||
y = sy;
|
||||
}
|
||||
}
|
||||
return normalized.trim();
|
||||
}
|
Reference in New Issue
Block a user