15

我第一次使用Raphaël,几乎没有 svg 经验,我需要真正了解这两个方面的人来帮助我。

我创建了一个带有动态扇区的饼图。可以通过拖动圆形按钮来调整扇区的大小。看到这个小提琴。我只在 Chrome 和 Safari 中进行了测试,它们是唯一需要的浏览器。

饼图尚未完成。扇区可以重叠。请暂时忽略这一点。

当扇区的起始角度大于结束角度时,我遇到了问题。当结束角度超过 0/360° 标记时就是这种情况。为了解决这个问题,我使用了路径旋转参数。我在将角度向后移动的同时将扇区向前移动,直到结束角度为 360。您可以在此函数的小提琴中看到这一点:

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"]);
}

虽然效果很好,但我有点怀疑。这可以在不旋转路径的情况下解决吗?我感谢任何帮助或指示。

4

1 回答 1

2

Can this be solved without the rotation of the path?

答:是的,可以。您根本不必更改路径的旋转。除非我遗漏了某些东西,否则以下代码似乎与您在小提琴中的代码相同:

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 SpecRaphael Reference Library中的 SVG 术语。也就是说,当您使用cxcyrotation时,它们分别使用rxryx-axis-rotation

简而言之,无论何时rxequals ry, thenx-axis-rotation都是没有意义的。

看看这个 SVG。使用浏览器的开发工具,或将 SVG 保存到您的计算机并使用文件编辑器进行编辑。具体来说,查看最后一个path元素,其中有四个弧。尝试修改x-axis-rotation每个弧上的值。您会注意到,当您更新值时,第一个弧(其中rxry都是“25”)永远不会改变。x-axis-rotation

为什么? 这是因为你有一个圆弧。无论你旋转一个圆圈多少,它仍然是同一个圆圈。例如,在您面前举起一个玻璃杯,使玻璃杯与地面水平,并且您正直视玻璃杯。现在用手腕旋转/扭转玻璃。你看到你看到的圆形是如何保持在同一个圆形的吗?现在将玻璃杯正常放在桌子上(因此它是垂直的并且可以容纳液体)。现在把玻璃翻过来。可以看到明显的视角变化;它本来是朝上的,但现在它是平躺的。就是x-axis-rotation这样。

也许一个更好的例子是只玩前面提到的 SVG 文件。在最后一个元素x-axis-rotation的弧上玩。path您将看到圆弧正在旋转。就是x-axis-rotation这样。

回到您的代码: 因为您只处理圆形对象,x-axis-rotation所以最终输出没有任何区别。只要您处理循环对象,您就可以将其值硬编码为零而无需担心。您真正需要做的就是修改您正确完成的角度。

性能: 我尝试使用 JavaScript 在sector_update修改和不修改x-axis-rotation变量的情况下为您的函数计时。结果?我没有看到性能上的差异。大部分时间花在实际绘制 SVG 上,而不是在确定其值的数学上。事实上,您在 JavaScript 中真正所做的只是更新代码以设置path元素中的值。在那个时间点,浏览器接管它的渲染引擎来实际绘制 SVG 对象。我想这是每个浏览器的问题,因为每个浏览器都有不同的渲染性能。但至于该x-axis-rotation值是否有任何影响,我的猜测是否定的。如果性能下降(因为浏览器可能必须执行额外的浮点操作),因为绝大多数时间都花在绘制对象上,而不是计算它的值,所以它非常没有实际意义。所以我想说不要担心。

我希望这会有所帮助,如果我遗漏了什么或解释得不够好,请告诉我。

于 2012-07-22T03:19:49.773 回答