This post is from the talented maxwellito, if you're interested in posting, you can open up a proposal, just like he did!
This triangular meshing effect is often shown off in libraries with SVG. Today we’re going to build it with canvas! It’s a great example of how a coordinate system and a little displacement can give clean beautiful effects.
As usual we begin with a little setup code, a square canvas. We will also set the size of the canvas and adjust it based on the user’s device pixel ratio, or pixel density. This ensures that the final result is crisp on all monitors.


Now let’s make a grid of dots. The standard way, regular lines and columns. For every dot coordinate we will draw it on the canvas, but also store the coordinate in an array for future use.
Every coordinate will be represented by an object with 2 properties: x
and y
.
The space between lines and columns is defined by the variable gap
, we’ll draw these circles so we can see how our grid is placed out on the canvas.


Now, we’re going to displace every other line on the x axis. We do this by alternating the variable called odd
between true and false.
We can see that the new pattern is shaping up to be a mesh of regular triangles.


The next step will be using the dots to draw the triangles.
To make our life easier let’s make a function that take the 3 coordinates of a triangle and draw them together.


Now we’ll string up our drawTriangle
function, and use the dots we generated earlier to draw all the triangles.
This part might be a bit complex to understand. The script is going to go through all the lines and combining the two dots of the sibling line, forming triangles. The concatenation of two lines, let’s say line a
and line b
, and merge the dots into one array to make it look like a zigzag: a1
, b1
, a2
, b2
, a3
etc.
This will give us an array, containing each triangles specific coordinates. Looking something like [a1
, b1
, a2
], [b1
, a2
, b2
], [a2
, b2
, a3
]…


Now that we have a regular triangle mesh, we are one detail away from getting the magic to happen.
Every dot is a gap
away from the surrounding dots. So a dot can be moved in this area without overlapping with other dots. Let’s use a bit of Math.random()
to get a random position in this area.


And for a little extra generative fun, let’s add in some grays! Only 16 shades. No more.


If you’re interested in exploring more detailed implementations of this effect, you can check out my library: triangulr