EzDevInfo.com

Snap.svg

The JavaScript library for modern SVG graphics. Snap.svg - Home

How do I understand Transform properties in snap.svg?

I have been trying to learn snap.svg and I have some doubts regarding the transform properties. My question is pretty stupid but here it is

In the following sample code, what do the the numbers mean?

     {"transform" : "t-10 0 s0 32 32"}
     {"transform" : "r180 32 32"}

I am guessing that s stands for scale, Also what is the difference between animAfter and after? I am very new to SVGs.


Source: (StackOverflow)

Snap.svg can't find dynamically (and successfully) appended SVG element with jQuery

Snap.svg doesn't work in this case :

$('body').append($('<svg>').attr('id', 'test')) ;
console.log($('#test').length) ; // 1

var svg = Snap('#test') ;
svg.circle(100, 100, 50) ;
// Uncaught TypeError: Object [object Object] has no method 'circle'

... but works when the element is already in the HTML :

<body>
    <svg id="test"></svg>
</body>

The SVG element is successfully in the HTML but can't be found with Snap.svg. Am I doing it wrong with the first example or is it a bug ?


Source: (StackOverflow)

Advertisements

how to resize a large svg to fit inside a div

I have the following div inside <body>.

<div style="width:320px; height:480px;">
    <svg id="svg1"></svg>            
</div>

I want to fit a 640X480 svg inside this div. I have tried this:

var paper=Snap("#svg1");
Snap.load("somesvg.svg",function(f){ 
 paper.append(f);
 }); 
 paper.attr({ 
 width:320, height:480
 }) 

But the svg is cut off from the right size.


Source: (StackOverflow)

Snap.svg - drag event handler

Question is about the onstart event handler for Element.drag in the newly announced Snap.svg.

The intention of the code below is to register event handlers for the start and stop of a drag (onstart/onstop) on an svg object.

        var s = Snap(800,600);

        var bigCircle = s.circle(300,150,100);

        bigCircle.drag(null,
                function(){
                    console.log("Move started");
                },
                function(){
                    console.log("Move stopped");
                }
        );

The console messages work fine on drag start and stop, but the null overrides the default onmove function - resulting in no actual drag happening. How do I pass something that says "I don't want to mess with the default onmove"?

(Note: I'd prefer to register an event handler by means of assignment, like the familiar onClick, but that's a different matter.)


Note added after few hours: The Raphael.js documentation and examples provide some clues. At least now I know how to pass in a proper function for onmove that provides the default move behavior:

        var s = Snap(800,600);

        var bigCircle = s.circle(300,150,100);

        start = function() {
            this.ox = parseInt(this.attr("cx"));
            this.oy = parseInt(this.attr("cy"));
            console.log("Start move, ox=" + this.ox + ", oy=" + this.oy);
        }

        move = function(dx, dy) {
            this.attr({"cx": this.ox + dx, "cy": this.oy + dy});
        }

        stop = function() {
            this.ox = parseInt(this.attr("cx"));
            this.oy = parseInt(this.attr("cy"));
            console.log("Stop move, ox=" + this.ox + ", oy=" + this.oy);
        }

        bigCircle.drag(move, start, stop);

Source: (StackOverflow)

Snap.load() external SVG fails to Load

PROBLEM: I'm using Snap.svg to create some basic interactive graphics, but for some reason I can't get my external SVG file to load using Snap.load(). I've pulled code straight from the tutorial at snap.io and checked and double-checked the docs. My SVG file renders in the browser fine, it just doesn't display inside the Snap SVG. Other shapes (i.e. not pulled in using Snap.load() ) do display.

CODE: I've boiled my example down to the most simple HTML and SVG files imaginable, and the Snap.load() method still isn't working for me. Does anyone see what I'm missing?

HTML:

<head>
  <style media="screen">
            #svg {
                width: 300px;
                height: 300px;
            }
  </style>
  <script src="snap.svg-min.js"></script>
  <meta charset=utf-8 />
</head>
<body>
  <svg id="svg"></svg>
  <script type="text/javascript">
    var s = Snap("#svg");
    Snap.load("svgtest.svg");
  </script>
</body>

SVG (originally exported from Illustrator):

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="100px" height="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<rect x="14" y="33" fill="#2BB673" width="70" height="30"/>
</svg>

UPDATE: Updated the code as per @Ian's suggestion -

var s = Snap("#svg");
Snap.load("http://www.w3.org/TR/SVG/images/struct/Use01.svg", onSVGLoaded ) ;

function onSVGLoaded( data ){ 
    s.append( data );
}

- but still no display of external SVG. I tried using an SVG from w3.org just to be sure it wan't a problem with the file itself or my domain.


Source: (StackOverflow)

How to animate path morphs using snap.svg

I have been searching for a good example on how to animate a svg path morph. I know how to do do pretty complex ones using SMIL, but snap.svg is new and shiny, and everyone seems to love it, so I'd like to take a look. I can't find a good example anywhere on how to do n animated path morph anywhere. Hopefully a snap.svg guru could point me in the right direction?

here's a link to the svg image and the code for it:

link to image

<svg xmlns="http://www.w3.org/2000/svg" width="600" height="400">
  <path id="thing"  d="M94.2,265.7L82,203.4c43.3-15.6,83.8-29.2,137.1-20.2c61.5-27.6,126.1-56.9,202.6-46.1c18.7,18.9,21.5,39.8,12.2,62.3C322.7,231.9,208.2,247.6,94.2,265.7z">
    <animate id="myAnimationElement" dur="2s" begin="0" repeatCount="indefinite" attributeName="d"
         values="M94.2,265.7L82,203.4c43.3-15.6,83.8-29.2,137.1-20.2c61.5-27.6,126.1-56.9,202.6-46.1c18.7,18.9,21.5,39.8,12.2,62.3C322.7,231.9,208.2,247.6,94.2,265.7z;

                M179.4,83.5l62.4-11.8c15.3,43.4-76,102.6-22.6,111.5c61.5-27.6,126.1-56.9,202.6-46.1c18.7,18.9,21.5,39.8,12.2,62.3C250.6,296.7,52.4,259.2,179.4,83.5z;"/>
  </path>
</svg>

Source: (StackOverflow)

Get coordinates of svg group on drag with snap.svg

I'm brand new to svg and thought I would try out snap svg. I have a group of circles that I am dragging around, and am looking to get the coordinates of the group. I am using getBBox() to do this, but it isn't working as I would expect. I would expect getBBox() to update its x and y coordinates but it does not seem to do that. It seems simple but I think I am missing something. Here's the code

var lx = 0,
  ly = 0,
  ox = 0,
  oy = 0;
  moveFnc = function(dx, dy, x, y) {
      var thisBox = this.getBBox();
      console.log(thisBox.x, thisBox.y, thisBox);
      lx = dx + ox;
      ly = dy + oy;
      this.transform('t' + lx + ',' + ly);
  }
  startFnc = function(x, y, e) {  }
  endFnc = function() {
      ox = lx;
      oy = ly;  
      console.log(this.getBBox());
  };

var s = Snap("#svg");
var tgroup = s.group();
tgroup.add(s.circle(100, 150, 70), s.circle(200, 150, 70));
tgroup.drag(moveFnc, startFnc, endFnc);

The jsfiddle is at http://jsfiddle.net/STpGe/2/

What am I missing? How would I get the coordinates of the group? Thanks.


Source: (StackOverflow)

SnapSVG: Remove mask from an element (unmask)

I have my JS code in which I use Snap SVG. At some point I use

element.attr({mask:maskelement});

In that snippet, element and maskelement are two elements inside my svg.

Now I want to remove the mask. What would be the correct code that achieves this?


Source: (StackOverflow)

How to listen to a load event of an object with a SVG image?

I want to manipulate a SVG image after it's loaded with snap.svg. Unfortunately the callback of the load event is never called. How can I register a load event to the svg object?

I have created this minimal example of my problem.

HTML:

<object data="http://upload.wikimedia.org/wikipedia/en/8/80/Wikipedia-logo-v2.svg" type="image/svg+xml" id="animation" />

Javascript:

alert('loading');
$('#animation').on('load', function() {
  alert('loaded');
});

Source: (StackOverflow)

How to change the points of a polygon in Snap.svg through animation?

I'm trying to implement a button with a certain polygon on it, which when pressed changes the polygon to something else. For example the play icon on the button changing to stop icon. Ideally the icon should be a polygon with three points depicting the play symbol. After animation it turns into a polygon of four points(A square) depicting the stop symbol.

I tried doing it this way:

var paper = Snap('svg');
var tpts = [100,100,100,130,120,115];
var sqpts = [100,100,100,130,130,130,130,100];
var tri = paper.polygon(sqpts);
tri.attr({
    id:"tri",
    fill:"#555555"
});

sqrFunc = function(){
    tri.animate({"points":sqpts},1000,mina.linear);
}
triFunc = function(){
    tri.animate({"points":tpts},1000,mina.linear);
}

On clicking the button once I call sqrFunc and on clicking it again I call triFunc. I tried assigning different point arrays to "points" because when I query tri.attr("points") I get the assigned points as return value. However, trying to assign the arrays like this ends up in errors. Any help regarding this problem is greatly appreciated.


Source: (StackOverflow)

Set ID attribute on a Snap.svg graphic

I'm using Snap.svg API and I have three graphics that I need to select in my CSS for styling purposes. Thus, to distinguish between them, I need to give them an ID or class name.

This is how I create an element:

var draw = Snap(100, 75);
c = draw.polyline(0,0, 50,75, 100,0, 0,0);
c.attr({
    fill: "black"
});

This is the result I get:

<svg height="75" version="1.1" width="100" xmlns="http://www.w3.org/2000/svg">
    <polyline points="0,0,50,75,100,0,0,0" style="" fill="#000000"></polyline>
</svg>

This is what I need the result to be:

<svg id="graphic_1" height="75" version="1.1" width="100" xmlns="http://www.w3.org/2000/svg">
    <polyline points="0,0,50,75,100,0,0,0" style="" fill="#000000"></polyline>
</svg>

Source: (StackOverflow)

Manipulate a path in Snap.svg or redraw it?

For a metaball animation like this one: http://paperjs.org/examples/meta-balls/ I am creating a path in snap.svg that connects two circles. It looks like this:

<path d="M171 370 C207, 335, 493 335, 529 370 C493, 335, 493 264, 529 229 C493, 264, 207 264, 171 229 z"></path>
  1. What would be better: to redraw the path on each frame or to manipulate it?
  2. How can I manipulate the path? (i.e. move the points and control points around)

If it were more than two circles, I suppose redrawing would be the way to go.


Source: (StackOverflow)

How do you get the rotation value of an svg object with snap.svg?

So, I'm using snap.svg and I'd like to dynamically rotate an object over time. Something like this:

function rotateObject()
{
    myObject.rotation += value;
}

The problem is I don't know how to access the rotation values for my display objects (or if they even exist!) So given something simple, let's say a circle declared like this:

snap = Snap(800,600);   
circle = snap.circle(400,300,50);

I know I can access the x and y values like so:

circle.attr("cx");
circle.attr("cy");

What I need help with is:

  1. Is there a rotation property of some sort that I can use to rotate this object?
  2. If not, how do I rotate an object with snap.svg?

Source: (StackOverflow)

SVG - Endless rotation takes wrong center point

I made a codepen with snap svg: Codepen

I try to rotate a svg-gear in an endless-loop around his own centerpoint. This works on Internet Explorer, but fails on Mozilla-Firefox and Google-Chrome.

The center point in Chrome and Firefox seems wrong and so the gear move out of his position.

enter image description here

For the rotation i used following code:

function infRotate(el, time, cw) {
        var box = el.getBBox();
        el.transform('r0,' + box.cx + ',' + box.cy);
        if (cw)
            el.animate({transform: 'r360,' + box.cx + ', ' + box.cy}, time, mina.linear, infRotate.bind(null, el, time, cw));
        else
            el.animate({transform: 'r-360,' + box.cx + ', ' + box.cy}, time, mina.linear, infRotate.bind(null, el, time, cw));
    }

What i have to do for Firefox and Chrome to find right center point? Thanks for your help.


Source: (StackOverflow)

Translating browser click event `x` and `y` coordinates to coordinates on a scaled Snap svg element

I needed to add a piece of text to an svg rendered by snap, at the point where the user clicks.

Because the SVG is scaled using 100% width and uses the viewBox attribute, I needed to translate the x and y coordinates provided by the browser's click event to x and y coordinates on the scaled svg.

I managed to make this work by using this piece of code:

var $canvas = $('svg#myscaledsvg');
var snap = new Snap($canvas[0]);

snap.mousedown(function(event) {
    var offset = $canvas.offset();
    var matrix = snap.transform().diffMatrix.invert();

    var x = matrix.x(event.pageX - offset.left, event.pageY - offset.top);
    var y = matrix.y(event.pageX - offset.left, event.pageY - offset.top)

    // below function call actually renders the text element to the given x and y coords       
    addSomeText(x, y);
});

Now, I understand why I need to subtract the offsets. What I don't understand is what snap.transform().diffMatrix.invert() actually does.

Can someone enlighten me why this works? I can't get much from the snap documentation, which seems rather sparse overall.


Source: (StackOverflow)