A Typescript SVG Manager library
Provides classes used to manage interactive SVG's in the HTML DOM, minimize definitions and make controlling the SVG elements from JS/TS as easy and reliable as possible.
Look at the Docs for detailed information
Install the package using npm:
npm install ts-svgmanager
SVGManager creates a resourceful and compact way to handle interactive SVG containers. SVGManager provides a easy way to deal with events and mentions of nodes within a SVG container, so that you can come back and adjust them.
Here we are going to draw a simple circle to the DOM using the manager. There are a some predeclared shapes, which can we very easily drawn using the standard functions. Here we are gonna use the standard circle.
In the HTML we define a container, which we can mention later within the typescript/javascript.
<body>
<!-- ... Rest of DOM ... -->
<div id="svg-root"></div>
<!-- ... Rest of DOM ... -->
</body>
In the typescript/javascript files, we can then initiate a manager and render a circle within that.
import { SVGManager } from 'ts-svgmanager'
import { circle } from 'ts-svgmanager/Shapes'
// Initialize the SVGManager to the container
const manager = new SVGManager().init('svg-root')
// Render a circle with a radius of 25 at (50, 50)
manager.render(circle(25, 50, 50))
This will look like:
Now we going to draw a bit more difficult of a shape a pentagon.
import { SVGManager } from 'ts-svgmanager'
import { polygon } from 'ts-svgmanager/Shapes'
// Again we initialize the SVGManager
const manager = new SVGManager().init('svg-root')
// Then we render a pentagon
manager.render(
polygon([
{ x: 20, y: 10 },
{ x: 80, y: 10 },
{ x: 95, y: 60 },
{ x: 50, y: 95 },
{ x: 5, y: 60 },
]),
)
This will look like:
If we want to add a gradient a background we use the Gradient
Helper. This will turn the code into this:
import { SVGManager } from 'ts-svgmanager'
import { polygon } from 'ts-svgmanager/Shapes'
import { SVGLinGradient, SVGStops } from 'ts-svgmanager/helpers'
// Again we initialize the SVGManager
const manager = new SVGManager().init('svg-root')
// Define a gradient into the manager using the Gradient Helper
const blueGradient = manager.define(
new SVGLinGradient(
new SVGStops()
.stop(0, 'rgb(72, 60, 102)')
.stop(1, 'rgb(136, 169, 197)'),
)
.spreadMethod('pad')
.x1(0)
.y1(0)
.x2(0.87)
.y2(1.11),
)
// Render a pentagon with a custom fill
manager.render(
polygon([
{ x: 20, y: 10 },
{ x: 80, y: 10 },
{ x: 95, y: 60 },
{ x: 50, y: 95 },
{ x: 5, y: 60 },
]),
.fillDef(blueGradient),
)
This will look like:
Now we are gonna add animations to a shape. The Animate
Helper will help a lot with this. We are gonna use the ellipse shape here.
import { SVGManager } from 'ts-svgmanager'
import { SVGLinGradient, SVGStops, SVGAnimate } from 'ts-svgmanager/helpers'
import { ellipse } from 'ts-svgmanager/Shapes'
// Initialize the SVGManager
const manager = new SVGManager().init('svg-root')
// We add a gradient for some color
const orangeGradient = manager.define(
new SVGLinGradient(
new SVGStops()
.stop(0, 'rgb(255, 156, 96)')
.stop(1, 'rgb(245, 125, 125)'),
)
.spreadMethod('pad')
.x1(0)
.y1(0)
.x2(1.28)
.y2(0.47),
)
// Render a ellipse at (50,50) and add the gradient and the animations
manager.render(
ellipse(20, 40, 50, 50)
.fillDef(orangeGradient)
.animate(new SVGAnimate(2000, 'rx', [20, 40, 20]).repeatIndefinitely())
.animate(new SVGAnimate(2000, 'ry', [40, 20, 40]).repeatIndefinitely()),
)
This will look like:
Now we are going to show how you could load a svg element from a file. We are going to do this using the Parser
Helper.
import { SVGManager, SVGNode } from 'ts-svgmanager'
import { fetchSVGNode } from 'ts-svgmanager/helpers'
import { rect } from 'ts-svgmanager/Shapes'
// Initialize the SVGManager
const manager = new SVGManager()
manager.init('svg-root')
// Fetch the SVG node from the file
fetchSVGNode('./gradient.svg').then((node: SVGNode) => {
const blueGradient = manager.define(node)
// Render a rect with the blue gradient
manager.render(rect(10, 10, 80, 80).fillDef(blueGradient))
})
<linearGradient
spreadMethod="pad"
id="gradient"
x1="0%"
y1="0%"
x2="87%"
y2="111%"
>
<stop offset="0%" style="stop-color:rgb(72, 60, 102);stop-opacity:1;" />
<stop offset="100%" style="stop-color:rgb(136, 169, 197);stop-opacity:1;" />
</linearGradient>
This will look like:
Now we are going to add some events to this rectangle. We are going to create a mouseover event.
import { SVGManager } from 'ts-svgmanager'
import { SVGLinGradient, SVGStops } from 'ts-svgmanager/helpers'
import { rect } from 'ts-svgmanager/Shapes'
// Initialize the SVGManager
const manager = new SVGManager()
manager.init('svg-root')
const blueGradient = manager.define(
new SVGLinGradient(
new SVGStops()
.stop(0, 'rgb(72, 60, 102)')
.stop(1, 'rgb(136, 169, 197)'),
)
.spreadMethod('pad')
.x1(0)
.y1(0)
.x2(0.87)
.y2(1.11),
)
const orangeGradient = manager.define(
new SVGLinGradient(
new SVGStops()
.stop(0, 'rgb(255, 156, 96)')
.stop(1, 'rgb(245, 125, 125)'),
)
.spreadMethod('pad')
.x1(0)
.y1(0)
.x2(1.28)
.y2(0.47),
)
manager.render(
rect(10, 10, 80, 80)
.fillDef(blueGradient)
.on('mouseenter', (_e, node) => node.fillDef(orangeGradient))
.on('mouseleave', (_e, node) => node.fillDef(blueGradient)),
)
import { SVGManager, SVGNode } from 'ts-svgmanager'
import { PathData } from 'ts-svgmanager/helpers'
// Initialize a circle with args
const pill = new SVGNode('path')
.set(
'd',
new PathData()
.moveTo(10, 40)
.lineTo(10, 60)
.curveTo(30, 60, 10, 70, 30, 70)
.lineTo(30, 40)
.curveTo(10, 40, 30, 30, 10, 30)
.closePath(),
)
.stroke('#000', '1px')
.fill('none')
// Initialize the SVGManager
const manager = new SVGManager()
manager.init('svg-root')
// Render this
manager.render(pill)
This will look like:
We are gonna create a custom cursor for our SVG.
Here is how we do it:
import { SVGManager } from 'ts-svgmanager'
import ViewBox from 'ts-svgmanager/helpers/ViewBox'
import { circle } from 'ts-svgmanager/Shapes'
// Initializing the SVGManager with a viewBox of '-30 -30 60 60'
const manager = new SVGManager()
.init('svg-root')
.viewBox(new ViewBox(0, 0, 200, 200))
.width(200)
.height(200)
.set('cursor', 'none')
// Rendering a circle with a radius of 5 at (0,0)
manager.render(circle(5).tag('custom-cursor').cx(-20).cy(-20))
// Adding the onmousemove listener
manager.on('mousemove', (ev: MouseEvent, svgNode) => {
// Get the position of the SVG element
const svgX = svgNode.element.getBoundingClientRect().x,
svgY = svgNode.element.getBoundingClientRect().y
// Get the x and y of the mouse relative to the SVG
const x = ev.clientX - svgX,
y = ev.clientY - svgY
// Move the cursor to this location
manager.tagged('custom-cursor').forEach((cursor) => cursor.cx(x).cy(y))
})