mirror of
https://github.com/konvajs/konva.git
synced 2025-09-18 18:27:58 +08:00
Better svg parsing. fix #1549
This commit is contained in:
@@ -522,19 +522,77 @@ export class Path extends Shape<PathConfig> {
|
|||||||
// while ((match = re.exec(str))) {
|
// while ((match = re.exec(str))) {
|
||||||
// coords.push(match[0]);
|
// coords.push(match[0]);
|
||||||
// }
|
// }
|
||||||
const p: number[] = [];
|
let p: number[] = [];
|
||||||
|
// Track param position for A/a commands: 0..6 => rx, ry, psi, fa, fs, x, y
|
||||||
|
let arcParamIndex = c === 'A' || c === 'a' ? 0 : -1;
|
||||||
|
|
||||||
for (let j = 0, jlen = coords.length; j < jlen; j++) {
|
for (let j = 0, jlen = coords.length; j < jlen; j++) {
|
||||||
|
const token = coords[j];
|
||||||
// extra case for merged flags
|
// extra case for merged flags
|
||||||
if (coords[j] === '00') {
|
if (token === '00') {
|
||||||
p.push(0, 0);
|
p.push(0, 0);
|
||||||
|
if (arcParamIndex >= 0) {
|
||||||
|
arcParamIndex += 2;
|
||||||
|
if (arcParamIndex >= 7) arcParamIndex -= 7;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const parsed = parseFloat(coords[j]);
|
if (arcParamIndex >= 0) {
|
||||||
if (!isNaN(parsed)) {
|
// index-aware minimal handling for merged flags
|
||||||
p.push(parsed);
|
if (arcParamIndex === 3) {
|
||||||
|
// expecting large-arc-flag; token may contain fa+fs(+x)
|
||||||
|
if (/^[01]{2}\d+(?:\.\d+)?$/.test(token)) {
|
||||||
|
p.push(parseInt(token[0], 10));
|
||||||
|
p.push(parseInt(token[1], 10));
|
||||||
|
p.push(parseFloat(token.slice(2)));
|
||||||
|
arcParamIndex += 3;
|
||||||
|
if (arcParamIndex >= 7) arcParamIndex -= 7;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (token === '11' || token === '10' || token === '01') {
|
||||||
|
p.push(parseInt(token[0], 10));
|
||||||
|
p.push(parseInt(token[1], 10));
|
||||||
|
arcParamIndex += 2;
|
||||||
|
if (arcParamIndex >= 7) arcParamIndex -= 7;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (token === '0' || token === '1') {
|
||||||
|
p.push(parseInt(token, 10));
|
||||||
|
arcParamIndex += 1;
|
||||||
|
if (arcParamIndex >= 7) arcParamIndex -= 7;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (arcParamIndex === 4) {
|
||||||
|
// expecting sweep-flag; token may contain fs(+x)
|
||||||
|
if (/^[01]\d+(?:\.\d+)?$/.test(token)) {
|
||||||
|
p.push(parseInt(token[0], 10));
|
||||||
|
p.push(parseFloat(token.slice(1)));
|
||||||
|
arcParamIndex += 2;
|
||||||
|
if (arcParamIndex >= 7) arcParamIndex -= 7;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (token === '0' || token === '1') {
|
||||||
|
p.push(parseInt(token, 10));
|
||||||
|
arcParamIndex += 1;
|
||||||
|
if (arcParamIndex >= 7) arcParamIndex -= 7;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const parsedArc = parseFloat(token);
|
||||||
|
if (!isNaN(parsedArc)) {
|
||||||
|
p.push(parsedArc);
|
||||||
|
} else {
|
||||||
|
p.push(0);
|
||||||
|
}
|
||||||
|
arcParamIndex += 1;
|
||||||
|
if (arcParamIndex >= 7) arcParamIndex -= 7;
|
||||||
} else {
|
} else {
|
||||||
p.push(0);
|
const parsed = parseFloat(token);
|
||||||
|
if (!isNaN(parsed)) {
|
||||||
|
p.push(parsed);
|
||||||
|
} else {
|
||||||
|
p.push(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -487,6 +487,30 @@ describe('Path', function () {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.only('parses arc without separators after flags', function () {
|
||||||
|
const stage = addStage();
|
||||||
|
const layer = new Konva.Layer();
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
const path = new Konva.Path({
|
||||||
|
data: 'M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z',
|
||||||
|
stroke: 'red',
|
||||||
|
});
|
||||||
|
layer.add(path);
|
||||||
|
layer.draw();
|
||||||
|
|
||||||
|
const arc = path.dataArray[3];
|
||||||
|
assert.equal(arc.command, 'A');
|
||||||
|
assert.closeTo(arc.points[0], 12, 0.001);
|
||||||
|
assert.closeTo(arc.points[1], 10.5, 0.001);
|
||||||
|
assert.closeTo(arc.points[2], 7.5, 0.001);
|
||||||
|
assert.closeTo(arc.points[3], 7.5, 0.001);
|
||||||
|
assert.closeTo(arc.points[4], Math.PI, 0.001);
|
||||||
|
assert.closeTo(arc.points[5], Math.PI, 0.001);
|
||||||
|
assert.equal(arc.points[6], 0);
|
||||||
|
assert.equal(arc.points[7], 1);
|
||||||
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
it('Tiger (RAWR!)', function () {
|
it('Tiger (RAWR!)', function () {
|
||||||
this.timeout(5000);
|
this.timeout(5000);
|
||||||
|
Reference in New Issue
Block a user