使用paper.js将路径切割成两个单独的路径

时间:2014-04-24 01:08:01

标签: javascript paperjs

我需要切片'使用直线进入两条较小路径的大路径。例如,您可能具有以下配置:

Example of slicing

手术后,我应该有两条截然不同的闭路径。我可能应该找到两个交叉点并使用Path.split函数来拆分矩形路径,但我不完全理解paper.js API,我不确定使用paper.js API的最佳方法。

例如,我通过执行以下命令拆分原始矩形:

 var starting_shape = new paper.Path.Rectangle([paper.view.center.x - 200, paper.view.center.y - 200], 400);
 starting_shape.strokeColor = "#aaa";
 starting_shape.strokeWidth = 2;
 starting_shape.fullySelected = true;

 var p1 = starting_shape.split(starting_shape.getNearestLocation([paper.view.center.x - 40, paper.view.center.y - 250]));
 var p2 = starting_shape.split(starting_shape.getNearestLocation([paper.view.center.x + 50, paper.view.center.y + 250]));

我得到以下内容:

Splitting rectangle

我尝试执行以下操作:

p1.closed = true;
p2.closed = true;

p1.position.x += 10;

我得到了必要的结果:

Result

但有没有办法让它变得更聪明?

2 个答案:

答案 0 :(得分:4)

是的,您可以使用path.divide(path2)执行除法布尔运算。如果从github克隆项目,则会对Examples > Scripts > BooleanOperations.html

中的所有布尔函数进行测试

我不相信这个目前的工作方式与你想要的只是一条线。闭路径似乎更稳定。

答案 1 :(得分:1)

此处的splitUsingPath函数可以使用路径将两个复杂的形状分割成一个形状,甚至一个带有曲线的形状。

const rectangle = new Shape.Rectangle(new Point(200, 200), new Size(300, 300)).toPath();
const path = new Path([
    new Point(300, 150),
    new Segment(new Point(325, 350), new Point(-90, -90), new Point(90, 90)),
    new Point(400, 550)
])

rectangle.strokeColor = 'black'
path.strokeColor = 'black'

const splitUsingPath = (target, path) => {
    const paths = [path];
    const targets = [target];

    const originalTarget = target.clone({ insert: false })
    const intersections = target.getIntersections(path)

    intersections.forEach(location => {
      const newTarget = target.splitAt(location)
      const isNew = newTarget !== target

      if (isNew) targets.push(newTarget)

      paths.forEach(path => {
          const offset = path.getOffsetOf(location.point)
          const pathLocation = path.getLocationAt(offset)

          if (pathLocation) {
                paths.push(path.splitAt(pathLocation))
          }
      })
    })

    const innerPath = paths.find(p => 
        originalTarget.contains(p.bounds.center))

    paths
        .filter(path => path !== innerPath)
        .forEach(item => item.remove())

    targets.forEach((target, i) => {
        const isFirst = i === 0
        const innerPathCopy = isFirst ? innerPath : innerPath.clone()

        target.join(innerPathCopy, innerPathCopy.length)
    })

    return targets
}

const splitPaths = splitUsingPath(rectangle, path)

splitPaths.forEach((path, i) => {
    path.position.x += i * -10
})

enter image description here