Skip to main content

Code Generate an SVG File (Scalable Vector Graphics, Mac)

In this article, I will show you how to code generate an SVG (Scalable Vector Graphics) file. The example will use Brownian motion to simulate the random path of a particle in a fluid using NodeJS.

Code Generate an SVG File (Scalable Vector Graphics, Mac)

In this article, I will show you how to code generate an SVG (Scalable Vector Graphics) file. The example will use Brownian motion to simulate the random path of a particle in a fluid using NodeJS.  

These instructions were written on a Mac.

Step 1. Define what to generate

For this article, I will show you how to generate a path for a particle using Brownian motion.

First, a path string will be code-generated that looks something like this (trimmed for brevity):

"M517 283 561 291 579 269 ..."

Then it will be embedded into an SVG path tag like this:

<path fill="none" stroke="#000000" stroke-width="2" d="M517 283 561 291 579 269 ..." />

Think of the path string (d) as instructions for an x/y plotter.  An M, followed by two numbers is the "Move To" command.  It usually implies that the plotter should first lift up the pen (pen up) and then move to the new x/y location.  

If the next two tokens in the string are numbers, that implies a "Line To" command. That command would tell the plotter to put the pen down, then draw a line to the new x/y location.  

So using the example above, the instructions would be:

Move To 517, 283
Line To 561, 291
Line To 579, 269

But instead of drawing a line with a plotter, the line is drawn on the screen.

Brownian Motion

To simulate Brownian motion an initial point on the screen will be set with a Move To command.  Then every subsequent Line To would be calculated based on the previous coordinate, applying a random angle and distance to travel to.

Step 2. Set up your project

To set up your project, open up a terminal window and do the following:

mkdir brownian-svg
cd brownian-svg
npm init -y
echo .DS_Store >> .gitignore
touch LICENSE
touch README.md
touch index.js

Step 3. Paste the code into the editor

  • Open index.js in your favorite code editor
  • Paste in this code and save it:
/**
* Author: Mitch Allen (https://mitchallen.com)
* https://scriptable.com/
*/

var fs = require('fs');

function generate(limit) {

let width = 1024
let height = 512
let margin = 10
let maxMove = width * 0.10
let x = width / 2
let y = height / 2
let precision = 0
let path = "M"
let backgroundColor = "gray"

// generate the path

for (let i = 0; i < limit; i++) {
let distance = Math.random() * maxMove
let angle = Math.random() * 360
let tx = x + distance * Math.sin(Math.PI / 180 * angle);
let ty = y + distance * Math.cos(Math.PI / 180 * angle);
if (
tx > margin && tx < (width - margin) &&
ty > margin && ty < (height - margin)
) {
x = +tx.toFixed(precision)
y = +ty.toFixed(precision)
path += `${x} ${y} `
}
}

// generate the svg markup

let xmlns = "http://www.w3.org/2000/svg"

let fd = `<svg viewBox="0 0 ${width} ${height}" xmlns="${xmlns}" width="${width}" height="${height}">\n`;
fd += `<rect fill="${backgroundColor}" width="${width}" height="${height}" />\n`
fd += `<path fill="none" stroke="#000000" stroke-width="2" d="${path}" />\n`
fd += '</svg>';

// write the file

var filename = 'brownian.svg';
var stream = fs.createWriteStream(filename);
stream.write(fd);
stream.end();
console.log(`Generated file: ${filename}` )
}

generate(2000)

The code does the following:

Defines a function

  • Declares a generate function that takes one argument (limit)

Declares variables within the function

  • Declares width and height for the SVG file
  • Declares a margin for the drawing to stay within
  • Declares maxMove - the maximum distance the simulated particle should move along its path with each step
  • Declares the initial x and y coordinates
  • Declares the decimal precision for rounding the x and y values
  • Declares the initial path string to be: "M" - which means "move to" - where to start the path
  • Declares a background color for the image

Generates the path

  • Using the limit argument passed to the function, creates a loop to run up to the limit
  • Calculates a random distance value up to maxMove - to simulate particle movement along a path
  • Calculates a random angle to simulate the particle direction
  • Uses the distance and angle to calculate a new target coordinate (tx and ty) for the particle path to move to
  • If tx and ty are within the margins of the drawing area, the code assigns the values to x and y, applies the decimal precision, and appends them to the path

Generates the SVG markup

  • Declares a variable (fd) to hold the SVG markup
  • Inits fd with the opening svg tag, using the width and height values to define the viewBox and the size of the image
  • Appends to fd a rect tag set to the size of the image to use as a background – otherwise the SVG file background will be transparent - not necessarily a bad thing
  • Appends to the fd a path tag, using the path string for the d (data) property
  • Then finally appends to fd the closing svg tag

Writes the file

  • Defines the filename
  • Creates a write stream (stream) using the filename
  • Writes the generated markup (fd) to the stream (file)
  • Ends the stream
  • Echos to the console the name of the newly generated file

Calls the function

  • Calls the generate function passing in a limit value as an argument

Step 4. Generate an SVG file

  • To generate the SVG file, do the following:
node index.js
  • Verify that the new file was generated:
ls -ls *.svg

Step 5. View the file

Most drawing programs and browsers can open a *.svg file.

  • Open the *.svg file in a drawing program or browser
open brownian.svg

If that doesn't work, try opening the file in a browser.

Note that some drawing programs don't watch for changes to a file.  So if you generate a new file, you may need to close it and reopen it again to see the changes.

Conclusion

In this article, you learned how to code generate an SVG file.

Below is a link to an example.  There is also a link to an alternative way of creating an SVG that uses one of my free open-source drawing packages.

Example

You can find an example based on this article here:

Using my drawing kit

In this article, I showed you how to code generate an SVG file without using any special packages. But I also have a few drawing packages that you could have used.

For an alternative way of creating Brownian motion using my drawing kit, see this demo repo:

References

  • What is Brownian Motion (YouTube) - [1]
  • Path - SVG - [2]