Sketch #2: Spinning webs

| 3 min read

I spent a good part of last's weekend trying to build spider webs with code because a spider installed on my yard 🤷🏻‍♂️. Isn't life beautiful?.

Setting the developing environment up

I read this amazing post by George Francis and wanted to try his approach on developing straight to SVG. I usually used work with an abstracting library like p5.js but always wanted to learn the SVG API itself so using svg.js proved to be a great in between.

I created an index.html with a bunch of styles and a script tag, spun up (no pun intended) a live-server and I had a sandbox ready to go in a couple of minutes.

By far the most minimal and comfortable environment I have worked in quite some time, completely gets out of the way and lets the creative juices flow.

Process

This is the overall process I followed to build this over the span of 2 days. Sorry for the quality of the process and commits, it didn't occur to me of documenting the process until the end, so it is not very detailed. Something to improve for the next sketch.

1. Straight lines web

I started by drawing two main axes (vertical and horizontal) plus two diagonals. Subdividing each axis in equal parts by doing a simple division and connecting their points I got a web spun up by a spider with a ruler. I tried my best to curve those lines but after a couple of hours that ended in defeat I just admitted that I had no idea how to do it and didn't even know how SVG paths work at all 😅.

2. Curving lines!

Fortunately my amazing searching skills and resourcefulness often compensate my lack of math! I found this post in Stack Overflow explaining exactly what I needed, with diagrams and everything! Thanks, Alexandr_TT! And not only I got it to work, but I also understood the concept behind it. Double win. This felt GREAT. This led me to this beautifully curved spider web:

3. Making things dynamic

I then tried making the connections that had been hard coded dynamic, so that I could control the number of anchors per axis. With my initial configuration I didn't work too well since I was iterating the anchor points from start to finish on each axis, this meant no easy way to easily correlate anchors between axes, resulting in this mess once the midpoint was surpassed:

I decided to change my axes and build them as lines radiating from the center, which not surprisingly is actually how spiders seem to do it. With this finished I could have the same as before but control the number of connections! So increasing them a bit, I got this sexy thing:

Things start to look promising.

5. Adding randomness

With a semi decent hard coded spider web working it was time for the fun stuff. I went through the different parameters of the web and started adding some variety to them thanks to some radom() magic. I ended up parametrizing:

  • Radii angle
  • Some anchors between radii might be missing. (Observed this happens in real life webs when some break due to insects, wind etc.)
  • Number of anchor points is irregular. I wonder if spiders use a fixed number 🤔 So number concentric circles vary from web to web
  • Some radii extend outside the canvas, to support the spider web to the environment

I had to be cautious with the ranges of the random parameters, otherwise I started getting very unnatural results like this:

But tweaking stuff around I started getting pretty natural results, so I call this experiment a success!

And that's it! Hope you enjoyed and learned something.

🎨 Try it yourself here!
🐙 Code can be found here

Learned

  • How webs are built by spiders
  • How to start a FAST and comfortable generative playing sandbox
  • A bunch of the SVG API. Specially how paths work
  • How to obtain the midpoint between two points
  • How to create a new point offset a specific amount in the bisecting angle between two points

Things I could have pushed further

  • Document as I was building it
  • Displace anchor points a bit up / down to add variety to the web.
  • Try to animate the step by step drawing of the web. Maybe using requestAnimationFrame?

Resources I found useful

Vilva.