好吧,首先要做的事情是:为了优雅地为弧段设置动画,我们需要能够以编程方式生成它们。考虑一下这个笨拙的三角函数:
// arcPath:
// cx, cy are the center point
// inner_radius and outer_radius describe the distance of the arc segment's inner and outer boundaries from the center point.
// starting_radians describes the offset of the segment start;
// arc_radians describes the width of the arg segment.
function arcPath( cx, cy, inner_radius, outer_radius, starting_radians, arc_radians )
{
var x1 = cx + Math.cos( starting_radians ) * inner_radius;
var y1 = cy + Math.sin( starting_radians ) * inner_radius;
var x2 = cx + Math.cos( starting_radians ) * outer_radius;
var y2 = cy + Math.sin( starting_radians ) * outer_radius;
var x3 = cx + Math.cos( starting_radians + arc_radians ) * outer_radius;
var y3 = cy + Math.sin( starting_radians + arc_radians ) * outer_radius;
var x4 = cx + Math.cos( starting_radians + arc_radians ) * inner_radius;
var y4 = cy + Math.sin( starting_radians + arc_radians ) * inner_radius;
var pathstr = "M" + x1 + "," + y1 + " "
+ "L" + x2 + "," + y2 + " "
+ "A" + outer_radius + "," + outer_radius + " " + arc_radians + " " + ( arc_radians > Math.PI ? "1" : "0" ) + " 1 " + x3 + "," + y3 + " "
+ "L" + x4 + "," + y4 + " "
+ "A" + inner_radius + "," + inner_radius + " " + ( 0 - arc_radians ) + " " + ( arc_radians > Math.PI ? "1" : "0" ) + " 0 " + x1 + "," + y1 + " z";
return pathstr;
}
使用更简单的几何构造,您可以简单地为从部分弧段到整个弧段的路径设置动画,并让 Raphael 进行提升,如下所示:
var arcPath1 = paper.path(arcPath( 150, 150, 75, 125, Math.PI / 2, Math.PI * 0.65 ) )
.attr({ fill: "#003a60", 'fill-opacity': 0.5, stroke: 'black' });
arcPath1.click(function ()
{
arcPath1.animate( { path: arcPath( 150, 150, 75, 125, Math.PI / 2, Math.PI * 2 - 0.0001 ) }, 2000, "<>" );
});
不幸的是,Raphael 在这方面做得非常糟糕,所以你会看到大量相交的弧线段将它们自己重新塑造成一个完整的圆,而不是所需的弧线扫描。所以为了让它做你想做的事,我们必须手动执行动画。
function arcSweep( arc, x, y, inner, outer, angle_offset, from_sweep, to_sweep, duration )
{
var steps = 100;
var current_step = 0;
var intervalID = setInterval( function()
{
current_step++;
if ( current_step >= steps )
clearInterval( intervalID );
arc.attr( { path: arcPath( x, y, inner, outer, angle_offset, from_sweep + ( ( to_sweep - from_sweep ) * ( current_step / steps ) ) ) } );
}, duration / steps );
}
所以基本上我们只是计算一系列中间弧并依次建立它们,直到我们达到目标角度。除了目标结束角度之外,动画函数还需要弧的所有原始参数(不能是 Math.PI * 2——因为它计算为空弧段!)。可能需要将其抽象为一个类,以便弧段的每个实例都可以跟踪其自己的变量。
这是一个演示成品的小提琴。