Creative coding with Figma — part. 2: Mandelbrot.

Loïc TORRES
5 min readOct 28, 2021

--

Part 2: Mandelbrot

Last time, we saw how to create a hundred of concentric circles in a blink, and how to play with various parameters like the stroke width or color to add variety. This time, we’re gonna level up: we will use trigonometry with the power of Scripter to create incredible shapes. Let’s go!

This article is a part of a series called “Creative coding with Figma”. We strongly recommend you to read the series from the beginning as some part of code is reused from one article to another. You can find the previous article here and the introduction here.

Concept

First of all, we gonna need to picture how to create such a form. I started from youtube videos about mathematical art, and this one explain how to draw it step by step. Our job here is to convert the draw steps into functions.

In a nutshell, the first step is to divide a circle in a certain number of points equally distributed, let’s say 20.

Then, from the first point, we draw a line to the second. From the second to the fourth, the third to the sixth and so on and so forth, each time by applying a factor 2.

When we start a line from the 11th point, we can’t reach the 22nd as we only have 20 points. The solution is to take the modulo of the number of the inexistent point, by the total number of points: 22%20 = 2. So we draw a line from the 11th to the 2nd point. And so on and so forth.

After a few lines, we got our shape!

Divide a circle into point

Let’s create a new script. To get started, we’re gonna need to draw a circle with equally distributed points. To do that, we’re gonna fill an array of coordinates corresponding to each points and iterate over it to draw some ellipsis.

To compute x, I used the dedicated formula: rayon*cos(angle). The angle is obtained by dividing (360°/amount of desired points)*iteration count, converted in radians (degree*PI/180).

Same for y, but with sine in place of cosine.

Here’s the result:

We got 20 points equally distributed, job’s done.

Draw the lines

Some headaches incoming here: the main problem is that Figma can’t draw a line from a point to another (at the moment I wrote those lines).

But don’t worry, there’s another method to draw lines. Yeah, we just need a starting point, a length and an angle. We already got the starting points freshly baked in an array, we just have to figure out how to compute the other two.

Length

To compute a length between two coordinates, we use this formula:

d = √[(X₂ − X₁)²+ (Y₂ − Y₁)²]

In Javascript:

Math.sqrt(((to.x - from.x)*(to.x - from.x))+((to.y - from.y)*(to.y - from.y)))

for example, if we need to compute the length of the line between the first and the second point, we would take the first point coordinates as from.x-.y and the second point as to.x-.y

Translated into Javascript, we got:

The method to compute the index of the destination point (the to constant) is a simple translation of the initial state. We multiply the origin by 2, and if it’s superior to the total number of points, we just take the rest. In math, it’s called modulo and it’s represent by % sign.

if we run the function, we got horizontal lines, with different lengths, it’s not really glamorous yet, and we need to give them a little twist.

The angle

In order to compute the angle of each line, we gonna use the infamous SohCahToa formulas: Sine equals opposite over hypotenuse; cosine equals adjacent over hypotenuse; tangent equals opposite over adjacent (a mnemonic for the ratios in trigonometry).

To use those formulas, we need to use a right triangle. If we draw some lines, we realize that we can found right triangles for each line like so:

With this disposition, we can compute the line’s angle like the following:

So let’s add the rotation parameter to our line object, with the correct formula as value. At this point, we got this in Scripter:

If you run the function now, you can see the beginning of the shape. To complete our function, there’s one thing we need to do: as there are negative angles and our acos function return positive values only, we have to compute a “negative factor”. When do we need to turn our value negative? When the destination is below the origin. In other terms, when y₁ > y₂. To do that, we have to add the following line:

const isNegative = from.y < to.y ? -1 : 1

and multiply the rotation parameter by this result. Here’s my result :

Now that we have a nice skeleton, we just have to create some parameters to draw a nice result. We can add the number of points as a parameter, as well as the factor we use to define the destination point. It has been 2 until now, but we can go for any number.

At this point, if you’re lost or if you just want the final code, it’s here. Just copy/paste into Scripter and run it.

In this example, I use 150 point with a factor 2. If we play with those parameters, we can get a various number of shapes with a different definition.

I hope you enjoyed your reading. Don’t forget you can play with more parameters, use polygons instead of lines, add colour… Possibilities are infinite!

Stay tuned ❤️

--

--

Loïc TORRES

Tech enthusiast, climber and hiker. Senior Software Engineer & Product Owner @ www.eklair.re