繁体   English   中英

SVG 开放路径上的剪切行程

[英]SVG clipping stroke on open paths

我正在尝试生成一个路径作为另外两个的结果,其中一个充当硬剪切路径 我的目标是实现一个形状被另一个形状剪裁的效果(我正在尝试使用简单的可视化器制作 web 应用程序,用于对信号进行幅度调制)。

这是一个视觉表示:

幅度调制示例

对于每种情况,第一条路径是载波信号,第二条路径是调制器 调制操作由 * 运算符表示; 这意味着调制器形状限制了载波:调制器之外的任何段/值都被切割以匹配调制器形状。

一个粗略的伪代码实现可能是:

# assuming both shapes as same-length arrays of Y values 
# (minimum 0), and their indexes as X values
carrier = [...]
modulator = [...]
result = []

for each x from 0 to carrier.length:
  result.push(min(carrier[x], modulator[x]))

draw(result)

由于每个操作数都有多个路径可供选择,因此我想避免为所有可能的组合编写 SVG 路径,而是旨在动态生成它们。 与此相关的其他答案仅适用于封闭/填充的形状,并且只会导致形状被截取。 我也偶然发现了Warp.js ,但这并不是我所需要的,因为给它的转换 function 会影响整个形状。

我正在使用的形状的一些示例:

第一对形状:

 <svg viewBox="-10 -10 70 70" width="100" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M0,50 C0,50 0,0 25,0 L25,50 L50,50" stroke="black" stroke-width="2" fill="none" /> </svg>

 <svg viewBox="-10 -10 70 70" width="100" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M0,50 L0,0 L50,50" stroke="black" stroke-width="2" fill="none" /> </svg>

最后一个形状(第三个和第二个一样):

 <svg viewBox="-10 -10 70 70" width="100" version="1.1" xmlns="http:/ /www.w3.org/2000/svg"> <path d="M0,50 L25,0 L25,50 L50,0 L50,50" stroke="black" stroke-width="2" fill="none" /> </svg>

我不受任何框架的限制,所以纯粹的 DOM 操作是完全可以的。 有什么方法可以通过使用标记来实现这一点? 或任何其他会产生剪切路径的过程?

我会通过编写一个新路径,用 Javascript 计算路径d属性来解决这个问题。 这太复杂了,无法在这里提供完整的解决方案。 但我认为有许多提示可以让你朝着正确的方向前进。

在我看来,主要问题似乎是识别两条路径之间的交点。 路径由多个段组成,可以占用相当多的forms:直线、椭圆弧、二次或三次贝塞尔曲线,它们都可以在ZCD15A75C260086946347B31A30Z路径中用多个forms表示。 这使得很多情况需要考虑。

这显然是一个使用已经完成繁重工作的库的案例。 有 node.js 库path-intersection ,它基本上是 Adobe 的Snap.js的摘录。 假设API与原版相同,您将能够获得许多您需要继续操作的信息。

乍一看,我没有看到的是这是否干净地处理了在一定长度上连续相同的路径段,而不是仅在有限数量的点上相交。 暂时忽略这种特殊情况,可能的算法可能具有如下粗略的轮廓:

  • 列出两条路径上的所有相交点。
  • 该库将识别发生交叉点的路径段,将它们转换为三次贝塞尔曲线,并为您提供其四个控制点的坐标以及相应的t值。
  • t是一个介于 0 和 1 之间的变量,可用于计算沿贝塞尔曲线的点。 例如,来自 pomax 的Bezier.js库的.get(t) function 实现了这一点。
  • 如果您将两条路径段的t值更改为少量(不超过下一个交点的任何值),您将能够识别两条路径中的哪一条在从交点开始的每个方向上具有较低的y值.
  • t拆分两个路径段,并将路径的原始段交换为两个部分。
  • 现在您有两条路径,其中每个交点也是线段边缘,并且您知道对于每条路径,哪个线段是较低的线段。 您现在可以编写由所有较低段组成的路径。

如果您有路径的完整AST 表示,最后两个步骤显然是最简单的,但可以使用一些正则表达式。

最后,我提到的所有库都不需要 DOM,只需要处理路径数据。 这在性能方面实际上是一件好事,并为您提供了更多执行该代码的选择(例如在服务器上或在 Web Worker 中)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM