3

我想用这样的圆角绘制折线:

在此处输入图像描述

将点设置为与Konva library一致存在问题。

我正在尝试使用bezier属性来模拟没有张力的光滑角落,正如文档所说:

if no tension is provided but bezier=true, we draw the line as a bezier using the passed points

但如果我设置bezier: true,它只接收 3 对点 [x,y] 并忽略点数组的其余部分,然后只切割折线。

代码打开示例

我不知道如何在没有bezier选项的情况下绘制带有圆角的直线折线tension

有没有办法用 Konva 或其他 JS Canvas 库来实现这样的图形?

4

2 回答 2

2

实际上,有一种方法可以仅使用以下方法绘制圆角Konva.Path

var path = new Konva.Path({
        x: 20,
        y: 20,
        data: 'm0 0 h 90 q 10 0 10 10 v 80 q 0 10 10 10 h 90',
        stroke: 'red',
      });

使用svg 路径规则中的二次曲线贝塞尔 (Q) 算子,我们可以得到这样的结果:

在此处输入图像描述

这是 Codepen 上的一个例子

于 2020-03-27T12:31:07.160 回答
1

这是函数的源代码,它允许您绘制带有弯曲角的漂亮线条。您可以创建Konva.Line对象并向参数添加特殊sceneFunc功能。

const BORDER_RADIUS = 40;

let line = new Konva.Line({
    points:[0,0,100,0,100,100,200,100], // put you points array here
    stroke:'#000000',
    strokeWidth:2,
    sceneFunc: function(ctx,shape){
        let points = shape.points();

        ctx.beginPath();
        ctx.moveTo(points[0],points[1]);
        if (points.length == 4) {
            ctx.lineTo(points[2],points[3]);
        } else {
            let n = 0;

            while (n < points.length-4) {
                let deltaX1 = (points[n+2] - points[n+0]);
                let deltaY1 = (points[n+3] - points[n+1]);
                let br1 = Math.min(BORDER_RADIUS,Math.max(Math.abs(deltaX1/2),Math.abs(deltaY1/2)));

                let deltaX2 = (points[n+2+2] - points[n+0+2]);
                let deltaY2 = (points[n+3+2] - points[n+1+2]);
                let br2 = Math.min(BORDER_RADIUS,Math.max(Math.abs(deltaX2/2),Math.abs(deltaY2/2)));

                let br = Math.min(br1,br2);

                let oneX = points[n+0] + (Math.abs(deltaX1) - br)*Math.sign(deltaX1);
                let oneY = points[n+1] + (Math.abs(deltaY1) - br)*Math.sign(deltaY1);

                ctx.lineTo(oneX, oneY);
                n+=2;
                let twoX = points[n+0] + (br)*Math.sign(deltaX2);
                let twoY = points[n+1] + (br)*Math.sign(deltaY2);

                ctx.quadraticCurveTo(points[n+0], points[n+1],twoX, twoY);
            }
            ctx.lineTo(points[points.length-2],points[points.length-1]);        
        }
        ctx.strokeShape(shape);
    }
}
于 2021-02-07T15:59:58.490 回答