饼图的线性梯度计算

时间:2014-12-10 12:57:18

标签: javascript svg raphael

我们正在渲染64个饼图,并希望每个pice从中间出一个完美的线性渐变。

现在,如果我将SVG复制到插图画家,它看起来像这样,因为你可以看到渐变在蓝色突出显示的pice中没有完美对齐: enter image description here

我们需要的是对这类作品进行更精确的计算。 enter image description here

这是我们目前使用的代码。我们需要的是gradientAngle的计算,它使渐变更加与中心对齐

var total=64
  , center_x=options.center_x
  , center_y=options.center_y
  , radie=options.radie
  , val = 360 / total;

for (var i=0; total>=i; i++) {
    var start=val*i
      , gradientAngle=val*(total-i)
      , angle = (start + val % 360) * Math.PI / 180;

   renderPiePiece(center_x, center_y, radie, start, start+val, gradientAngle);
}

function renderPiePiece(center_x, center_y, radie, start_angle, end_angle, gradientAngle) {
    var flag = (end_angle - start_angle) > 180;
    start_angle = (start_angle % 360) * Math.PI / 180;
    end_angle = (end_angle % 360) * Math.PI / 180;

    this.paper
        .path(
            ["M", center_x, center_y,
            "l", radie * Math.cos(start_angle), radie * Math.sin(start_angle), 
            "A", radie, radie, 0, +flag, 1, center_x + radie * Math.cos(end_angle), center_y + radie * Math.sin(end_angle), 
            "z"]
        ).attr({
            stroke:'black',
            "stroke-width":1,
            fill:gradientAngle+'-#fff:0-#000'
        });
    }

这是另一个例子,它现在看起来如何。正如您所看到的,渐变并非完全来自中心。 enter image description here

这是脚本的链接: http://jsbin.com/bakinikadi/1/edit?html,css,js,output

1 个答案:

答案 0 :(得分:1)

不是一个很大的解决方案,而是解决问题的方法。

将渐变为零的所有零件制作,然后旋转它们。

var total=30;
var center_x=200;
var center_y=200;
var radie=200;
var val = 360 / total;
for (var i=0; total>=i; i++) {
  var start=val*(total-0.5);
  rot = (val*0.5)+(i*val)
  renderPiePiece(center_x, center_y, radie, start, val*0.5, 0, rot);
}
function renderPiePiece(center_x, center_y, radie, start_angle, end_angle, gradientAngle, rotation) {
  var flag = (end_angle - start_angle) > 180;
  start_angle = (start_angle % 360) * Math.PI / 180;
  end_angle = (end_angle % 360) * Math.PI / 180;
  paper
    .path(
      ["M", center_x, center_y,
        "l", radie * Math.cos(start_angle), radie * Math.sin(start_angle), 
        "A", radie, radie, 0, +flag, 1, center_x + radie * Math.cos(end_angle), center_y + radie * Math.sin(end_angle), 
        "Z"]
    ).attr({
      stroke:'black',
      "stroke-width":1,
      fill:gradientAngle+'-#fff-#000'
    }).transform("r"+rotation+","+center_x+","+center_y);
}

http://jsfiddle.net/crockz/jtfkadmy/