我正在使用 Raphaël第一次没有 svg 经验,我需要真正了解这两者的人来帮助我。
我创建了一个包含动态扇区的饼图。可以通过拖动圆形按钮来调整扇区的大小。参见 this fiddle .我只在 Chrome 和 Safari 中测试过,它们是唯一需要的浏览器。
饼图尚未完成。 扇区可以重叠。请暂时忽略它。
当一个扇区的起始 Angular 大于结束 Angular 时,我遇到了问题。当结束 Angular 超过 0/360° 标记时就是这种情况。为了解决这个问题,我使用了路径-旋转-参数。我将扇区向前移动,同时将 Angular 向后移动,直到结束 Angular 为 360。您可以在此函数的 fiddle 中看到:
function sector_update(cx, cy, r, startAngle, endAngle, sec) {
var x1 = cx + r * Math.cos(-startAngle * rad),
x2 = cx + r * Math.cos(-endAngle * rad),
y1 = cy + r * Math.sin(-startAngle * rad),
y2 = cy + r * Math.sin(-endAngle * rad);
var rotation = 0;
// This is the part that I have the feeling could be improved.
// Remove the entire if-clause and let "rotation" equal 0 to see what happens
if (startAngle > endAngle) {
rotation = endAngle;
startAngle = startAngle - endAngle;
endAngle = 360;
}
sec.attr('path', ["M", cx, cy, "L", x1, y1, "A", r, r, rotation,
+(endAngle - startAngle > 180), 0, x2, y2, "z"]);
}
虽然效果很好,但我还是有点怀疑。不旋转路径能解决这个问题吗?感谢任何帮助或指点。
最佳答案
不旋转路径能解决这个问题吗?
回答:是的,可以。您根本不必更改路径的旋转。除非我遗漏了什么,否则以下代码似乎与您在 fiddle 中的代码一样工作:
function sector_update(cx, cy, r, startAngle, endAngle, sec) {
var x1 = cx + r * Math.cos(-startAngle * rad),
x2 = cx + r * Math.cos(-endAngle * rad),
y1 = cy + r * Math.sin(-startAngle * rad),
y2 = cy + r * Math.sin(-endAngle * rad);
//notice there is no "roation" variable
if (startAngle > endAngle) {
startAngle -= endAngle;
endAngle = 360;
}
sec.attr('path', ["M", cx, cy, "L", x1, y1, "A", r, r, 0,
+(endAngle - startAngle > 180), 0, x2, y2, "z"]);
}
解释:为了解释,我将在
W3 Spec和 Raphael Reference Library .也就是说,当您使用 cx
、cy
和 rotation
时,它们使用 rx
、ry
和 x-axis-rotation
分别。
简而言之,只要rx
等于ry
,那么x-axis-rotation
就没有意义。
看this SVG .使用浏览器的开发工具,或将 SVG 保存到计算机并使用文件编辑器对其进行编辑。具体来说,查看最后一个 path
元素,其中有四个圆弧。尝试修改每个圆弧上的 x-axis-rotation
值。您会注意到,当您更新 x-axis-rotation
值时,第一个圆弧(其中 rx
和 ry
都是“25”)永远不会改变.
为什么?这是因为你有一个圆弧。无论你旋转多少圈,它仍然是同一个圆。例如,在你面前举起一个玻璃杯,使玻璃杯与地面水平,而你正直视玻璃杯下方。现在用手腕旋转/扭转玻璃杯。你看到你看到的圆形如何保持相同的圆形吗?现在将玻璃杯正常放置在 table 上(因此它是垂直的并且可以容纳液体)。现在把玻璃杯倒过来。您可以看到明显的视角变化;它是朝上的,但现在是平躺的。这就是 x-axis-rotation
所做的。
也许一个更好的例子就是使用前面提到的 SVG 文件。在最后的 path
元素的圆弧上使用 x-axis-rotation
。您会看到圆弧在旋转。这就是 x-axis-rotation
所做的。
回到您的代码:因为您只处理圆形对象,所以 x-axis-rotation
对最终输出没有影响。只要您只处理圆形对象,您就可以毫无顾虑地将它的值硬编码为零。您真正需要做的就是修改您已经正确完成的 Angular 。
性能:我尝试使用 JavaScript 在修改和不修改 x-axis-rotation
变量的情况下为您的 sector_update
函数计时。结果?我没有看到性能差异。大部分时间花在实际绘制 SVG 上,而不是花在确定它的值的数学上。事实上,您在 JavaScript 中真正做的就是更新代码以设置 path
元素中的值。在那个时间点,浏览器接管它的渲染引擎来实际绘制 SVG 对象。我想这是每个浏览器的问题,因为每个浏览器都有不同的渲染性能。但至于 x-axis-rotation
值是否有任何影响,我的猜测是没有。如果 性能受到影响(因为浏览器可能必须执行额外的浮点运算),那么它就毫无意义了,因为绝大多数时间都花在了绘制对象上,而不是计算它值。所以我会说不用担心。
希望对您有所帮助,如果我遗漏了什么或没有解释清楚,请告诉我。
关于javascript - 使用 Raphaël JS 和 SVG 调整扇区路径大小的更优雅的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10910671/