paper.js - 通过封闭路径实现更平滑的边缘

时间:2014-09-19 14:43:51

标签: javascript html5 canvas paperjs

这是一个我生成的不规则形状的盒子:

这是我想要达到的最终效果(注意光滑的边缘):

enter image description here

这是我的敏锐版本的代码:

var path1 = new Path({
    segments: [[123, 6], [290, 6], [304, 142], [112, 142]],
    strokeColor: 'white',
    closed: true,
    strokeWidth: 3,
    strokeJoin: 'round'
});

事情是,我已经使用 strokeJoin:' round' 选项,并且在笔划宽度为3px时差异很小。这是一件小事,但可能变成一个游戏破坏者,因为会有像这样的多个对象,差别很大。

有没有办法用paper.js实现这一点而不会过度使用它?

2 个答案:

答案 0 :(得分:7)

正如markE所提到的,strokeJoin仅更改路径笔划的画布样式。 Paper.js没有角落舍入功能,你必须自己制作。

这是一个快速功能,您可以使用起点。它会将多边形的点偏移给定距离并添加适当的手柄。

function roundPath(path,radius) {
    var segments = path.segments.slice(0);
    path.segments = [];
    for(var i = 0, l = segments.length; i < l; i++) {
        var curPoint = segments[i].point;
        var nextPoint = segments[i + 1 == l ? 0 : i + 1].point;
        var prevPoint = segments[i - 1 < 0 ? segments.length - 1 : i - 1].point;
        var nextDelta = curPoint - nextPoint;
        var prevDelta = curPoint - prevPoint;
        nextDelta.length = radius;
        prevDelta.length = radius;
        path.add({
            point:curPoint - prevDelta,
            handleOut: prevDelta/2
        });
        path.add({
            point:curPoint - nextDelta,
            handleIn: nextDelta/2
        });
    }
    path.closed = true;
    return path;
}

Here it is in action.

答案 1 :(得分:1)

我正在寻找一个确切的实现,如下所述:http://shanfanhuang.com/everything/2015/10/27/rounding-corners

我的实施工作如下:

  • curPoint是上面的角落,prevPoint和nextPoint
  • nextNorm和prevNorm是积分的标准化版本
  • angle是角点的角度,源自点积
  • delta是从角点到需要插入控制点的距离,这是由控制点,curPoint和角弧中心形成的直角三角形得出的。角是半角,与角相对的一侧是半径
  • prevDelta和nextDelta是两侧的新端点,插入弧之间
  • through是圆弧中间的一个点,通过获得上面三角形的斜边并减去半径来找到。

    var segments = path.segments.slice(0);
    path.segments = [];
    for(var i = 0, l = segments.length; i < l; i++) {
        var curPoint = segments[i].point;
        var nextPoint = segments[i + 1 == l ? 0 : i + 1].point;
        var prevPoint = segments[i - 1 < 0 ? segments.length - 1 : i - 1].point;
    
        var nextNorm = (curPoint - nextPoint).normalize();
        var prevNorm = (curPoint - prevPoint).normalize();
    
        var angle = Math.acos(nextNorm.dot(prevNorm));
    
        var delta = radius/Math.tan(angle/2);
        var prevDelta = prevNorm.normalize(delta);
        var nextDelta = nextNorm.normalize(delta);
    
        var through = curPoint - (prevNorm + nextNorm).normalize(Math.sqrt(delta*delta + radius*radius) - radius);
    
        path.add(curPoint - prevDelta);
        path.arcTo(through, curPoint - nextDelta);
    }