如何在 Paper.js 中 select 路径中的单个曲线?

How to select a single Curve in a Path in Paper.js?

我需要明确地 select 单击路径的单个曲线,我该怎么做?

例如,在 this sketch 中,我们可以 select 单击它时的整个路径:

目前我可以检测到曲线(无论如何不确定这是否是合适的方法):

..onMouseDown = (event) ~>
    hit = scope.project.hitTest event.point
    if hit?item
        # select only that specific segment
        curves = hit.item.getCurves!
        nearest = null
        dist = null
        for i, curve of curves
            _dist = curve.getNearestPoint(event.point).getDistance(event.point)
            if _dist < dist or not nearest?
                nearest = i
                dist = _dist

        selected-curve = curves[nearest]
            ..selected = yes

但整个路径都是 selected:

我想要实现的是这样的:

没有内置的方法来做你想做的事情 AFAIK。

您基本上需要遍历各个段,构建一条线,然后查看命中是否在该特定线上。这条线不能是透明的或者它不被认为是命中,这就是为什么我给它颜色和宽度来匹配可见线;这也是为什么它在测试后被删除的原因。

这里是草图solution,它围绕这个实现了更多:

function onMouseDown(event){
    if (!myline.hitTest(event.point)) {
        return
    }
    c1.remove()
    c2.remove()
    // there's a hit so this should find it
    let p = event.point
    let segs = myline.segments
    for (let i = 1; i < segs.length; i++) {

        let line = new Path.Line(segs[i - 1].point, segs[i].point)
        line.strokeWidth = 6
        line.strokeColor = 'black'
        if (line.hitTest(p)) {
            c1 = new Path.Circle(segs[i-1].point, 6)
            c2 = new Path.Circle(segs[i].point, 6)
            c1.fillColor = 'black'
            c2.fillColor = 'black'
            line.remove()
            return
        }
        line.remove()
    }
    throw new Error("could not find hit")
}

这是我画的:

有一种更简单的方法可以实现您想要的。
您可以通过检查其 location 属性.
来了解命中是否在曲线上 如果已设置,您可以轻松获取曲线点并手动绘制您的 selection.
这是一个 sketch 演示。

var myline = new Path(new Point(100, 100));
myline.strokeColor = 'red';
myline.strokeWidth = 6;
myline.add(new Point(200, 100));
myline.add(new Point(260, 170));
myline.add(new Point(360, 170));
myline.add(new Point(420, 250));

function onMouseDown(event) {
    hit = paper.project.hitTest(event.point);

    // check if hit is on curve
    if (hit && hit.location) {
        // get curve
        var curve = hit.location.curve;
        // draw selection
        var selection = new Group(
            new Path.Line({
                from: curve.point1,
                to: curve.point2,
                strokeColor: 'blue',
                strokeWidth: 3
            }),
            new Path.Rectangle({
                from: curve.point1 - 5,
                to: curve.point1 + 5,
                fillColor: 'blue'
            }),
            new Path.Rectangle({
                from: curve.point2 - 5,
                to: curve.point2 + 5,
                fillColor: 'blue'
            })
        );
        // make it automatically be removed on next down event
        selection.removeOnDown();
    }
}

更新

作为替代方案,为了避免弄乱导出的绘图,您可以简单地 select 线条而不是应用笔触样式。
看到这个 sketch.

var selection = new Path.Line({
    from: curve.point1,
    to: curve.point2,
    selected: true
});