Michal Zimmermann
Michal Zimmermann

Reputation: 656

SVG SMIL animateMotion only triggers once

I have a SVG map of air flight destinations for Prague airport. I'd like to animate a circle along a path to each of these airports.

Grab the code here (sorry for this, doesn't work on jsfiddle).

The code that takes care of "flight" animation looks as follows:

function animate() {
    var flights = {
        100: ["travel-svo", "travel-svo"],
        600: ["travel-fra", "travel-fra", "travel-fra", "travel-fra", "travel-fra",
                 "travel-fra", "travel-fra", "travel-nap"],
        620: ["travel-ams", "travel-ams"],
        700: ["travel-lhr", "travel-lhr", "travel-lhr", "travel-lhr", "travel-lhr"],
        710: ["travel-cdg", "travel-cdg", "travel-cdg", "travel-cdg", "travel-cdg"],
        805: ["travel-gva"],
        810: ["travel-vie", "travel-vie", "travel-vie", "travel-vie"],
        850: ["travel-ams", "travel-ams", "travel-ams"],
        855: ["travel-svo"],
        930: ["travel-beg", "travel-beg"],
        935: ["travel-muc", "travel-muc", "travel-muc"],
        945: ["travel-sof", "travel-sof"],
        950: ["travel-fco"],
        955: ["travel-cdg", "travel-cdg", "travel-cdg", "travel-cdg", "travel-cdg",
                 "travel-cdg", "travel-cdg"],
        1010: ["travel-mad", "travel-mad", "travel-mad", "travel-mad", "travel-mad"],
        1015: ["travel-svo", "travel-svo"],
        1025: ["travel-zrh"],
        1030: ["travel-dxb", "travel-dxb", "travel-arn"],
        1035: ["travel-fra", "travel-fra", "travel-fra", "travel-fra", "travel-fra",
                "travel-fra"],
        1040: ["travel-led", "travel-led"]
    };

    var circle = function(coef, flight_id) {
        var svgns = "http://www.w3.org/2000/svg";
        var svgDocument =document;
        var motion = svgDocument.createElementNS(svgns,"animateMotion");
        var shape  = svgDocument.createElementNS(svgns, "circle");

        motion.setAttribute("begin", "path_ani.end");
        motion.setAttribute("dur", "10s");
        motion.setAttribute("path", document.getElementById(flight_id).getAttributeNS(null, "d"));
        motion.setAttribute("xlink:href", "#" + flight_id);

        shape.setAttributeNS(null, "r",  1*coef);
        shape.setAttributeNS(null, "fill", "1f78b4");
        shape.setAttributeNS(null, "stroke", "1f78b4");
        shape.setAttribute("id", "airplane-" + flight_id);
        shape.appendChild(motion);
        document.getElementById("airplanes").appendChild(shape);
    }
    setTimeout(function() {
        var time = 100;

        var interval = setInterval(function() {
            var f = flights[time];
            var counts = {};

            if (f) {
                // count unique items
                for(var i = 0; i < f.length; i += 1) {
                    var num = f[i];
                    counts[num] = counts[num] ? counts[num]+1 : 1;
                }

                for (var flight in counts) {
                    circle(counts[flight], flight);
                }
            }
            time += 5;
            // stop
            if (time > 1040) {
                clearInterval(interval);
            }
        }, 50);
    }, 12000);
}

The first animation (first key of flights object) starts as it should, while the rest appear at 0,0 (top left corner of the screen) and don't move at all. I have no idea what might be causing this, as the circle() function defines new <animateMotion> element for every unique flight.

UPDATE: jsfiddle

Upvotes: 3

Views: 280

Answers (1)

Kaiido
Kaiido

Reputation: 136638

It seems that your begin attribute for those elements is set to the past.
(path_ani.end already triggered before you create the two last animateMotion elements).

As I don't know the expected behavior, I'll let you figure out what to do
(Either find why the two last planes are created after, or what's the correct value to insert into their begin attributes.)

Updated fiddle with begin attributes set to 15s

Upvotes: 1

Related Questions