我使用ng-repeat指令为<rect>
个孩子生成了一些<animate>
。
在页面加载时,动画被正确触发,一切都按预期发生。
但是,当我添加新的<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();
}
}
&#13;
<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>
&#13;
加载示例后,将显示4 <rect>
,从底部到顶部进行动画制作。然而,当按下&#34;再多一次&#34;按钮,新<rect>
将添加没有动画(在Firefox 35和Chrome 38上测试行为)。
如何触发新<rect>
的动画?
答案 0 :(得分:4)
动画元素的默认开始时间(相当于begin="0s"
)始终相对于SVG加载时间进行测量。即使您在页面加载后动态创建动画元素,也是如此。
如果您想要任何其他开始时间,您需要(a)为begin
属性显式设置不同的值,或者(b)使用动画元素DOM的beginElement()
or beginElementAt(offsetTime)
方法对象。由于您使用脚本创建元素并希望它们在插入后立即启动,因此beginElement()
方法可能是最简单的方法。
编辑添加:
如果beginElement
不起作用,因为angular-js不能直接访问创建的元素,您可以使用begin
属性的事件格式。如果begin属性包含DOM事件的名称(或以分号分隔的时间和事件名称列表),则动画将在该事件发生时开始。默认情况下,将在动画将影响的元素上侦听事件 - 在您的情况下为矩形。 (您可以使用elementID.eventName
格式将动画绑定到其他元素。)
添加动画后立即启动动画的技巧是将动画链接到很少使用的DOM-mutation events之一,特别是DOMNodeInserted
。这样,当您将动画节点添加为<rect>
的子节点时,或者将<rect>
添加到SVG时,将立即触发事件和动画。
如果您希望在插入元素和触发动画之间有延迟,请使用eventName + timeOffset
格式。
Here is the proof of concept with vanilla JS (as a fiddle)
这是您修改后的代码段; 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();
}
}
&#13;
<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>
&#13;
我不确定你是否有意让条形图从底线开始偏移10px。如果这是偶然的,您可以通过将第一个动画的from
值设置为rect.height + rect.y
来修复它。
我已经测试了最新Chrome和Firefox中的小提琴。如果您需要支持旧版浏览器,特别是如果您使用SMIL polyfill支持旧版IE,那么您需要进行测试以确保正确抛出DOM突变事件。