【问题标题】:Raphael custom attribute (Arc) results in deformed circleRaphael 自定义属性(Arc)导致圆形变形
【发布时间】:2012-09-07 09:28:40
【问题描述】:

我正在为 jQuery 开发一个进度条插件,它利用 Raphael 来实现平滑的图形。

我尝试改造this Raphael example (polar clock)提供的属性函数。

问题是,一开始我没有注意到拉斐尔的例子也有变形错误。相对较大的圆圈只是减轻它。看着较小的,很明显。

是的,我基本上复制粘贴了该函数并进行了一些小调整,但最终结果出现了同样的错误。

我已经设置了一个 JSBin,我在场景中添加了参考圆,因此更容易发现问题:http://jsbin.com/ekovir/1

如何调整 Arc 函数以绘制正确的圆?

【问题讨论】:

    标签: javascript jquery svg raphael geometry


    【解决方案1】:

    我认为这是 Chrome 的 SVG 渲染实现中的一个错误。至少在 FireFox 和 Safari 中看起来要好得多。

    另外,在选择圆弧到点时,我认为最好使用(center.x + radius * cos(a-0.01), center.y + radius * sin(a-0.01)),而不是(center.x + radius * cos(a) - 0.01, center.y + radius * sin(a)),否则中心可能会偏移一点。

    作为一种解决方法,我建议为进度条创建一组分段,然后在工作完成时更改它们的颜色,而不是在旧分段上绘制新分段。这在任何浏览器中都应该看起来不错,而且我认为如果没有对比鲜明的背景圆圈,这些缺陷不容易被发现。

    【讨论】:

      【解决方案2】:

      我找到了导致圆圈变形的原因。

      我用stroke-width设置了圆的“胖”/“帽”,越大越变形。

      至少,这些是我的观察结果,从技术上讲,它也可能是由其他原因引起的。

      无论如何,为了得到合适的甜甜圈,我最终采用了这种方法:

      /**
       * Donut circle drawing
       *
       * @param  integer  start       Percentage to start with
       * @param  float    diameter
       * @param  float    fat         How fat should the circle bar be
       * @return object
       */
      var fatDonutArc = function (start, diameter, fat)
      {
          var center = diameter / 2;
          var outerRadius = center;
          var innerRadius = center - fat; // subtract fat
      
          var alpha = 360 / 100 * start;
          var a = (90 - alpha) * Math.PI / -180; // -180 starts to draw from 12 o'clock
      
          // calculate outer ring point coordinates
          var outerX = center + outerRadius * Math.cos(a);
          var outerY = center + outerRadius * Math.sin(a);
      
          // calculate inner ring point coordinates
          var innerX = center + innerRadius * Math.cos(a);
          var innerY = center + innerRadius * Math.sin(a);
      
          // path cache
          var path;
      
          if (start !== 100)
          {
              path = [
                  // move to start point of inner ring
                  [
                      "M",
                      center,
                      center - innerRadius
                  ],
      
                  // draw a line to outer ring
                  [
                      "L",
                      center,
                      center - outerRadius
                  ],
      
                  // arc to outer ring end
                  [
                      "A",
                      outerRadius,
                      outerRadius,
                      0,
                      +(alpha > 180),
                      1,
                      outerX,
                      outerY
                  ],
      
                  // move to inner ring end
                  [
                      "L",
                      innerX,
                      innerY
                  ],
      
                  // arc to inner ring start
                  [
                      "A",
                      innerRadius,
                      innerRadius,
                      0,
                      +(alpha > 180),
                      0,
                      center,
                      center - innerRadius
                  ]
              ];
          }
          else
          {
              path = [
                  // move to outer ring start
                  [
                      "M",
                      center,
                      center - outerRadius
                  ],
      
                  // arc around the clock
                  [
                      "A",
                      outerRadius,
                      outerRadius,
                      0,
                      +(alpha > 180),
                      1,
                      outerX - .1, // subtract, otherwise the path becomes "reset"
                      outerY
                  ],
      
                  // connect
                  [
                      "z"
                  ],
      
                  // move to inner circle start
                  [
                      "M",
                      innerX,
                      innerY
                  ],
      
                  // arc around the clock
                  [
                      "A",
                      innerRadius,
                      innerRadius,
                      0,
                      +(alpha > 180),
                      0,
                      innerX + .1, // subtract, otherwise the path becomes "reset"
                      innerY
                  ],
      
                  // and connect
                  [
                      "z"
                  ]
              ];
          }
      
          return {
              path : path
          };
      };
      

      这是一个混搭:raphael.js - converting pie graph to donut graph + http://raphaeljs.com/polar-clock.html

      我在这里设置了一个示例,以查看它的实际效果:http://jsbin.com/erusos/1

      还有一个悬而未决的问题:在 Chrome 中,是 CSS 渲染器,没有完全环绕圆形,还是 SVG?

      享受吧!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-17
        • 1970-01-01
        • 2012-04-10
        • 1970-01-01
        • 2012-02-15
        • 1970-01-01
        • 2014-10-13
        • 1970-01-01
        相关资源
        最近更新 更多