javascript - Raphael.path2curve 不遵循原始路径

标签 javascript raphael

我对 Raphael.path2curve() 有疑问.该函数修改 SVG 路径字符串,以便所有路径命令都转换为绝对三次曲线 (C)。该函数支持所有路径命令(mlcqahvstMLCQAHVST,参见 SVG SPEC)。

在很多情况下,Raphael.path2curve() 可以很好地处理路径,例如。它甚至可以正确地将弧形转换为立方体,这不是一个简单的计算。我做了很多测试,发现包含命令 QTCSHT 的路径转换得很好。以下也没有问题:MS, HS, VS, LS, TC, TH, TL, TV, QA, TA

但它无法处理命令QS、TS、AS、TT(按此顺序)。

如果我们例如。有这样的路径,转换失败:

M 0 0  T 205.4 112.9  S 260.8 23.36 82.45 72.86 

但这转换正确:

M 0 0  S 211.9 54.20 52.14 144.4  T 98.85 44.45 

因此,MTS 不行,但 MST 可以。有问题的是 S 和 T,因为当出现故障时,它们总是有问题。

我做了 a random path generator (慢,但使用 jsbin 来提高速度),您可以获得随机路径并将其转换为 使用 Raphael.path2curve() 的三次命令。在 fiddle 中单击 SVG 或在输入字段上按回车键以获得新的随机路径。重复直到你找到一个不正确的。在 jsfiddle在 HTML 窗口中是一个参数 var list = "st";,您可以在其中设置要随机化的路径命令。

这是一个示例图像。蓝色是原始路径,红色是转换后的路径。它们应该是相同的。

path

我应该如何处理 Raphael 代码才能正确转换?

(我制作了 a bug report ,但现在已经尝试解决问题几个小时但没有成功。

最佳答案

看来我终于修好了。请测试!我做了两个jsbin版本:

1) 使用未修改的 Raphael 库的非固定版本:jsbin.com/oqojan/33 .
2) 修改了 path2curve() 函数的固定版本:jsbin.com/oqojan/32 .

在两个版本中都有黑色(原始)和白色(规范化)路径。如果一切正常,您应该看不到黑色路径下方的白色路径。如果你看到白色的路径,那么lib代码有错误(请看下面对一些小闪烁的解释)。

请在输入字段上按住 ENTER 键一分钟左右。只要按下 ENTER,代码就会重复生成随机路径。更改属性 var list = "mlcqahvstz"; 以更改随机化的基本字母。

这里是我必须对 lib 代码做什么的解释。在 original Raphaël 2.1.0 lib code有一个函数 path2curve(),它有以下几行:

case "S":
    nx = d.x + (d.x - (d.bx || d.x));
    ny = d.y + (d.y - (d.by || d.y));
    path = ["C", nx, ny][concat](path.slice(1));
    break;
case "T":
    d.qx = d.x + (d.x - (d.qx || d.x));
    d.qy = d.y + (d.y - (d.qy || d.y));
    path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
    break;

当我将它们更改为:

case "S":
    if (pcom == "C" || pcom == "S") { // In "S" case we have to take into
                                      // account, if the previous command
                                      // is C/S.
        nx = d.x * 2 - d.bx;          // And reflect the previous 
        ny = d.y * 2 - d.by;          // command's control point relative
                                      // to the current point.  
    }
    else {                            // or some else or nothing
        nx = d.x;
        ny = d.y;
    }
    path = ["C", nx, ny][concat](path.slice(1));
    break;
case "T":
    if (pcom == "Q" || pcom == "T") { // In "T" case we have to take
                                      // into account, if the
                                      // previous command is Q/T.
        d.qx = d.x * 2 - d.qx;        // And make a reflection similar 
        d.qy = d.y * 2 - d.qy;        // to case "S".
    }
    else {                            // or something else or nothing
        d.qx = d.x;
        d.qy = d.y;
    }
    path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
    break;

该功能按预期工作(即尊重每个可能的路径命令组合中的原始路径形状)。 pcom 变量指的是原始路径的前一段,我还必须添加一种获取 pcom 的方法,这很容易,因为除了 A 之外的所有其他路径命令,从原始路径段类型到三次曲线 (C) 的转换仅产生一个三次命令。在 A 的情况下,函数可能会产生多个 C 命令(短 Angular 会产生一个或几个 C 段,而较大的 Angular 会产生更多)。

唯一的小不一致来自 Z 命令,因为 Raphaël 将每个 Z 转换为 C。这会影响路径起点(或终点)的视觉外观,但差异并不大。我假设它将 Z 转换为 C 以使路径可动画化。如果不需要动画,那么您可以考虑编辑函数以保留 Z:s 不转换,在这种情况下转换保真度非常好。

我很惊讶所有路径命令都可以如此可靠地表示为三次曲线!

我希望这个错误在 Raphaël 的 future 版本中得到修复。

编辑:也为路径动画制作了测试平台:
1) 非固定:http://jsbin.com/oqojan/44
2)固定:http://jsbin.com/oqojan/42

在对非动画路径和动画路径进行全面测试后,我可以确认我对 path2curve 函数的修复是稳定的,并且可以在生产代码中实现。如果您想确定,请使用上述测试平台。

关于javascript - Raphael.path2curve 不遵循原始路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13043217/

相关文章:

javascript - 语法错误 : Unexpected token < in React. js

javascript - 向管道 Angular 添加一个字符

javascript - jQuery 如果带有选择的表单已填写,则显示 div

用于在移动网站横幅上显示到移动应用程序的 JavaScript 库

javascript - 如何使用 raphael.js 重复绘制折线动画

javascript - 如何在 raphaeljs 中使用 attr 的 stroke-dasharray,stroke-linecap,stroke-linejoin

javascript - 刷新选择选项

jquery - Raphael JS 工具提示在第一次悬停时不显示

graph - raphael js 和实时图

svg - Raphael.js 将文本转换为路径