SVG.js

Attributes

attr() as setter

returns itself
animate yes (only for numbers, arrays, colors, ...)

Set a single attribute:

rect.attr('x', 50)

Set multiple attributes at once:

rect.attr({
  fill: '#f06'
, 'fill-opacity': 0.5
, stroke: '#000'
, 'stroke-width': 10
})

Set an attribute with a namespace:

rect.attr('x', 50, 'http://www.w3.org/2000/svg')

Explicitly remove an attribute:

rect.attr('fill', null)

attr() as getter

returns value (string, number, ...)

You can get and set an element's attributes directly using attr().

Get a single attribute:

var x = rect.attr('x')

Get all attributes as an object:

var attributes = rect.attr()

Get only specified attributes:

var attributes = rect.attr(['x', 'y'])


Positioning

While positioning an element by directly setting its attributes works only if the attributes are used natively by that type of element, the positioning methods described below are much more convenient as they work for all element types.

For example, the following code works because each element is positioned by setting native attributes:

rect.attr({ x: 20, y: 60 })
circle.attr({ cx: 50, cy: 40 })

The rect will be moved by its upper left corner to the new coordinates, and the circle will be moved by its centre. However, trying to move a circle by its 'corner' or a rect by its centre in this way will fail. The following lines will get silently ignored as the attributes that are addressed are not natively used by the element setting them:

rect.attr({ cx: 20, cy: 60 })
circle.attr({ x: 50, y: 40 })

However, the positioning methods detailed below will work for all element types, regardless of whether the attributes being addressed are native to the type. So, unlike the lines above, these lines work just fine:

rect.cx(20).cy(60)
circle.x(50).y(40)

It is important to note, though, that these methods are only intended for use with user (unitless) coordinates. If for example, an element has its size set via percentages or other units, the positioning methods that address its native attributes will most likely still work, but the ones that address non-native attributes will give unexpected results -- as both getters and setters!

move()

returns itself
animate yes

Move the element by its upper left corner to a given x and y position:

rect.move(200, 350)

x() as setter

returns itself
animate yes

Move the element by its upper left corner along the x-axis only:

rect.x(200)

x() as getter

returns value

Without an argument the x() method serves as a getter:

var x = rect.x()

y() as setter

returns itself
animate yes

Move the element by its upper left corner along the y-axis only:

rect.y(350)

y() as getter

returns value

Without an argument the y() method serves as a getter:

var y = rect.y()

center()

returns itself
animate yes

Move the element by its center to a given cx and cy position:

rect.center(150, 150)

cx() as setter

returns itself
animate yes

Move the element by its centre in the x direction only:

rect.cx(200)

cx() as getter

returns value

Without an argument the cx() method serves as a getter:

var cx = rect.cx()

cy() as setter

returns itself
animate yes

Move the element by its centre in the y direction only:

rect.cy(350)

cy() as getter

returns value

Without an argument the cy() method serves as a getter as well:

var cy = rect.cy()

dmove()

returns itself
animate yes

Shift the element in both the x and y directions relative to its current position:

rect.dmove(10, 30)

Note: when using dmove() (and dx() or dy() too for that matter), always make sure you provide values of the same unit the element is originally positioned in. So if the element is at x:10%, use element.dx('5%') and not element.dx('5px').

dx()

returns itself
animate yes

Shift the element in the x direction relative to its current position:

rect.dx(200)

dy()

returns itself
animate yes

Shift the element in the y direction relative to its current position:

rect.dy(200)


Resizing

size()

returns itself
animate yes

Set the size of an element to a given width and height:

rect.size(200, 300)

Proportional resizing is also possible by leaving out height:

rect.size(200)

Or by passing null as the value for width:

rect.size(null, 200)

As with positioning, the size of an element could be set by using attr(). But because every type of element is handles its size differently the size() method is much more convenient.

width() as setter

returns itself
animate yes

Set the width of an element:

rect.width(200)

width() as getter

returns value

var width = rect.width()

height() as setter

returns itself
animate yes

Set the height of an element:

rect.height(325)

height() as getter

returns value

rect.height()

radius()

returns itself
animate yes

Circles, ellipses, and rects may use the radius() method. On rects, it defines rounded corners.

For a circle, the argument sets the r attribute.

circle.radius(10)

For ellipses and rects, pass two arguments to set the rx and ry attributes individually. Or, pass a single argument, to make the two attributes equal.

ellipse.radius(10, 20)
rect.radius(5)


Syntactic sugar

fill()

returns itself

The fill() method is a pretty alternative to the attr() method:

rect.fill({ color: '#f06', opacity: 0.6 })

A single hex string will work as well:

rect.fill('#f06')

Last but not least, you can also use an image as fill, simply by passing an image url:

rect.fill('images/shade.jpg')

Or if you want more control over the image, you can pass an image instance as well:

rect.fill(draw.image('images/shade.jpg', function() {
  this.size(20, 20)
}))

stroke()

returns itself

The stroke() method is similar to fill():

rect.stroke({ color: '#f06', opacity: 0.6, width: 5 })

Like fill, a single hex string will work as well:

rect.stroke('#f06')

Not unlike the fill() method, you can also use an image as stroke, simply by passing an image url:

rect.stroke('images/shade.jpg')

Or if you want more control over the size of the image, you can pass an image instance as well:

rect.stroke(draw.image('images/shade.jpg', 20, 20))

opacity()

returns itself

To set the overall opacity of an element:

rect.opacity(0.5)


Transforming

transform() as setter

returns itself
animate yes

Transformations are applied absolutely by using an affine approach:

element.transform({
  rotate: 125,
  translateX: 50,
  translateY: 100,
  scale: 3 
})

To make the syntax as easy as possible, it is possible to pass in parameters in different ways:

  • translation: translate: {x: 50, y: 50}, translate: [50, 50], translateX: 50, translateY: 50, tx: 50, ty: 50
  • rotate: rotate: 50
  • scale: scale: 2, scale: [2,2], scaleX: 2, scaleY: 2
  • shear/skew: skew: [10, 10], skewX: 10, skewY: 10, shear: 3
  • flip: both, true, x, y
  • origin: origin: {x: 50, y: 50}, origin: [50, 50], origin: 50, originX: 50, originY: 50, ox: 50, oy: 50
    • origin can also be a up to 2 words speciying the corners of the element: center, top, bottom, left, right
  • position: position: {x: 50, y: 50}, position: [50, 50], positionX: 50, positionY: 50, px: 50, py: 50
    • absolute position of the origin after all transformations are applied
  • relative: relative: {x: 50, y: 50}, relative: [50, 50], relativeX: 50, relativeY: 50, rx: 50, ry: 50
    • relative position of the origin after all transformations are applied
element.transform({
  translate: [10, 20],
  origin: 'top left',
  flip: 'both'
})

You can also pass in a matrix or an object with a-f parameters to apply it directly:

element.transform({
  a: 1, b: 0, c: 1, d: 0, e: 10, f: 20
})

To apply a relative transformation, you can pass a second argument:

Alternatively a relative flag can be passed as the second argument:

element.transform({ rotate: 125 }).transform({ rotate: 37.5 }, true)

It is also possible to apply a transformation relative to another element or even a matrix. You can do that by passing in the element or matrix instead of the relative flag:

element.transform({ rotation: 125 }, someElement)
element.transform({ rotation: 125 }, someMatrix)

transform() as getter

returns value

The transform() method acts as a full getter without an argument:

element.transform()

The returned object contains the following values:

  • translateX (translation on the x-axis)
  • translateY (translation on the y-axis)
  • skewX (calculated skew on x-axis)
  • skewY (calculated skew on y-axis)
  • shear (calculated sher on x-axix)
  • scaleX (calculated scale on x-axis)
  • scaleY (calculated scale on y-axis)
  • rotate (calculated rotation)
  • originX (0 for this usecase)
  • originY (0 for this usecase)
    -a-f (matrix data)

Additionally a string value for the required property can be passed:

element.transform('rotate')

flip()

returns itself
animate yes

Flips element over a given axis:

element.flip('x')

or

element.flip('y')

By default, elements are flipped over their centre point. The flip origin can be defined with the second argument:

element.flip('x', {x: 20, y: 30})

Finally, an element can also be flipped over two axes at once by not providing an axis value, 'both' or true:

element.flip()
element.flip('both')
element.flip(true)

rotate()

returns itself
animate yes

The rotate() method will automatically rotate elements according to the center of the element:

// rotate(degrees)
element.rotate(45)

Although you can also define a specific rotation point:

// rotate(degrees, cx, cy)
element.rotate(45, 50, 50)

skew()

returns itself
animate yes

The skew() method will take an x and y value:

// skew(x, y)
element.skew(0, 45)

scale()

returns itself
animate yes

The scale() method will scale elements by multiplying their x and y
coordinates by either a single scale factor or two separate scale factors:

// scale(factor)
element.scale(2)
// scale(xFactor, yFactor)
element.scale(0.5, -1)

By default, scaling is relative to the center of the element.
You can also define a specific center point (vanishing point of scaling):

// scale(factor, centerX, centerY)
element.scale(2, 0, 0)
// scale(xFactor, yFactor, centerX, centerY)
element.scale(0.5, -1, 0, 0)

translate()

returns itself
animate yes

The translate() method will take an x and y value:

// translate(x, y)
element.translate(0.5, -1)


Styles

css() as setter

returns itself

With the css() method the style attribute can be managed like attributes with attr:

element.css('cursor', 'pointer')

Multiple styles can be set at once using an object:

element.css({ cursor: 'pointer', fill: '#f03' })

Explicitly deleting individual style definitions works the same as with the attr() method:

element.css('cursor', null)

css() as getter

returns value (string, number, ...)

Similar to attr() the css() method can also act as a getter:

element.css('cursor')
// => pointer

Or even a full getter:

element.css()
// => {cursor:pointer;fill:#f03;}

You can also get only specific styles by using an array:

element.css(['cursor', 'fill'])
// => {cursor:pointer;fill:#f03;}

hide()

returns itself

Hide element:

element.hide()

show()

returns itself

Show (unhide) element:

element.show()

visible()

returns boolean

To check if the element is visible:

element.visible()


Class Names

addClass()

returns itself

Adds a given css class:

element.addClass('pink-flower')

classes()

returns array

Fetches the CSS classes for the node as an array:

element.classes()

hasClass()

returns boolean

Test the presence of a given css class:

element.hasClass('purple-rain')

removeClass()

returns itself

Removes a given css class:

element.removeClass('pink-flower')

toggleClass()

returns itself

Toggles a given css class:

element.toggleClass('pink-flower')


Data

The data() method allows you to bind arbitrary objects, strings and numbers to SVG elements.

data() as getter

returns value

Fetching the values is similar to the attr() method:

var key = rect.data('key')

data() as setter

returns itself

rect.data('key', { value: { data: 0.3 }})

Or set multiple values at once:

rect.data({
  forbidden: 'fruit'
, multiple: {
    values: 'in'
  , an: 'object'
  }
})

Removing the data altogether:

rect.data('key', null)

Your values will always be stored as JSON and in some cases this might not be desirable. If you want to store the value as-is, just pass true as the third argument:

rect.data('key', 'value', true)


Memory

remember() as getter

returns value

To retrieve a memory

rect.remember('oldBBox')

remember() as setter

returns itself

Storing data in-memory is very much like setting attributes:

rect.remember('oldBBox', rect.bbox())

Multiple values can also be remembered at once:

rect.remember({
  oldFill:    rect.attr('fill')
, oldStroke:  rect.attr('stroke')
})

forget()

returns itself

Erasing a single memory:

rect.forget('oldBBox')

Or erasing multiple memories at once:

rect.forget('oldFill', 'oldStroke')

And finally, just erasing the whole memory:

rect.forget()


Document Tree

add()

returns itself

Sets the calling element as the parent node of the argument. Returns the parent:

var rect = draw.rect(100, 100)
var group = draw.group()

group.add(rect) //-> returns group

addTo()

returns itself

Sets the calling element as a child node of the argument. Returns the child:

rect.addTo(group) //-> returns rect

clone()

returns SVG.Element

To make an exact copy of an element the clone() method comes in handy:

var clone = rect.clone()

This will create a new, unlinked copy. For making a linked clone, see the use element.
To insert the clone, use the addTo() or add().

put()

returns SVG.Element

Sets the calling element as the parent node of the argument. Returns the child:

group.put(rect) //-> returns rect

putIn()

returns SVG.Element

Sets the calling element as a child node of the argument. Returns the parent:

rect.putIn(group) //-> returns group

remove()

returns itself

Removes the calling element from the svg document:

rect.remove()

replace()

returns SVG.Element

At the calling element's position in the svg document, replace the calling element with the element passed to the method.

rect.replace(draw.circle(100))

toRoot()

returns itself

Same as toParent() but with the root-node as parent

toParent()

returns itself

Moves an element to a different parent (similar to addTo), but without changing its visual representation. All transformations are merged and applied to the element.

rect.toParent(group) // looks the same as before

ungroup()

returns itself

Breaks up a groupd and puts all of its elements into the parent of the group without changing their visual representation. That means, any transformation applied to the group is now applied to its individual elements.

group.rect(100, 200)
group.circle(4)
group.transform({rotate: 20}).ungroup()
// group is deleted, rect and circle both have rotate: 20

You can also specify to which container the elements of the group are moved:

group.ungroup(otherContainer)

flatten()

returns itself

Recursively breaks up all containers and flattens the whole structure so that no container element survives. This is useful for exporting to reduce the number of nested groups or similar.

Ungroup all elements in this group recursively and places them into the given container

group.flatten(container)
// (default: parent container of the calling element)

Call it on the whole document to get a flat svg structure:

drawing.flatten()

Break up the group and places all elements in the drawing:

group.flatten(drawing)

Flat and export svg:

var svgString = drawing.flatten().svg()


Arranging

You can arrange elements within their parent SVG document using the following methods.

after()

returns itself

Insert an element after another:

// inserts circle after rect
rect.after(circle)

before()

returns itself

Insert an element before another:

// inserts circle before rect
rect.before(circle)

insertAfter()

returns itself

Insert the current element behind the passed element

rect.insertAfter(circle)

insertBefore()

returns itself

Insert the current element before the passed element

rect.insertBefore(circle)

back()

returns itself

Move element to the back:

rect.back()

backward()

returns itself

Move element one step backward:

rect.backward()

front()

returns itself

Move element to the front:

rect.front()

forward()

returns itself

Move element one step forward:

rect.forward()

next()

returns SVG.Element

Get the next sibling:

rect.next()

position()

returns number

Get the position (a number) of rect between its siblings:

rect.position()

previous()

returns SVG.Element

Get the previous sibling:

rect.previous()

siblings()

returns array

To get all siblings of rect, including rect itself:

rect.siblings()


Geometry

point()

returns SVG.Point

Transforms a point from screen coordinates to the elements coordinate system.

// e is some mouseevent
var point = path.point(e.pageX, e.pageY) // {x, y}

inside()

returns boolean

To check if a given point is inside the bounding box of an element you can use the inside() method:

var rect = draw.rect(100, 100).move(50, 50)

rect.inside(25, 30) //-> returns false
rect.inside(60, 70) //-> returns true

Note: the x and y positions are tested against the relative position of the element. Any offset on the parent element is not taken into account.

bbox()

returns SVG.Box

Gives the bounding box of an element which is the untransformed tightest box around the element.

element.bbox()

rbox()

returns SVG.Box

Returns the transformed box of an element which is the transformed tightest box around the element. To specify to which coordinate system the box is transformed, relatively it is possible to pass in an element:

element.rbox(drawing)
// transformed box in coordinates of drawing

This method is a convenient wrapper around getBoundingClientRect().

viewbox()

viewbox() as setter

Sets the viewbox of an element (only available on elements which support viewbox)

drawing.viewbox(10, 10, 500, 600)
// or
drawing.viewbox('10 10 500 600')
// or
drawing.viewbox(box)

viewbox() as getter

returns SVG.Box

drawing.viewbox()
Fork me on GitHub