Skip to content

Instantly share code, notes, and snippets.

@athaller
Forked from osvik/SNAP-SVG-CHEAT-SHEET.md
Created April 22, 2020 03:59
Show Gist options
  • Select an option

  • Save athaller/aa429c21f2821a43d8d16fef10b34d34 to your computer and use it in GitHub Desktop.

Select an option

Save athaller/aa429c21f2821a43d8d16fef10b34d34 to your computer and use it in GitHub Desktop.

Snap SVG cheat sheet

Cheat sheet based on Snap SVG docs.

Intitialize SNAP

Intitialize an svg element by reference:

var s = Snap("#svg");

Note: It can be a complex svg graph or an empty svg tag.

Read the DOM

Select

Select an element inside the SVG by ID:

var n = s.select("#test");

Select another element by tag name:

var u = s.select("rect");

Select works with a CSS selector, normally for an element.

Too see what was selected:

console.log( u.outerSVG());

TODO: Add select more than one element (for example by class name) and change multiple elements.

Parent element

var t = n.parent();

Write in the DOM

Append, prepend

Append and prepend actually move the element from defs to the begining or end of the svg element:

var snip = s.select("#bar");
s.prepend(snip);
// s.append(snip);
// snip.prependTo(s);

With parse you need to use append first and then select before continuing:

var snip = Snap.parse('<rect x="250" y="80" width="74" height="66" ry="0" fill="blue" id="bar"/>');
s.append(snip);
var w = s.select("#bar");
s.prepend(w);
w.attr({x:200});

Clone

Add a copy of the element after the original**:

var q = u.clone();

Use

Make a use copy of the object. See more about use in SVG documentation.

k = n.use();

Remove

n.remove();

To defs

Send the object to the defs area (not visible)

u.toDefs();

Clear

Clear all inside the SVG:

s.clear();

Groups

Create a group:

var s = Snap("#svg");
var n = s.select("#test");
var u = s.select("rect");

var z = s.g(n,u);

Before and after

Hidden5 is an object in defs. With this code we move it to before and after the rectangle.

var hidden5 = s.select("#hidden5");
u.after(hidden5)
var hidden5 = s.select("#hidden5");
u.before(hidden5)

Create objects with javascript

To create new objects with Snap

Circle

var c = s.circle(50, 50, 40);

Image

Place a squared image with 80px at position 10,10:

var c = s.image("example.jpg", 10, 10, 80, 80);

Polyline

Each pair of numbers is a point

var myLine = s.polyline([30,60,130,160]).attr({stroke: "blue"});

Polygon

Each pair of numbers is a point

var myPolygon = s.polygon([20,60,130,170,0,0]);

Path

Note: It should work with a path imported from Inkscape or Illustrator.

var myPath = s.path("M445.25,300V140c0-5.523-4.478-10-10-10h-183c-5.523,0-10,4.477-10,10v160H445.25z");

Text

var j = s.text(55, 120, "Hello world");
j.attr({fontFamily: "Sans-Serif"});
j.attr({fontSize: "22px"});
j.attr({fill: "red"});
var koo = Snap.parse("<tspan>Koo</tspan>");
j.append(koo);

Work with attributes

Attributes are very important to create interactive elements or to animate.

Change atributes

n.attr({cx: 80, cursor: "pointer"});
q.attr({x: 120, y: 100, fill:"blue"});

Read attribute

Read attribute cx from element n:

n.attr().cx

Transform

Rotate, translate and scale:

c.transform( "r45");
c.transform( "r45 110 10");

Translate from the current position:

c.transform( "t-45,45");

Scale from the center, scale width but not height and scale from the 0,0 coordinates:

c.transform( "s1.5");
c.transform( "s1.5,1");
c.transform( "s2 0 0");

Classes

Classes are very important to manage state and work with animations.

Add a class

Add a class to an SVG element:

n.addClass("foo");

Has this class?

Check if an element has a specific class. In this example "foo"

n.hasClass("foo") // true or false

Remove class

Remove the class foo from the element n:

n.removeClass("foo");

Events

Events is how you make your pages listen to user input:

Click

Add the event:

n.click(function(){
    console.log("You have clicked in the elipse");
});

Remove all events from an element:

n.unclick();

Hover

Add the hover event to an element:

n.hover(function(){
    console.log("You have hovered the elipse");
}, function(){
    console.log("You have left the elipse");
});

Remove the hover events from an element:

n.unhover();

Other stuff

See what type of object it is:

n.type
n.node

Grab SVG code as a string

s.innerSVG();
s.outerSVG();
s.toString();

Convert string to fragment and append it to the dom.

var title = Snap.parse('<title>This is a title 2</title>'); 
var rect = s.rect(20,20,40,40);
rect.append( title );

Convert a snap object to a data url, that can be used in html as an image.

var imagecontent = n.toDataURL();

Animate with javascript

Simple:

u.animate({x: 100},2000);

Define easying and callback:

u.animate({x: 100},2000, mina.bounce);
u.animate({x: 100},2000, mina.elastic);
u.animate({x: 100},2000, mina.linear, function(){
    console.log("Done");
});
u.animate({transform: "r45"},2000, mina.easeinout, function(){
    console.log("Done");
});

mina includes easying functions that you can use in your animations.

Animate a number:

var t = s.text(50,50,0);
Snap.animate(0, 100, function (value) {
    t.attr({text: Math.round(value)});
}, 1000);
Snap.animate(0, 180, function (value) {
    u.attr({ transform: "r" + value});
}, 2000);

Snap animate does not loop trough all the numbers like a classic javascript loop. It also doesn't block the UI, so you can perform many simultaneous animations.

Load SVG file or fragment

Load SVG as a separate file, once loaded insert it into the dom and perform operations.

<svg id="svg" width="800" height="800" version="1.1" viewbox="0 0 800 800" xmlns="http://www.w3.org/2000/svg"></svg>
var s = Snap("#svg");
var tux = Snap.load("tux.svg", function ( loadedFragment ) {
    s.append( loadedFragment );
} );

SVG and CSS animations

Don't forget to test your CSS animations, as not all proprieties will work in all browsers.

First the CSS animation:

@keyframes disappear {
  0% {
      opacity: 1;
      transform: translateX(0px);
    }
  33% {
      opacity: 0.6;
      transform: translateX(10px);
    }
  66% {
      opacity: 0.3;
      transform: translateX(20px);
    }
  100% {
      opacity: 0;
      transform: translateX(30px);
    }
}

.vanish {
    animation-name: disappear;
    animation-duration: 1s;
    animation-timing-function: linear;
    animation-delay: 0.5s;
    animation-iteration-count: 2;
    animation-fill-mode: forwards;
}

The svg:

<svg id="svg" width="800" height="800" version="1.1" viewbox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <g transform="translate(0,-97)" stroke="#872eca" stroke-width=".079">
        <ellipse id="test" cx="63" cy="1.7e2" rx="40" ry="41" fill="#0f0"/>
        <rect x="110" y="120" width="74" height="66" ry="0" fill="red"/>
    </g>
</svg>

And finally the javascript (snap):

var u = s.select("rect");
u.addClass("vanish");

If you add classes as a consequence of user behavior, you are creating interactive svgs.

Matrix

Matrix is a tool to calculate the transform parameters.

getBBox is a utility to get info about the object you want to apply the matrix.

myMatrix.scale(2,2, u.getBBox().cx, u.getBBox().cy);
myMatrix.rotate(45, u.getBBox().cx, u.getBBox().cy);
u.transform(myMatrix);

It can also be applied to paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment