Search code examples
javascripthtmlcsssnap.svginkscape

Can't add elements with SnapSVG to my Page


So I am using SnapSVG to manipulate (animate) my SVG File that i created with Inkscape. The animating of the different elements like a rectangle or circle is working completely fine. The problem that i have is when i try to add a new element like a rectangle with SnapSVG code it does not work and the whole screen is blank (everything disappears). Why do i have this problem? Is it even possible to add a new element with SnapSVG to a existing SVG File?

Down below i showed you some code on how i manipulate the SVG and how it gets displayed in a DIV on my Page. And I am also showing you how I am trying to add a new Element with SnapSVG

I tried almost everything. I can put the code for the new Element outside of the code for the already existing SVG but then it always appears outside of the SVG file.

  <head>
        <meta charset="utf-8">
        <title>Inkscape Animated Icon Snap</title>
<!--We need to add the Snap.svg script to our document-->
        <script src="snap.svg.js"></script>
        <script>
//Run script right away
            window.onload = function () {
//We'll be appending the icon to this DIV later
                var s = Snap("#svgDiv");
//Have Snap load the SVG file
                Snap.load("icon.svg", function(f) {
                    s.append(f);
//Assign the white rectangle
                    whiteRect = f.select("#whiteRect");

//Assign the whole icon group
                    icon = f.select("#icon");

                    //When the icon is hovered over, have the white rectangle move up slightly with elastic properties
                    icon.hover(function() {

                        whiteRect.animate({y:18}, 500, mina.elastic);
                    },
//And return to original position when not hovered over
                               function() {
                        whiteRect.animate({y:23.984177}, 500, mina.elastic);
                    }
                    );

                    var bigCircle = s.circle(0, 0, 20).attr({fill: 'green' });
            icon.append(bigCircle);
//Finally append the icon to iconDiv in the body

                });          
            };
        </script>
    </head>
    <body>
<!--Here's the DIV that will hold the animated SVG icon-->
<svg id="svgDiv"></svg>     
    </body>

So basically what I want as a result is just another rectangle added to my SVG File. What i get is a blank Page.


Solution

  • 2 main things spring to mind (hard to be sure without the html/svg as well).

    Firstly, you Snap must be called on an SVG element, not an HTML element, so when I see this line...

    var s = Snap("#iconDiv");
    

    it's almost certainly wrong. It cannot be a div, or any HTML element. Snap works on SVG elements,

    var s = Snap("#anSVGselement");
    

    is what's needed.

    Secondly, your line

    s.append(f);
    

    Wants to be straight after the Snap.load()

    Snap.load("icon.svg", function(f) {
        // stuff here probably won't work, there are some minimal methods like select, but not like hover etc
        s.append(f);
        //do stuff now it's appended
        var icon = s.select("#icon");
        var bigCircle = s.circle(10, 970, 20);
        icon.append(bigCircle);
    });
    

    The problem is, f is just a fragment at this point, it has no place in the DOM yet, so methods like 'hover' etc, aren't available until you have added with append into the DOM. Once it's appended these methods become available. There are a few methods available like select, before it's appended (so you 'may' be able to select an element from the fragment and then append that, rather than appending everything I think).

    Example

    Also note, the icon.svg file has some transforms on it, so you will need to adjust the circle to have the correct cx/cy like in my example, or add a transform to match (or remove the transforms from the original svg and have correct cx/cy)