如何将 SVG'c' 曲线转换为三次贝塞尔曲线列表

How to convert SVG 'c' curve to a list of cubic bezier curve?

本文关键字:曲线 三次 列表 转换 SVG      更新时间:2023-09-26

我有一条路径如下:

d="m 0,0 38.913,455.481 c 7.122,83.37 6.816,164.779 13.005,236.077 18.924,218.078 232.099,308.663 268.399,493.918 16.874,86.119 -37.253,229.874 -42.144,323.022 -7.527,143.381 69.579,142.669 104.526,244.648"

我不太明白它是如何表示的。

我想它被转换为多个简单立方贝塞尔曲线的列表,但是如何转换呢?每次我应该采取什么作为控制点、起点、终点?

这里的坐标到底是什么亲戚?相对于什么?

我对 SVG 图形完全陌生,(在我看来)w3 参考没有在这些方面提供足够的细节。

如果它可以帮助我在这里的目标,那就是在画布中逐点用 javascript 表示这条曲线。

你似乎有三次贝塞尔曲线,而不是二次曲线。规范文本解释了控制点是什么以及它们相对于什么(通常是前一个移动/线/曲线的终点)

1. 通过 yqnn 的 svg 路径编辑器进行转换

重写 pathdata d 属性的一种简单方法是在 yqnn 的 svg 路径编辑器和
中插入字符串。切换缩小选项复选框两次。

将添加所有省略的命令字母(用于重复和隐式命令),以获得更具可读性的d字符串。

2. 通过getPathData()转换

getPathData()尚未被任何主流浏览器支持.
所以你需要一个像 Jarek Foksa 的 pathdata polyfill 这样的 polyfill。

  1. 使用 getPathData() .
    解析路径所有重复或隐式命令将被拆分为单独的命令:
    隐式相对l行到:
m 0,0 38.913,455.481 
// result:
M 0,0 l 38.913,455.481   

d属性中的第一个m命令实际上始终是绝对的。由于我们已经转换了隐式 l 命令 – 我们可以将第一个 moveto 更改为大写M命令字母(可以促进路径连接)。

重复c(立方聚乙烯)

c 7.122 83.37 6.816 164.779 13.005 236.077   
18.924 218.078 232.099 308.663 268.399 493.918 
16.874 86.119 -37.253 229.874 -42.144 323.022 
-7.527 143.381 69.579 142.669 104.526 244.648  
// result:
c 7.122 83.37 6.816 164.779 13.005 236.077   
c 18.924 218.078 232.099 308.663 268.399 493.918 
c 16.874 86.119 -37.253 229.874 -42.144 323.022 
c -7.527 143.381 69.579 142.669 104.526 244.648
  1. 应用路径数据与setPathData()

let pathData = path.getPathData();
path.setPathData(pathData);
output.value = path.getAttribute('d');
svg{
height:20em
}
textarea{
width:100%;
min-height:20em;
}
<script src="https://cdn.jsdelivr.net/npm/path-data-polyfill@1.0.4/path-data-polyfill.min.js"></script>

<svg viewBox="0 0 382.7 1753.15">
        <path id="path" d="m 0,0 38.913,455.481 c 7.122,83.37 6.816,164.779 13.005,236.077 18.924,218.078 232.099,308.663 268.399,493.918 16.874,86.119 -37.253,229.874 -42.144,323.022 -7.527,143.381 69.579,142.669 104.526,244.648&quot;" fill="none" stroke="#000000" stroke-width="2" />
</svg>
<textarea id="output"></textarea>

3. 手动方法

您只需要知道每种命令类型的值/参数的数量,并相应地将命令值拆分为块:

M:2 个值 - 后续值被视为隐式L linetos.
LT : 2 个值
VH : 1 值
C : 6 个值
SQ : 4 个值
A:7个值