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,21 +522,79 @@ export class Path extends Shape<PathConfig> {
|
||||
// while ((match = re.exec(str))) {
|
||||
// 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++) {
|
||||
const token = coords[j];
|
||||
// extra case for merged flags
|
||||
if (coords[j] === '00') {
|
||||
if (token === '00') {
|
||||
p.push(0, 0);
|
||||
if (arcParamIndex >= 0) {
|
||||
arcParamIndex += 2;
|
||||
if (arcParamIndex >= 7) arcParamIndex -= 7;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const parsed = parseFloat(coords[j]);
|
||||
if (arcParamIndex >= 0) {
|
||||
// index-aware minimal handling for merged flags
|
||||
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 {
|
||||
const parsed = parseFloat(token);
|
||||
if (!isNaN(parsed)) {
|
||||
p.push(parsed);
|
||||
} else {
|
||||
p.push(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (p.length > 0) {
|
||||
if (isNaN(p[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 () {
|
||||
this.timeout(5000);
|
||||
|
Reference in New Issue
Block a user