SVG NG-repeat'ed元素SMIL动画只发生在页面加载(SMIL animatio

2019-10-21 05:12发布

我产生了一些<rect> s的<animate>使用NG重复指令的孩子。

在页面加载动画正确触发,一切都发生如预期。 然而,当我添加一个新的<rect>动画不会发生。

下面的代码片段演示了此行为:

 function Controller($scope) { $scope.rects = []; var spacing = 5; var width = 10; var height = 100; var x = 10; var y = 10; $scope.newRect = function() { $scope.rects.push({ x: x, y: y, width: width, height: height }); x += spacing + width; }; for (var i = 0; i < 5; i++) { $scope.newRect(); } } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app ng-controller="Controller"> <svg width="1000" height="200"> <rect ng-repeat="rect in rects" x="{{rect.x}}" y="{{rect.y}}" height="{{rect.height}}" width="{{rect.width}}"> <animate attributeName="y" from="{{rect.height}}" to="{{rect.y}}" dur="1s" repeatCount="1" /> <animate attributeName="height" from="0" to="{{rect.height}}" dur="1s" repeatCount="1" /> </rect> </svg> <button ng-click="newRect()">One more</button> </div> 

在加载的例子中,4 <rect>将出现,从底部到顶部动画。 然而,按“多了一个”按钮时,新<rect>无动画(行为在Firefox 35和Chrome 38测试)将被添加。

我怎样才能引发新的动画<rect> S'

Answer 1:

默认开始时间为动画元件(相当于begin="0s" )相对于所述负载SVG时间总是测量。 这是真实的,即使你的页面加载后动态创建动画元素。

如果你需要的任何其他开始的时候,你就需要(一)明确设置不同的值的begin属性,或(b)使用beginElement()beginElementAt(offsetTime)动画元素的DOM对象的方法。 既然你使用脚本创建的元素,你希望他们将它们插入后立即启动,该beginElement()方法可能是最简单的方法。

编辑补充:

如果beginElement不工作,因为角的js不为您提供直接访问创建的元素,你可以为使用该事件格式的begin属性。 如果开始属性包含DOM事件的名称(或分号分隔的时间和事件名称列表),当事件发生时,动画将开始。 默认情况下,该事件将被听取该动画将影响-矩形在你的案件的元素。 (可以配合动画以使用不同的元件elementID.eventName格式)。

诀窍让动画为它添加是将其链接到很少使用的一个尽快启动DOM的突变事件 ,特别是DOMNodeInserted 。 这样一来,当您添加动画节点的子<rect> ,或者当您添加<rect>的SVG的事件,然后动画将立即触发。

如果你想插入元素和触发动画之间的延迟,使用eventName + timeOffset格式。

这里是香草JS概念证明(如小提琴) 。

这是你要修改的摘录; JS代码是相同的,只有角模板已经改变:

 function Controller($scope) { $scope.rects = []; var spacing = 5; var width = 10; var height = 100; var x = 10; var y = 10; $scope.newRect = function() { $scope.rects.push({ x: x, y: y, width: width, height: height }); x += spacing + width; }; for (var i = 0; i < 5; i++) { $scope.newRect(); } } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app ng-controller="Controller"> <svg width="1000" height="120"> <rect ng-repeat="rect in rects" x="{{rect.x}}" y="{{rect.y}}" height="{{rect.height}}" width="{{rect.width}}"> <animate attributeName="y" from="{{rect.height}}" to="{{rect.y}}" dur="1s" repeatCount="1" begin="DOMNodeInserted"/> <animate attributeName="height" from="0" to="{{rect.height}}" dur="1s" repeatCount="1" begin="DOMNodeInserted"/> </rect> </svg> <button ng-click="newRect()">One more</button> </div> 

我不知道你是否有意想有酒吧开始10px的从底线偏移。 如果这是偶然的,你可以通过设置修复它from第一动画的价值rect.height + rect.y

我测试了最新的Chrome和Firefox的小提琴。 如果您需要支持旧的浏览器,特别是如果你有一个SMIL填充工具支持旧的IE浏览器,你需要进行测试,以确保DOM突变事件是否被正确抛出。



文章来源: SMIL animation on SVG ng-repeat'ed element only occurs on page load