angularjs - SMIL animation on SVG ng-repeat'ed element only occurs on page load -



angularjs - SMIL animation on SVG ng-repeat'ed element only occurs on page load -

i'm generating <rect>s <animate> children using ng-repeat directive.

on page load animations correctly triggered , happens expected. however, when add together new <rect> animation not occur.

the next code snippet demonstrates behaviour:

class="snippet-code-js lang-js prettyprint-override">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; }; (var = 0; < 5; i++) { $scope.newrect(); } } class="snippet-code-html lang-html prettyprint-override"><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>

upon loading example, 4 <rect> appear, animating bottom top. however, when pressing "one more" button, new <rect> added without animation (behaviour tested on firefox 35 , chrome 38).

how can trigger animation new <rect>s?

the default begin time animation element (equivalent begin="0s") measured relative svg load time. true if create animation element dynamically after page load.

if want other begin time, need either (a) explicitly set different value begin attribute, or (b) utilize beginelement() or beginelementat(offsettime) methods of animation element dom objects. since you're creating elements scripts , want them start right after inserting them, beginelement() method easiest approach.

edited add:

if beginelement isn't working because angular-js doesn't provide direct access created element, can create utilize of event format begin attribute. if begin attribute contains name of dom event (or semi-colon separated list of times , event names), animation begin when event occurs. default, event listened on element animation affect—the rectangle in case. (you can tie animation different element using elementid.eventname format).

the trick animation start added link 1 of used dom-mutation events, domnodeinserted. way, when add together animation node kid of <rect>, or when add together <rect> svg, event , animation triggered immediately.

if want delay between inserting element , triggering animation, utilize eventname + timeoffset format.

here proof of concept vanilla js (as fiddle).

and here modified snippet; js code same, angular template has changed:

class="snippet-code-js lang-js prettyprint-override">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; }; (var = 0; < 5; i++) { $scope.newrect(); } } class="snippet-code-html lang-html prettyprint-override"><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>

i'm not sure whether intentionally want have bars start 10px offset bottom line. if accidental can prepare setting from value of first animation rect.height + rect.y.

i've tested fiddle in latest chrome , firefox. if need back upwards older browsers, if you're supporting older ie smil polyfill, you'll want test create sure dom mutation events beingness thrown correctly.

angularjs animation svg smil

Comments

Popular posts from this blog

assembly - What is the addressing mode for ld, add, and rjmp instructions? -

vowpalwabbit - Interpreting Vowpal Wabbit results: Why are some lines appended by "h"? -

Is there a way to convert an HTML page styled with Bootstrap CSS into email-compatible html? -