【问题标题】:animating SVG path when changing value更改值时为 SVG 路径设置动画
【发布时间】:2015-02-01 11:00:55
【问题描述】:

我正在尝试使用 SVG 和 angular 指令创建一个图形来更改动态部分。现在我已经这样做了:

http://plnkr.co/edit/TcbK7kyzM3tapDISxndh?p=preview

app.directive('pieChart', function($document) {
    return {
        restrict: "E",
        template: '<svg width="500" height="500">' +
          '<path d="M100,200 a150,150 0 1,0 150,-150" stroke="black" stroke-width="10" fill="none"></path>' +
        '</svg>',
        scope: {
          value: '='
        },
        link: function(scope, elem, attr) {
        }
    }
});

我希望我的图表在值为 100% 时看起来像这样,当值为 - 比如说 - 45% 时,我希望看到这条线,但距离顶部中心只有 45% 的长度.我可能需要重新计算路径的路径值,但我想问,当我用 JS 更改路径以使其在更改大小时具有动画效果时,是否有可能?

提前感谢您,或者如果您知道有关此内容的好教程,请将其链接给我。

编辑:我将指令更改为一个简单的条形图,但这只是举例,我知道这可以在没有 SVG 的情况下完成,因为您可以使用 div 来制作它,但我希望之后的图表更复杂。

这是一个 jsfiddle http://jsfiddle.net/fg9e7eo4/1/

在我的例子中,图表一直在动画,我想让它只动画一次,而不是停留在那个点。

顺便说一句,这是我正在尝试使其工作的指令:

testApp.directive('pieChart', function() {
  var html = 
    '<svg width="510" height="20" style="background: #fff">' +
      '<path d="{{path}}" stroke="red" stroke-width="10" fill="none">' +
        '<animate dur="1s" repeatCount="indefinite" attributeName="d" values="{{path2}}"/>' +
      '</path>' +
    '</svg>';

  return {
    restrict: 'E',
    template: html,
    scope: {
      'value': '='
    },

    link: function(scope, elem, attrs) {

      scope.$watch('value', function(newValue, oldValue) {
        scope.path = 'M 5 10, L ' + (newValue * 5) + ' 10';
        scope.path2 = 'M 5 10, L ' + (oldValue * 5) + ' 10; M 5 10, L ' + (newValue * 5) + ' 10';
        elem.children().children().beginElement();
      });

    }
  };
});

【问题讨论】:

  • 你需要$observe attr的值
  • 我得到了由我在指令中调用的范围更新的值,但我不知道何时更改模板内的路径,如何将路径从最后一个 'd' 动画化到新的
  • 您基本上必须使用一些缓动函数来修改路径。有一些框架(如 snap 或 d3)可以为您做到这一点 - here 是使用 d3 的示例。
  • 我知道你也可以用一种叫做 SMIL 的东西来做动画。没有 js 可以做吗?

标签: angularjs svg angularjs-directive


【解决方案1】:

如果要使用条形图,为什么不使用rect 而不是path? IMO,rectpath 更具描述性。

这是我使用rect 对其进行动画处理的示例。

http://plnkr.co/edit/2hEzBqIVgh0rgE3D0Pd4?p=preview

对于 AngularJS,您只需设置 widthto 属性。

<rect x="10" y="10" height="110" width="500"
     style="stroke:#ff0000; fill: #0000ff">
    <animate
        attributeName="width"
        begin="0s"
        dur="2s"
        from="0"
        to="500"
    />
</rect>

我认为这个答案也很有帮助。
SMIL animation on SVG ng-repeat'ed element only occurs on page load

【讨论】:

  • 感谢您的回复,但我正在寻找一种通过角度指令开始/停止动画的方法,有没有办法将动画的开始/停止与指令中的函数挂钩?所以当模型改变时我可以调用它
  • @PacuraruDaniel,我可能错了,但我不认为您的问题是停止/启动 SVG 动画。我对此有自己的答案,但我们不要让读者感到困惑。我建议您发布另一个问题,让我知道,我很乐意回答。
【解决方案2】:

如果您希望它只动画一次然后停止将 repeatCount="indefinite" 替换为 repeatCount="1" fill="freeze"

如果你确保值中的路径在命令的数量和类型上是一致的,你应该得到流畅的动画。这是一个例子:

<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">
    <path d="M100,200 L150,200" stroke="black" stroke-width="10" fill="none">
        <animate attributeName="d" values="M100,200 L150,200;M100,200 L200, 200" fill="freeze" begin="1s" dur="2s" />
    </path>
</svg>

SVG 测试套件有an example of path animation.,还有一个w3c primer on animation

【讨论】:

  • 是的,我在 jsfiddle 中对其进行了测试,但动画不再起作用
  • 除非你给我看更新的小提琴,否则我看不出你做错了什么。 “不再工作”是否意味着它不顺畅或什么都不做?
【解决方案3】:

不确定您是否愿意尝试新的插件,但从 Easy Pie Chart.js 的外观来看,它有您想要的,它的配置速度非常快,而且非常轻巧。如果您打算使用 SVG,请查看 Raphael.js,我知道您可以为 SVG 设置动画(甚至可以从一个变形到另一个)。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2020-01-29
    • 1970-01-01
    • 2012-07-14
    • 1970-01-01
    • 2013-01-27
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    相关资源
    最近更新 更多