Search code examples
javascripthtmlsvgsvg-animate

Animating a linked svg not working; Working fine when inline


I have an svg file comprised of a bunch of paths which I am animating through the method seen here. This is the standard method of animating paths—the one with the dash offset and what not.

I've tested the code and it works fine on my svg file, when it is written inline— that is, the code for the svg paths are written directly into the same document as the script. You can see it in action here. The script being used is this:

$(document).ready(function(){

    var path = document.getElementsByTagName('path');
    var length;
    var anim = document.getElementsByTagName('animate');

    for(i = 0; i < path.length; i++){
        length = path[i].getTotalLength().toString();
        path[i].setAttribute('stroke-dasharray',length+','+length);
        anim[i].setAttribute('values','-'+length+';0');
    }

});

However, when trying to make it work with an svg file in an <object>, I am not so lucky. I have placed the file correctly, and it shows up fine. When I run the modified script, it runs fine, and assigns the length values and what not to each <path> and <animate> element as it should (you can verify this by inspecting the svg elements — the stroke-dasharray property should have a value equal to the length of each path).

The problem is, despite the values properly changing to what should trigger the animation, nothing animates. I am not sure why this would be, as the code operates the exact same as the inline one, with the exception of looking into the svg document rather than the current document... here is the modified version of the script (to work with a loaded svg rather than an inline one):

$(document).ready(function(){
    var a = document.getElementById("logoSVG");
    //it's important to add an load event listener to the object, as it will load the svg doc asynchronously
    a.addEventListener("load",function(){
        var svgDoc = a.contentDocument; //get the inner DOM of .svg
        var path = svgDoc.getElementsByClassName('line');
        var length;
        var anim = svgDoc.getElementsByTagName('animate');

        for(i = 0; i < path.length; i++){
            length = path[i].getTotalLength().toString();
            path[i].setAttribute('stroke-dasharray',length+','+length);
            anim[i].setAttribute('values','-'+length+';0');
        }
    },false);
});

If you would like to see the above code in action (where it is loaded in rather than inline), that is here.


Solution

  • Your problem is that styles defined in the parent document (the stroke-dasharray and stroke-dashoffset rules) don't apply to embedded objects. CSS does not cascade into objects.

    You can either add the style rules directly to the object using JavaScript, or you can embed the CSS rules in the external SVG file instead of the parent document.

    This question has more details.