Introduction
This project is part of my study at Pratt Institute. In Professor Matthew Miller‘s course Programing for User Interface, for the first time I tried to make some functioning applictions with JavaScript.
Get Ready
My intention was to make a light-weight interface that help artists and designers create central symmetrical geomatric patterns with one repeating polygon, and users should have the full control of this pattern, and it should be able to export as an SVG file, which can be further edited in softwares like Adobe Illustrator or Coral Draw.
JavaScript is a great tool to create interactive projects. However, before I start coding, I need to figure out the facts behind the scene and find the right tools to complete it. I splited this project into three main chunks: draw SVG (Drawing), add parameter controls (Controling), and Export the SVG (Downloading).
Drawing
In order to define a pattern as I planned, we first need to define the polygon with the following parameters:
- amount of the polygon’s sides (corners/points)
- the size of the polygon is (its radius)
- the angle that the polygon tilts
Then I will need to define how this polygon create the pattern with two more parameters:
- the amount of the repeating polygons
- the distance that these polygons are from the center of symmetry
Lastly I want to give this pattern a color set.
- The web color code
Controling
The parameters should be able to be manipulated by users, and it should be able to work both instinctively and accurately. Therefore it should have two features:
- Integer value input (an input box)
- Range input (a slide bar)
Downloading
Users might want to download the pattern they have generated, which requires a download function that allows them to export a reusable SVG file:
- get the SVG codes
- download the codes as an SVG file
JavaScript Libraries Used
In order to achieve the listed requests, two JavaScript librarys has been used.
Svg.js provides a variety of classes that help people draw, manipulate and animate SVG, while I used Vue.js to create the input functions.
Some Details
Draw a Polygon with SVG.js
The fundamental task of this project is to draw a polygon in SVG. SVG.js defines the polygon element as “a closed shape consisting of a set of connected straight line segments”. Therefore, it is necessary to find out the coordinates of each vertices of the polygon.
I found these two formulas on StackOverflow, provided by Oliver Charlesworth.
x[n] = r * cos(2*pi*n/N)
y[n] = r * sin(2*pi*n/N)
which computes x(n) and y (n) coordinates of an N-sided polygon of radius r, centred at (0,0).
According to this formula, I used
px = this.shapeSize / 2 * Math.cos(2*Math.PI * j / this.polygonSideNumber)
py = this.shapeSize / 2 * Math.sin(2*Math.PI * j / this.polygonSideNumber)
to caculate the value of (px, py) and use .push method to add it to the svg.draw function. Similarly,
let shapeX = this.drawRadius * Math.cos(2*Math.PI * i / this.shapeNumber) + this.cx – this.shapeSize / 2
let shapeY = this.drawRadius * Math.sin(2*Math.PI * i / this.shapeNumber) + this.cy – this.shapeSize / 2
computes the polygon center of each polygon, and with SVG.js’s .move and .rotate function the polygon can be modified with different position and angle.
CSS mixBlendMode
In order to create a variety of patterns I wanted to make the shapes semi-transparent and create different shades of colors, pretty much like the “multiply blend mode” in Photoshop. So I found that CSS has a property mix-blend-mode that can achieve this effect. However, I can only change the nesting
instead of the SVG if I directly add this property to my CSS file, so I had to use JavaScript to give the SVG this value.
const mixBlendMode = ‘screen‘
shape.style(‘mix-blend-mode‘, mixBlendMode)
Vue.js X-template and Event Handling
Vue.js is a progressive framework that focuses on ‘the view layer only’, which is much easier for me to understand. I used its x-template property to define a template:
It was much easier to add event listeners and handlers here with the “v-on:”/”@” as an attribute to a
@change=”flush” type=”range” min=”3″ max=”360″ value=”50″ v-model=”polygonSideNumber”
Download SVG with svg_blob
A blob, according to HTML5 API, represents “a file-like object of immutable, raw data.” Thanks to DaveTheScientist‘s contribution, which shows how to create an object’s url and append it to an element for users to download.
var svg_blob = new Blob([svg], {‘type’: “image/svg+xml”});var url = URL.createObjectURL(svg_blob);var downloadLink = document.createElement(“a”);downloadLink.href = url;
Downloaded SVG samples
This application works properly and can really generate a pattern that you can download and reuse in other softwares. Here are some sample SVG files that opened in Adobe Illustrator.
The exported SVG file could actually be opened, analyzed, and modified with Adobe Illustrator.
Project Review
As my first serious JavaScript user interface developing project, I’m pretty satisfy with my outcome. However, there are still some flaws that I would like to figure out in the future.
First and foremost, for some reason, this program is only working properly with polygons with even number of sides. With triangle or pentagon, for example, it will tilt to one side. I think its because my way of cauculate the center point (cx, cy) wasn’t really right.
Secondly, it would be nice if it can generate patterns with polygon borders, which could really use a toggle on/off function. But in the interest of simplicity, I didn’t include the this function.
Third, the webpage is not yet mobile friendly (though I doubt someone would need this function on cellphones), but it could be potentially useful on tablets, working with Adobe’s mobile applications.
What’s more, SVG.js has a great property of animating the SVG. I have tried the rotate method, but I met some problem of controling the parameters so I had to give it up.
Lastly, the range input setting for the amount of polygon sides ain’t really user friendly. I set the max number to 360 was because that was the number turns polygons to circles in Logo (a programing language that I have learned in elementry school), and I really want this application can deal with circles.