Opera浏览器对于SVG bug可不少,而且低级。今天又碰见一个Opera SVG bug.
应用场景是这样:绘制一段很简单的SVG圆弧,移动,保存,再打开,发现圆弧方向竟然变了。
不知道是不是巧合,两年前我写过一篇blog说Opera对Canvas Context 2D的实现中的圆弧指令也有方向反了的bug,看来Opera的工程师是一辈子闹不清圆弧这种高级货了!
分析得知,圆弧的路径属性被Opera错误的修改了。
bug分析重现:绘制圆弧,查看path d属性;脚本移动圆弧,再查看它的path d属性,发现圆弧指令的7个参数中两个表示圆弧方向的标记largeArcFlag和sweepFlag颠倒了.
进一步测试发现,根本不需要移动,只要读取了圆弧路径的pathSegList属性,就会出现这个问题。
例如原来是<path d="M 40 30A 4 5 0 1 0 40 20" stroke="#000000" stroke-width="1" fill="none" />
读取后成了<path d="M 40 30A 4 5 0 0 1 40 20" stroke="#000000" stroke-width="1" fill="none" />
1,0对调会变成0,1,0,1对调会变成1,0,1,1和0,0因为对调了不变所以没出错。
之所以说隐蔽,是因为移动之后视觉上看不到任何不对劲,当你用代码去取得属性或者保存起来的时候,却获得了错误的值。
测试重现的代码
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<svg viewBox="0 0 400 203" xmlns="http://www.w3.org/2000/svg">
<path id="p1" d="M 40 30A 4 5 0 1 0 40 20" stroke="#000000" stroke-width="1" fill="none" />
<script type="text/javascript"><![CDATA[
var p = document.getElementById("p1"),
console.log(p.getAttribute('d')); //打出原始的路径值
var ss = p.pathSegList; //这里什么也没做,只是读取了一下pathSegList属性
console.log(p.getAttribute('d')); //这里打出来的路径已经变掉了
]]></script>
</svg>
要修复这个问题,需要重新设置一次path元素的d属性为正确值。组装这个正确的d属性字符串则要根据pathSegList接口来进行,Opera虽然将d属性搞错了,但是路径片段的DOM接口中还是正确的值,因此要根据pathSegList去解析拼接d属性值字符串。