返回项目

项目

PaperJs Offset

geometrypaperjstypescript

paperjs-offset 是一个面向 Paper.js 的路径偏移辅助库。它接受 paper.Path 和 paper.CompoundPath,可以生成闭合路径偏移、可填充的描边轮廓,并提供用于检查结果几何质量的分析信息。

这个库刻意保持较小的 API 面:扩张或收缩一个闭合路径,把中心线描边转换成闭合轮廓,然后检查生成结果是否足够可靠。

PaperJs Offset 的路径偏移与描边轮廓示例

闭合路径偏移

正距离会把闭合形状向外扩张,负距离会向内收缩。源路径仍由调用方控制,因此可以保留它用于对比,也可以在生成后移除。

const expanded = offset(source, 14, {
  join: "round",
  insert: false
});

const contracted = offset(source, -10, {
  join: "round",
  insert: false
});

这是大多数基础 demo 和 Gallery case 的核心操作。

描边轮廓

offsetStroke 把开放或闭合中心线作为独立操作处理。Join 决定拐角如何重建,cap 决定开放路径端点如何闭合。对自然形状来说,round 通常是最稳妥的默认值;miter 和 bevel 更适合锐角构造几何。

const outline = offsetStroke(centerline, 8, {
  join: "round",
  cap: "round",
  insert: false
});

质量分析

默认的 algorithm: "auto" 会先生成 adaptive 结果。质量检查没有发现自交、意外空结果、包含关系错误或负向偏移距离坍缩等结构性问题时,它会直接返回;只有发现异常,才继续比较其他策略。

同一套评分信息也可以通过 analyze 读取。分析时应传入实际使用的 join、cap 和 stroke 语义,避免把 bevel 连接或 butt 端点的预期形状误判为距离坍缩。

const result = offset(source, 12, {
  algorithm: "auto",
  join: "round",
  insert: false
});

const quality = analyze(source, result, 12, {
  join: "round"
});

策略选择

模式适用情况
auto推荐的应用默认值;先走 adaptive,必要时再比较其他候选。
adaptive保持请求的偏移距离;激进内缩接近塌缩边界时,会比较原 join 与更安全的 round join。
robust对凹角和自交描边轮廓执行额外清理。
split拆分自交曲线,保留比 robust 更多的原始结构。
legacy尽量维持旧版本输出,用于兼容已有结果。

auto 的目标不是让调用方猜测哪种算法适合某个图形,而是在常见输入上避免不必要的多策略计算,并在困难几何出现时才扩大搜索范围。需要复现历史输出或检查某个特定策略时,仍然可以显式选择模式。

交互指南

下面的例子来自项目仓库生成的 Dev Site Export Contract。详情页只读取 manifest.json、data/guide.json 和 runtime,具体示例内容仍由 paperjs-offset 仓库维护。

paperjs-offset 交互指南截图
交互指南的静态截图。启用 JavaScript 后会挂载项目仓库导出的实时 canvas 示例。

Playground

Playground 使用同一套导出的 data 和 runtime。你可以选择预设形状,调整偏移参数,并立即观察生成路径。

paperjs-offset Playground 截图
Playground 的静态截图。启用 JavaScript 后会挂载可调参数的实时偏移实验区。

Gallery 由 data/gallery.json 驱动,包含 198 个确定性 case。页面默认先显示 12 个轻量精选案例,基础、进阶、边界与特殊 case 会在切换 tab 后再渲染。每个 case 都带有 SVG path、operation、distance、options 和 expected 质量信息。

除常规的星形、平滑曲线、孔洞和开放描边外,用例还覆盖嵌套岛屿轮廓、尺寸悬殊的分离组件、深度细分、包含关系泄漏、数值精度敏感的侵蚀,以及应当完全消失的负向偏移。这些输入既用于页面展示,也直接来自项目的压力测试语料。

paperjs-offset Gallery 截图
Gallery 的静态截图。启用 JavaScript 后会从项目导出的 gallery 数据渲染全部确定性 case。

用例与验证

固定 Gallery 之外,测试还会使用固定 seed 生成 400 个 fuzz case,覆盖随机多边形、Bezier 曲线、复合路径和开放描边。失败输入可以用 seed 和 case 编号重放,再收录为新的确定性回归用例。

Benchmark 使用同一批语料比较不同算法,输出总耗时、P50、P95、最大耗时和最慢案例。它不设置容易受机器差异影响的硬性时间阈值,主要用于观察策略调整是否引入明显退化。

安装

使用这个库的应用需要自行安装 Paper.js:

npm install paper paperjs-offset

推荐 API

新代码推荐使用具名函数:

import paper from "paper";
import { analyze, offset, offsetStroke } from "paperjs-offset";

paper.setup(new paper.Size(400, 300));

核心函数包括:

offset(path, distance, options);
offsetStroke(path, distance, options);
analyze(source, result, distance, options);

offset 负责闭合路径的扩张或收缩。offsetStroke 把中心线描边转换成闭合轮廓。analyze 对生成结果打分,并报告困难几何 case 的警告信号。

说明

Bezier 几何偏移是近似问题,尤其在紧曲线、凹角、自交、复合路径和激进负偏移附近更明显。

adaptive 会保留调用方请求的偏移距离,不再通过缩小负向偏移来换取看起来更安全的图形。激进内缩接近临界区时,它会比较请求的 bevel/miter join 与 round 候选,避免退化轮廓面积重新增长,或在完全消失后再次出现。对于过度侵蚀后理应消失的形状,空结果本身可能就是正确结果;是否可接受,应结合业务语义和 analyze 的报告判断。

本页目录