Building SVGs in JavaScript with Pablo
Monday 04 July 2022 10:54 AM Beirut Time · 251
Wajdi Alkayal Wajdi Alkayal
Building SVGs in JavaScript with Pablo

The intersection of JavaScript and SVG is a good example of how web technologies can work together to create something greater than the sum of their individual specifications.

SVG works easily with JavaScript through the SVG DOM interface to enhance the interactivity of the web. But, the vanilla JavaScript workflow can be complex and cluttered. Fortunately, several libraries, like Pablo and gySVG, have been developed to help simplify the construction and manipulation of SVGs with JavaScript without compromising performance.

In this article, we’ll introduce Pablo and discuss how it can be used to create both simple and complex SVG shapes.

What is Pablo?

Pablo is a lightweight, open source library used for simplifying the construction and manipulation of SVGs in JavaScript. It is relatively full-featured and has a friendly, easy-to-explore API.

Pablo’s primary focus is simplicity and performance. This library enables developers to more easily work with dynamically generated vector graphics while avoiding the verbose workflow of vanilla JavaScript.

There are several libraries and frameworks available for drawing and manipulating SVGs. But Pablo offers a unique, simplified approach and a plugin system that allows for new functionalities to be added on the fly.

Comparing vanilla JavaScript to Pablo

The vanilla code for drawing even the simplest SVG shape tends to be several lines long. This lengthy code can quickly become hard to understand and maintain.

Pablo provides name methods, like .line() and .circle() for creating standard types of SVG elements. Pablo also provides methods for manipulating SVG and HTML elements to change their appearance, size, position, and more. These methods make the code comprehensive but very concise.

Here’s a comparison of vanilla JavaScript code and Pablo code. Both examples render a simple SVG circle:

// vanilla js
const ns = 'http://www.w3.org/2000/svg'

const div = document.getElementById('vector') 

const svg = document.createElementNS(ns, 'svg')

svg.setAttributeNS(null, 'width', '100%')

svg.setAttributeNS(null, 'height', '100%')

div.appendChild(svg)

const circle = document.createElementNS(ns, 'circle')

circle.setAttributeNS(null, 'width', 100)

circle.setAttributeNS(null, 'height', 100)

circle.setAttributeNS(null, 'fill', '#f06')

svg.appendChild(circle)

// Pablo
const svg = Pablo(HTMLElement).svg({height:100}),
    circles = svg.circle({cy:50, r:50});

As you can see, Pablo’s code is simpler than the vanilla JS.

Getting started with Pablo

Now that we have some insight into how concise Pablo can be, let’s take a look at how we can set it up in a project.

There are two methods for getting started with Pablo: downloading and adding the script to the HTML document or installing it with the Bower package manager.

Loading the Pablo script

When downloading Pablo’s script, you can choose to either download the full script or the minified script. The full script is for development — it is large and is not optimized. The minified script is for production. It is a compressed, optimized version of the full script.

Both the full and minified scripts are available for download directly from their respective script pages: pablo.js and pablo.min.js.

To add either of the scripts to your project, create a new file in your project folder:

  • pablo.js for full script
  • pablo.min.js for minified script

Then, copy and paste the code from the script page and save.

Loading a Pablo Script

Now, add the script file to the project’s HTML with pablo.min.js:

<script src="pablo.min.js""></script>

Or, add the script using a path to the downloaded folder passed in as a src attribute:

<script src="source/pablo.min.js"></script>

Installing Pablo with Bower

Bower is a package manager, like Yarn and npm, which manages frameworks, libraries, assets, and utilities and makes sure they are up to date.

Bower is a command-line utility. You will need to have the latest version of Node.js and Git installed on your machine. First, we use this command to install Bower:

$ npm install -g bower

Next, we install Pablo with this command:

$ bower install pablo

Understanding the Pablo building blocks

We previously examined the basic structure of a Pablo code block. Now, let’s take an in-depth look at the building blocks of the library and how they work.

The Pablo() object is the most significant method in Pablo. It contains several properties that can be used to create and append an SVG element to a pre-existing element in the DOM. It is also used to create an array-like structure (called a collection) of new and pre-existing HTML or SVG elements. We will discuss these in more detail in the following sections.

The Pablo() method returns an empty Pablo collection when logged to the console:

const collection = Pablo();
alert(collection.length); // 0

To load Pablo into the document, we have to append it to a pre-existing HTML element in the DOM. Suppose we have a div element with a class attribute of elem in the document:

<div class="elem"></div>

We can append our Pablo SVG to the div container in the document by passing the class or id into the Pablo() method as a parameter and then chaining an .svg() method to specify the width and height of the vector as a parameter:

const svg = Pablo(.mycontainer).svg({
    width: 200,
    height: 100
});

The code above creates an <svg></svg> HTML element in the DOM and then appends it to the div container we created earlier.

The output will look like this in the DOM:

<div class="mycontainer">
    <svg version="1.1" width="200" height="100"></svg>
</div>

Adding elements to a collection

A collection is an array-like object that encloses SVG and HTML elements when Pablo creates or selects any element in the DOM. Elements can be worked on directly, but the methods on the collection object are usually used to manipulate and filter elements in Pablo.

However, there are a few methods that are equivalent to those used in standard JS arrays, such as .push().pop().forEach().map(), and .filter(). These methods work just like they would in a standard array object. For example, elements can be added to a collection with the .push() method or removed with the .pop() method.

Appending elements to a collection is as easy as creating a new element, setting its attribute object, and then chaining it to the collection with either the .push().concat(), or .unshift() methods:

const collection = Pablo(['circle', 'path']);

collection.push(Pablo.rect({width: 200, height: 100}));

alert(collection.lenght) //3

In this example, we created a collection, passed in an array of element methods, and then added a new rectangle shape to the array with the .push() method. The .push() method appends new elements to the end of a collection. It is the equivalent of .add() in jQuery.

Check the Pablo documentation for a comprehensive list of methods you can use to manipulate a collection.

Creating SVG shapes with element methods

Now, let’s walk through how we can create basic SVG shapes with Pablo, and how we can append them to the created SVG element.

Element methods are used to create new SVG elements with the same name as the method. For example, the circle, rectangle, and line elements will be created with the .circle().rect(), and .line() methods, respectively. These elements are nested under the <svg></svg> element in the DOM, creating a nested structure similar to this example:

<svg>
    <line x1="5" y1="195" x2="295" y2="5" stroke="green" stroke-width="10"/>
</svg>

We can create these elements independently as a variable by calling them directly on a collection, — Pablo.ELEMENT_NAME() — and appending them to an element on the DOM.

Alternatively, we can simply chain them to the element:

/* Append an <svg> element to an HTML element */
const svg = Pablo(demoElement).svg({
    width: 220,
    height: 220
});

/* Create a <circle> element, wrapped in a collection */
const circle = Pablo.circle();

/* Create a <rectangle> element, wrapped in a collection */
const rect = Pablo.rect();

/* Append to svg element */
svg.append(circle, rect)

Creating SVG shapes with method chaining

Pablo is largely inspired by jQuery. It uses a jQuery-like pattern of chaining method calls to manipulate SVG and HTML elements. This technique makes it possible to run multiple, successive methods on the same element within a single statement.

To create a chain, simply append a method to the previous method:

/* Append an <svg> element to an HTML element */
const svg = Pablo(demoElement).svg({
    width: 220,
    height: 220
});

/* Append a <rect> element to the <svg> */
svg.rect({width:200, height:100}).transform('translate', 70).attr('fill', 'turquoise')

In this example, we chain the .rect().transform(), and .attr() methods to the SVG element. Pablo appends a rectangular shape with a width of 200px and a height of 100px, rotates the element with the CSS transform property, and then sets an attribute property to the shape element to change the color of the rectangle.

We can format the block of code by adding line breaks and indentations to avoid the rabbit hole of cluttered syntaxes:

/* Append an <svg> element to an HTML element */
const svg = Pablo(demoElement).svg({
    width: 220,
    height: 220
});

/* Append a <rect> element to the <svg> */
svg.rect({width:200, height:100})
   .transform('translate', 70)
   .attr('fill', 'turquoise')

In the above example, Pablo will ignore the whitespace and execute the block as one long line of code.

Related Posts
Graphic design
09 June
The Power of Email Marketing
03 June
Photography
01 June