SVGRX - Overview
SVGRX: convert SVG to a bunch of line segments
The library is used to convert SVG vector drawing to an array of line segments with absolute coordinates. Drawing these line segments, i.e. onto HTML canvas, should give you fairly accurate representation of the original SVG document, but without any styling, animations etc.
Here is an example of using the library to parse SVG document and then render line segments, created by the library, onto HTML canvas:
Library does not support animations or any other fancy SVG stuff.
Its sole purpose is to extract vector drawing information from a SVG document and present that in a form that is easy to process afterwards.
The main idea behind this library is to create vector drawings in tools like Inkscape, and then extract the paths in a form that can be easily converted into i.e. CNC machine gcode. In the process, all the more or less important information is preserved, i.e. all of the element attributes are preserved
Nevertheless, the library, and internal classes and functions, i.e. Point, Matrix, Bezier etc., could be useful for different projects.
Concept
SVG parsing is done by DOMParser and then the resulting DOM tree is traversed and only nodes and information relevant to the final conversion to an array of line segments are collected.
Phases of the entire process are:
- parsing SVG and converting it to a tree of SVGRX objects
- all attributes of SVG nodes are collected
- for each of SVG tags:
svg
,g
,rect
,circle
,ellipse
,line
,polyline
,polygon
andpath
an object of corresponding class is created
- transform matrix for each, if any, is parsed and stored
- each class parses its attributes and exposes them as properties
- every node converts itself into an array of Bezier curves of 2-nd (a line), 3-rd (quadratic) and 4-th (cubic) order
- conversion arrays of Bezier curves are then flattened into an array of line segments using various algorithms
- you then use the resulting array of line segments to do whatever work you intended with them
The main thing to do, once a svg file (or string) is loaded and parsed, is to call flatten
method:
svg.flatten( new SVGRX.Matrix() )
The method accepts a transformation matrix as parameter. You can leave it out unless you want to translate, rotate, scale, or do something similar with the entire vector drawing before it is converted into a bunch of lines.
Example that loads svg file from server and draws it onto a canvas:
//
// SVGRX CODE
//
SVGRX.ConvertFromUrl( 'test.svg' )
// loadedSvg is SVGRX.Svg object
.then(function( loadedSvg ){
// current transformation matrix
// by default it's unit matrix
let ctm = new SVGRX.Matrix()
ctm = ctm.translate( guiData.offsetX, guiData.offsetY ).rotate( guiData.rotationAngle )
// segments -> array of arrays, each of the arrays has SVGRX.Point as elements
let segments = loadedSvg.flatten( ctm )
drawSvgOnCanvas( segments )
})
//
// CODE TO DRAW STUFF ON HTML CANVAS
//
var drawSvgOnCanvas = function( segments )
{
var canvasWidth = 1200
var canvasHeight = 500
var canvas = document.getElementById(canvasName)
canvas.width = canvasWidth
canvas.height = canvasHeight
canvas.style.width = canvasWidth
canvas.style.height = canvasHeight
var ctx = canvas.getContext('2d')s
for( let idx = 0; idx < segments.length; idx++ )
{
// draw lines
ctx.lineWidth = 2
ctx.strokeStyle = '#74b71b'
ctx.beginPath()
ctx.moveTo( segments[0].x, segments[0].y )
for( let idx = 1; idx < segments.length; idx++)
{
ctx.lineTo( segments[idx].x, segments[idx].y )
}
ctx.stroke()
// draw line ends as points
SVGRXTools.drawPoints( ctxA, segments[ idx ], '#30363b' )
ctx.fillStyle = '#30363b'
var size = 2
for( let idx = 0; idx < points.length; idx++)
{
ctx.fillRect( points[idx].x - size, points[idx].y - size, size * 2, size * 2 )
}
}
}
You can do the same with SVG as a literal string:
// javascript template literal, use with pre-processors, i.e. babel
let svgAsString = `
<svg>
<g>
<path d="M 100,100 L 100,50 50,50 Z" />
</g>
</svg>
`
// loadedSvg is SVGRX.Svg object
let loadedSvg = SVGRX.ConvertFromString( svgAsString)
// current transformation matrix
// by default it's unit matrix
let ctm = new SVGRX.Matrix()
ctm = ctm.translate( guiData.offsetX, guiData.offsetY ).rotate( guiData.rotationAngle )
// segments -> array of arrays, each of the arrays has SVGRX.Point as elements
let segments = loadedSvg.flatten( ctm )
drawSvgOnCanvas( segments )
For more details, checkout the Git repo.