Vector Graphics in Sass

Originally published at:

Sass is a very powerful tool and many of us are still examining it’s limits. What can we do with it and how far can we push it?

After throwing ideas at Hugo Giraudel, I got myself very excited about one idea; a 2D graphics engine. This may be confusing, because CSS and thus Sass is already part of the realm of graphics. Instead of styling content, I wanted to (ab)use Sass to render an image, pixel by pixel. The output can be drawn as a box-shadow value on a 1×1 pixel element.

Examining strategies

One way is to iterate through a grid and a list of objects, and check if a pixel should be drawn. Sass would have to process n x width x height iterations, where n is the amount of objects. That is a lot of work so not very performant, especially considering loops in Sass aren’t fast. Instead of rendering the entire grid, it is possible to render only parts that may contain an object by getting a so called bounding box. Check out the demo.

A better option is to use paths.

Paths may sound familiar to you. It is a common term in graphics software like Adobe Illustrator and Adobe Photoshop, but the term occurs in web technologies like SVG and HTML5 too. A path is a list of coordinates that are connected in sequence. All I need to define a shape is a couple of coordinates. If you are familiar with paths, you probably know you can make curved paths as well. For now, I will stick to straight lines.

The process of converting a vector path to pixels – or in our case a vector path to a box-shadow – is called rasterizing.

Scanline algorithm

Paths are often rendered using the scanline algorithm. Personally, whenever I hear the word “algorithm” I panic and execute whatever exit strategy I have at hand. This algorithm however is surprisingly comprehensible, so don’t be scared just yet!

We iterate through the vertical pixels. For every row, we store the intersections of all lines of that path. After iterating through all lines, we sort and iterate through the intersections from left to right. At every intersection, we toggle drawing.

Scanline Algorithm

Sass implementation

Before rendering anything, it is useful to know what to render. We have to define a path. I think a list of coordinates is a pretty good set-up:

Continue reading this article on SitePoint

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.