Raphael.path2curve不尊重原始路径 [英] Raphael.path2curve does not honor the original path

查看:97
本文介绍了Raphael.path2curve不尊重原始路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到,但现在已经尝试了几个小时没有运气解决问题。

解决方案

似乎我终于修好了。请测试!我制作了两个jsbin版本:



1)使用未经修改的Raphael lib的NON-FIXED版本: jsbin.com/oqojan/33 。< br>
2)修改了path2curve()函数的修复版本: jsbin.com/oqojan/32



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



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



这是解释我与lib代码有什么关系。在原始Raphaël2.1.0lib代码中,有一个函数path2curve(),它具有以下内容行:

 案例S:
nx = dx +(dx - (d.bx || dx) );
ny = d.y +(d.y - (d.by || d.y));
path = [C,nx,ny] [concat](path.slice(1));
休息;
caseT:
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]));
休息;

当我将它们更改为:

  caseS:
if(pcom ==C|| pcom ==S){//在S情况下我们必须考虑
// account,如果前一个命令
//是C / S.
nx = d.x * 2 - d.bx; //并反映之前的
ny = d.y * 2 - d.by; //命令的控制点相对
//到当前点。
}
else {//或其他一些或没有什么
nx = d.x;
ny = d.y;
}
path = [C,nx,ny] [concat](path.slice(1));
休息;
caseT:
if(pcom ==Q|| pcom ==T){//在T情况下,我们必须将
//纳入账户,如果
// previous命令是Q / T.
d.qx = d.x * 2 - d.qx; //并做出类似的反思
d.qy = d.y * 2 - d.qy; //对案例S。
}
else {//或别的或其他什么
d.qx = d.x;
d.qy = d.y;
}
path = [C] [concat](q2c(d.x,d.y,d.qx,d.qy,path [1],path [2]));
休息;

函数按预期工作(即遵循每个可能的路径命令组合中的原始路径形状)。 pcom 变量是指ORIGINAL路径的上一段,我还必须添加一种方法来获取 pcom ,这是相当简单,因为对于除A之外的所有其他路径命令,从原始路径段类型到三次曲线(C)的转换仅产生一个立方命令。在A的情况下,该函数可能产生多个C指令(短角产生一个或几个C段,较大的角度产生更多)。



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



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



我希望在将来的Raphaël版本中修复这个bug。



编辑:制作测试平台也用于路径动画:

1)未经修复: http:// jsbin .com / oqojan / 44

2)修复: http://jsbin.com/oqojan/42



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


I have a problem with Raphael.path2curve(). The function modifies SVG path string so that all path commands are converted to absolute Cubic curves (C). The function supports all path commands (mlcqahvstMLCQAHVST, see SVG SPEC).

The Raphael.path2curve() can handle well paths in many cases, eg. It can even convert arcs to cubics correct, which is not an easy calculation. I have made many tests and realized that paths that consist of commands QT, CS or HT converts well. There are no problems with also the following:MS, HS, VS, LS, TC, TH, TL, TV, QA, TA.

But it cannot handle commands QS, TS, AS, TT (in that order).

If we eg. Have a path like this, the conversion fails:

M 0 0  T 205.4 112.9  S 260.8 23.36 82.45 72.86 

But this converts correct:

M 0 0  S 211.9 54.20 52.14 144.4  T 98.85 44.45 

So, MTS is not OK, but MST is. The problematic ones are S and T, because they are always in question, when something fails.

I made a random path generator (slow, but use jsbin for speed), where you can get random path and get it converted to Cubic commands using Raphael.path2curve(). In fiddle click the SVG or press enter on the input field to get a new random path. Repeat until you find an incorrect one. In jsfiddle in HTML window is a parameter var list = "st"; where you can set the path commands to be randomized.

This is an example image. The blue is original path and red is converted path. They should be identical.

What should I do to Raphael code to get the conversion correct?

(I made a bug report, but have now tried to solve the problem several hours without luck.

解决方案

It seems that I finally got it fixed. Please test! I made two jsbin versions:

1) NON-FIXED version which uses unmodified Raphael lib: jsbin.com/oqojan/33.
2) FIXED version where path2curve() function is modified: jsbin.com/oqojan/32.

In both versions there are black (original) and white (normalized) path. If everything works okay, you shouldn't see the white path below black path. If you see the white path, the lib code has a bug (please see below the explanation of some minor flickering).

Please hold ENTER down on input field a minute or so. The code generates random paths repeatedly as long as ENTER is down. Change the attribute var list = "mlcqahvstz"; to change the base letters for randomization.

And here is the explanation of what I had to do with the lib code. In original Raphaël 2.1.0 lib code there is a function path2curve(), which has the following lines:

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;

When I changed them to:

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;

the function worked as expected (ie respects the original path shape in every possible path command combination). pcom variable refers to the previous segment of ORIGINAL path and I had to also add a way to get pcom, which was rather easy, because regarding all other path commands than A, the conversion from original path segment type to cubic curve (C) produces only one cubic command. In case of A the function may produce more than one C command (short angles produces one or few C segments and larger angles produces more).

The only minor inconsistence comes from Z commands, because Raphaël converts every Z to C. This affects to the visual appearance of path starts (or ends), but the difference is not huge. I assume that it converts Z to C to make paths animatable. If animation is not needed, then you may consider to edit the function to leave Z:s unconverted, in which case the conversion fidelity is excellent.

I'm amazed that all path commands can be represented as Cubic curves so reliably!

I hope this bug gets fixed in some future release of Raphaël.

EDIT: Made testbed also for path animations:
1) NON-FIXED: http://jsbin.com/oqojan/44
2) FIXED: http://jsbin.com/oqojan/42

After thorough testing with both non-animated and animated paths, I can confirm that my fix to path2curve function is stable and can be implemented in production code. If you want to be sure, please use above mentioned testbeds.

这篇关于Raphael.path2curve不尊重原始路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆