Geeking-out on SVG Graphics part-one
Tags: graphics, svg, javascript, css
Published: 2022-05-01 11:16:37

---
title: Geeking-out on SVG Graphics part-one
published: true
description: Hand-coding SVG graphics for pleasure
series: Geeking-out on SVG Graphics
tags: graphics, svg, javascript, css 
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylsaw4y65ah24b2k9ov4.jpg
---

My interest in computers and computer programming was first sparked by the way it gave me a way to plot geometry. I could exercise formulae and visualise the results with greater accuracy than I could manage by hand.

In the early days computers were far less capable, screens were often monochrome and had a very low resolution. Presenting data in textual form was really the only option, graphics were usually too coarse and blocky to be usable.

Home computers of the 1980's brought greater resolution and more colourful displays, making graphics not only practicable but also for some of us a joy. Since then the capability and accessibility of computing resources has improved extensively. We have tools and libraries for creating outstanding 2-dimensional and 3D graphics. Examples, to name just a few, include:

* [GIMP](https://www.gimp.org/)
* [InkScape](https://inkscape.org/)
* [DIA](http://dia-installer.de/)
* [Diagrams.net](https://app.diagrams.net/)
* [Blender](https://www.blender.org/)
* [Vectr](https://vectr.com/)
* [D3](https://d3js.org/)
* [Three JS](https://threejs.org/)

##Get back to primitives
When I first started working with graphics there was little in the way of standardisation such as OpenGL. The best I had access to were simple memory access functions directly into the screen memory such as `peek` and `poke`. Peek read the content of a memory location and poke wrote a value into a memory location, to in effect detect or change the colour of a pixel on the screen respectively.

One of my first assignments as a professional software developer was to create a simple graphics library to be used as a teaching aid. The library expanded on the peek and poke operations to draw lines, shapes, perform fill operations and much more. All of which were far more complicated than you might think given the limitations of the equipment at the time. Consider the complexities of translating vector graphics into raster memory locations and you might have an idea.

###My Project
I have a project in mind that will use a technology that is equivalent to the library I created. It is not at the peek/poke level but still quite primitive. That said it forms the basis of many graphics libraries especially on the web. The technology is SVG (Scalable Vector Graphics) which is far more than an image format.

##SVG introduction
SVG is more a graphics language than an image format especially when compared to raster formats like JPG and PNG. For large detailed images raster formats are more efficient but have limited scalability. SVG (and other vector formats) can be more compact, scalable and adaptable, which is well suited for applications like infographics and user interactive graphics. Just take a look at the possibilities demonstrated at the [D3 Gallery](https://observablehq.com/@d3/gallery).

Most image formats encode data as some form of bitmap where the colour of every pixel is recorded, although this can be compression to reduce the overall file size. However, the bigger the image resolution and colour depth, the larger the file. Also, resizing the image either by re-encoding it or by confining /stretching the display area will eventually distort the image.

SVG does not suffer these issues because it encodes data as a set of instructions defined using XML, which is similar to HTML but HTML is far less compliant to XML. Consequently, the size of the file is affected by the size of the rendered image but it is by the number of elements/shapes contained in the image. This is why they are not suited for detailed images with lots of shape and colour variation.

SVG files can also reference CSS and JavaScript files so think of it like an alternative the HTML. In fact HTML can contain SVG and SVG can contain HTML, with a little manipulation. 

###An example SVG v JPG/PNG
For example, we will encode the following image in two ways: 400px x 300px with a blue background (Hex #0000FF) with a red 100px radius circle (Hex #FF0000) in the centre of it. The rounded corners of the image below is as a result of the Dev.to styling.

![Example image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hppj1kxvrr0cb41fs0i6.png)

In JPG format the file size would be 16.7KB. The PNG equivalent would be reduced to 639 bytes. However, as an (unoptimized) SVG the file size would be just 208 bytes.

```html
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <rect x="0" y="0" width="400" height="300" fill="#0000FF"></rect>
  <circle cx="200" cy="150" r="100" fill="#FF0000"></circle>
</svg>
```

But the real 'trick' is what happens if we increase the size to 800px x 600px. This can be done with JPG and PNG files by stretching them but the circle will become grainy. If the images are resized (redrawn) the file sizes will be increased. The JPG is almost double at 32.3KB, the PNG is more than five times the size at 3.17KB. However, the size of the SVG files is unchanged and only eight characters need to be changed from the original to present a larger image, with no distortion of the circle. In fact, if the original SVG image were stretched to 800px wide (but 600px tall) there be no noticeable difference.

##The Project - cutting mat backdrop
Following my long-held fascination with geometry, before commencing this project, I was considering capturing an image of a cutting mat off the web and using it as a backdrop (wallpaper) for my PC desktop. _Very geeky I accept_.

An example being:

![Cutting mat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhs8j515wply5r6945mk.png)

But the problem was there are loads of variation in the mats and the details they show. Also, rather than presenting information more useful for handicrafts I wanted to show information more appropriate for me as a software developer, so I decided to develop my own and the project was formed.

_"Show what do I want to show?"_
1. A grid of cells just like a conventional cutting mat.
2. Common screen resolutions for 4:3 and 16:9 ratios. See below for more details.
3. Again taken from the conventional mat, I would like to show a selection of regular angles (15&deg;, 30&deg;, 45&deg;, 60&deg; and 75&deg;) and their Sine equivalents (0.26, 0.50, 0.71, 0.87 and 0.97).
4. A selection of "Aesthetic ratios" and formulae; Golden ratio, Silver ratio, Pythagorean Hypotenuse, plus one of my own "Vitruvian Coefficient" - See table below.
5. An example of the Egyptian (3:4:5) Triangle and the angles within the right-angle and side lengths of the triangle.
6. An explanation of my "Vitruvian Coefficient", which is the ratio linking a square and circle of the same area.

> "This might take some time so there will be several posts - stay tuned."

|Screen Resolutions | Width | Height | Ratio |
|--------------|-------|--------|-------|
|VGA/SD 480p | 640 | 480 | 4:3 |
|SVGA | 800 | 600 | 4:3 |
|HD 720p | 1280 | 720 | 16:9 |
|XGA | 1024 | 768 | 4:3 |
|UXGA | 1600 | 1200 | 4:3 |
|Full HD 1080p | 1920 | 1080 | 16:9 |
|UHD 2K/QHD 1440p | 2560 | 1440 | 16:9 |
|UHD 4K | 3840 | 2160 | 16:9 |

I want to show the above information, on top of the grid, as a set of rectangles using the actual resolutions. The rectangles will be anchored at the origin of the image, which is the top-left corner. 

The aspect ratios of the resolutions are 4:3 or 16:9, which means a grid with an aspect ratio of 16:10 would enable aspect-ratio lines projected from the origin would pass through the sides of the grid rather than the bottom-right corner.

I also need a grid a little larger than the largest screen resolution (3840px x 2160px). After a few calculations I decided on a grid of 4000px x 2500px with each grid cell being 250px square.

|Aesthetic ratio | Ratio | Formulae |
|----------------|-------|----------|
|Golden Ratio (aka Fibonacci) | 1.618 | (1 + sqrt(5))/2 |
|Silver Ratio | 2.414 | (1 + sqrt(2)) |
|Pythagorean Hypotenuse | 1.414 | sqrt(2) |
|Vitruvian Coefficient | 1.128 | 2/sqrt(pi) |

###Colour scheme
As stated earlier, we can use CSS to style SVG elements in the same way as we style HTML elements but with some different properties.

Actual cutting boards come is a wide variety of colours with the most common being a dark green, as shown above. However, I have chosen a dark blue (#191662) based on "Machinist's Blue Layout Fluid" used by mechanical engineers. See this clip from Adam Savage's [YouTube video](https://youtube.com/clip/UgkxvIY-VvVNbl7lkNqY7qI5EsdNl6GefFF5) for an explanation.

The grid will comprise of horizontal and vertical lines enclosed in a rectangle of different line thicknesses and styles but all using the same grey colour #777, which we will also use for my 'by line' text in the bottom right-hand corner.

We will cover the colours of additional features just prior to their implementation. If you have any questions or comments on this project please add a message in the discussion section below. To answer an immediate question: Why not use one of the products listed above? Because that would not be as much fun or offer the learning exercise I was aiming for.

In the [next post](https://dev.to/tracygjg/geeking-out-on-svg-graphics-part-two-4aih) I will be creating the SVG file, the grid and by-line.

##Resources
* [W3C on Scalable Vector Graphics](https://www.w3.org/Graphics/SVG/)
* [MDN on Scalable Vector Graphics](https://developer.mozilla.org/en-US/docs/Web/SVG)
* [Jakob Jenkov](https://jenkov.com/tutorials/svg/index.html)