Как я уже говорил, вы можете использовать javascript для вычисления координат для квадратичной c кривой Безье для закругленных углов. Контрольной точкой Безье является точка полилинии. Затем вам нужно получить начальную и конечную точки Безье в виде точки на расстоянии r
от контрольной точки на полилинии. Когда у вас есть все точки для нового пути, вы можете использовать их для построения значения атрибута d
thePath
.
. Убедитесь, что переменная r
имеет разумный размер.
let polypoints = poly.getAttribute("points");
let r = 5; // distance for the curvature
function getPoints(poly) {
// poly is the polygon's element d attribute
let polyPoints = poly
.replace(/(\r?\n|\r|\t)+/g, "")
.replace(/\-/g, " -")
.split(/[\s,]+/);
polyPoints = removeEmptyElements(polyPoints);
let points = [];
for (let i = 0; i < polyPoints.length; i += 2) {
let temp = [Number(polyPoints[i]), Number(polyPoints[i + 1])];
points.push(temp);
}
return points;////[[10, 40],[15, 45],[30, 70],[35, 75]]
}
function getAngle(c, l) {
let delta_x = l.x - c.x;
let delta_y = l.y - c.y;
let a = Math.atan2(delta_y, delta_x);
return a; //in radians;
}
function removeEmptyElements(array) {
for (let i = 0; i < array.length; i++) {
if (array[i] == "") {
array.splice(i, 1);
}
}
return array;
}
function polygonWithRoundedCorners(poly, r) {
let points = getPoints(poly);
//move to the first point
let d = `M${points[0][0]},${points[0][1]}`;
for (let i = 1; i < points.length - 1; i++) {
let previous = i - 1;
let next = i + 1;
let c = {};//the control point
c.x = points[i][0];
c.y = points[i][1];
let l1 = {};
l1.x = points[previous][0];
l1.y = points[previous][1];
let l2 = {};
l2.x = points[next][0];
l2.y = points[next][1];
let a1 = getAngle(c, l1);
let a2 = getAngle(c, l2);
//if great precision is needed remove .toFixed(3)
//x1 and y1 are defining the start point of the Bézier
let x1 = (c.x + r * Math.cos(a1)).toFixed(3);
let y1 = (c.y + r * Math.sin(a1)).toFixed(3);
//x2 and y2 are defining the end point of the Bézier
let x2 = (c.x + r * Math.cos(a2)).toFixed(3);
let y2 = (c.y + r * Math.sin(a2)).toFixed(3);
//build the d attribute
d += "L" + x1 + "," + y1 + " Q" + c.x + "," + c.y + " " + x2 + "," + y2;
}
//move to the last point and return the d attribute
return (d += `L${points[points.length - 1][0]},${
points[points.length - 1][1]
}`);
}
thePath.setAttributeNS(null, "d", polygonWithRoundedCorners(polypoints, r));
svg{border:solid;width:90vh}
<svg viewBox="-5 30 55 55">
<polyline id="poly" points="10,40 15,45 30,70 35,75" fill="none" stroke="black" ></polyline>
<path id="thePath" fill="none" stroke="red" />
</svg>