【问题标题】:Fill outer-circle with Raphael JS用 Raphael JS 填充外圆
【发布时间】:2013-11-19 11:27:00
【问题描述】:

我正在尝试根据变量填充圆的边框,如下所示:

我找到了this example,但这不是我想要的。我希望外边框从下往上填充,在圆的两侧。

这是我的代码:

var completion = '5%';

drawcircle("js-raphael-completion", completion);

function drawcircle(div, rate) {
  var archtype = Raphael(document.getElementsByClassName(div)[0], "90%", "90%");
  archtype.customAttributes.arc = function (xloc, yloc, value, total, R) {
    var alpha = 360 / total * value,
        a = (90 - alpha) * Math.PI / 180,
        x = xloc + R * Math.cos(a),
        y = yloc - R * Math.sin(a),
        path;
    if (total == value) {
      path = [
          ["M", xloc, yloc - R],
          ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R]
      ];
    } else {
      path = [
          ["M", xloc, yloc - R],
          ["A", R, R, 0, +(alpha > 180), 1, x, y]
      ];
    }
    return {
       path: path
    };
  };

  // inner ring
  var circle = archtype.circle("50%", "50%", "40%").attr({
      "stroke": "#2787d3",
      "stroke-width": 1
  });

  // text
  var text = archtype.text("95%", "50%", rate).attr({
      'font-size': 14, 'font-family': 'Avenir',
      "fill": "#2787d3"
  });

  // outer ring (filling)
  var my_arc = archtype.path().attr({
      "stroke": "#2787d3",
      "stroke-width": 10,
      arc: [100, 100, 0, 100, 50]
  });

  // animation of outer ring
  my_arc.animate({
     arc: [100, 100, 100, 100, 50]
  }, 1000);
}

查看演示:http://jsfiddle.net/SUBn6/

目前,因为我没有使用百分比作为外环(填充),所以它没有以边框圆(内)为中心。

我遇到的另一个问题是“5%”这个数字。它需要跟随外环(填充),因为它从下到上填充......

有什么想法吗?谢谢。

【问题讨论】:

    标签: javascript graph svg drawing raphael


    【解决方案1】:

    Raphael 似乎没有这样的笔画结束设置。因此,另一种方法是使用两条弧线并填充它们之间的空间以模拟笔画。

    这涉及到更多的几何形状:) 但这应该可行:

    var completion = '5%';
    
    drawcircle("js-raphael-completion", completion);
    
    // JSFiddle needs not onload
    // window.onload = function () {
    //  drawcircle("js-raphael-completion", completion);
    // };
    
    function drawcircle(div, rate) {
        var archtype = Raphael(document.getElementsByClassName(div)[0], "90%", "90%");
        archtype.customAttributes.arc = function (xloc, yloc, value, total, R,lineWidth) {
            var alpha = 360 / total * value,
                a = value / total * Math.PI,
                w = R * Math.sin(a),
                h = R * Math.cos(a),
                gamma = Math.asin(R / (R + lineWidth) * Math.sin(Math.PI / 2 + a)),
                beta = Math.PI/2 - a - gamma,
    
                xOffset = (R + lineWidth) * Math.sin(beta) / Math.sin(Math.PI / 2 + a),
                x = xloc - R * Math.sin(a),
                y = yloc + R * Math.cos(a),
                path;
    
            if (Math.abs(a - Math.PI/2) < 0.0001) {
                xOffset = lineWidth;
            }
    
            if (total == value) {
                path = [
                    ["M", x, y],
                    ["A", R , R , 1, 1, 1, x - 0.01, y],
                    ["L", x - 0.01,y-lineWidth],
                    ["A", R + lineWidth, R + lineWidth, 1, 1, 0, x, y - lineWidth],
                    ["Z"]
    
                    /*
                    ["M", xloc, yloc - R],
                    ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R]
                    */
                ];
            } else {
                path = [
                    ["M", x, y],
                    ["A", R , R , 0, +(alpha > 180), 0, x + 2 * w, y],
                    ["L", x+ 2 * w + xOffset,y],
                    ["A", R + lineWidth, R + lineWidth, 0 , +(alpha > 180) , 1, x - xOffset, y],
                    ["Z"]
                ];
            }
            return {
                path: path
            };
        };
    
        // inner ring
        var circle = archtype.circle(100, 100, 50).attr({
            "stroke": "#2787d3",
                "stroke-width": 3
        });
    
        // text
        var text = archtype.text("95%", "50%", rate).attr({
            'font-size': 14,
            'font-family': 'Avenir',
                "fill": "#2787d3"
        });
    
        // outer ring (filling)
        var my_arc = archtype.path().attr({
            "stroke": "#FF0000",
            "fill":  "#2787d3",
            "stroke-width" : 0,
            arc: [100, 100, 0, 100, 51,10]
        });
    
        // animation of outer ring
        my_arc.animate({
            arc: [100, 100, 100, 100, 51,10]
        }, 1000);
    
    }
    

    http://jsfiddle.net/Xp77x/2/

    【讨论】:

      【解决方案2】:

      我认为你搞砸了 cos 和 sin 的东西 :)。基本上弧的起点是可变的,取决于比率 (xloc - R * sin(a), yloc + R * cos(a)),宽度也是可变的 (2 * R *sin(a))。

      我稍微修改了你的东西:

      var completion = '5%';
      
      drawcircle("js-raphael-completion", completion);
      
      // JSFiddle needs not onload
      // window.onload = function () {
      //  drawcircle("js-raphael-completion", completion);
      // };
      
      function drawcircle(div, rate) {
          var archtype = Raphael(document.getElementsByClassName(div)[0], "90%", "90%");
          archtype.customAttributes.arc = function (xloc, yloc, value, total, R) {
              var alpha = 360 / total * value,
                  a = value / total * Math.PI,
                  w = R * Math.sin(a),
                  h = R * Math.cos(a),
                  x = xloc - R * Math.sin(a),
                  y = yloc + R * Math.cos(a),
                  path;
      
              if (total == value) {
                  path = [
                      ["M", xloc, yloc - R],
                      ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R]
                  ];
              } else {
                  path = [
                      ["M", x, y],
                      ["A", R, R, 0, +(alpha > 180), 0, x + 2 * w, y]
                  ];
              }
              return {
                  path: path
              };
          };
      
          // inner ring
          var circle = archtype.circle(100, 100, 50).attr({
              "stroke": "#2787d3",
                  "stroke-width": 1
          });
      
          // text
          var text = archtype.text("95%", "50%", rate).attr({
              'font-size': 14,
              'font-family': 'Avenir',
                  "fill": "#2787d3"
          });
      
          // outer ring (filling)
          var my_arc = archtype.path().attr({
              "stroke": "#2787d3",
                  "stroke-width": 10,
              arc: [100, 100, 0, 100, 50]
          });
      
          // animation of outer ring
          my_arc.animate({
              arc: [100, 100, 100, 100, 55]
          }, 1000);
      }
      

      见:http://jsfiddle.net/Xp77x/1/

      但是我使用了绝对坐标。要获得相对坐标,您需要稍微解析 % 的输入并将其转换为 0-100 画布。

      【讨论】:

      • 谢谢。几个问题。当外圈开始填充时,与内圈有一些重叠。但这在最后(顶部)附近是固定的:oi41.tinypic.com/x0occ0.jpg。第二个问题与拉斐尔有关。是否可以使路径水平填充而不是围绕圆圈旋转?这有点难以解释(见上面的截图)......就像你用液体填充那个空白的边界......
      猜你喜欢
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-02
      相关资源
      最近更新 更多