I have recently been investing a lot of time and effort into web development, and one of my recent challenges was to do animated recursion.
This story started when I wrote an essay on infinite regress, where I explained how we can use recursive algorithms to general very interesting fractal patterns. To illustrate this point, I had written a Python program to generate a fractal curve known as the cross-stitch curve (the one from the title image).
Since I had already done the legwork, I thought I should make this code/model available to the readers so that they may play with it and experience how recursive algorithms work in the process.
So, if I have the algorithm already, how hard would it be to come up with a working web software application based on it? “This should be straightforward”, I thought to myself.
I could not have been more wrong. It was much more challenging than I thought it would be. I am writing this essay to describe these challenges, and also outline the technical solutions I came up with to solve them. If this sort of thing interests you, please read along.
Before we begin, it makes sense to set the context with my background in web development. I am very much still in the process of learning the ropes as far as web development is concerned.
Having said that, I have been able to complete pretty advanced projects in a very short duration of time. This has to do with the fact that I relish problem-solving adventures.
My blog is based on WordPress. So, I had already invested a lot of time and effort into learning custom WordPress development, as well as PHP and JavaScript coding. With this head start in my pocket, one would think that doing animated recursion should be a piece of cake.
But it is not. To pull such a project off, one needs to know the ropes of “animation”. This was my very first time working with animations. So, naturally, right off the bat, I made a terrible mistake.
Animated Recursion Using p5.js
In my Python code, I used a library known as Turtle. This is an advanced graphics library that makes the job very simple. For the web version of my code, I chose p5.js, a well-known open-source graphics library for web development.
I had read a lot about how beginner-friendly this library was. All of this made it a no-brainer. So, I started straight away by implementing my Python code as-is onto this library. My first challenge was to simply animate “anything”.
As it turns out, the p5.js library simply computes geometries based on inputs and renders them directly. In other words, pre-computation just displays static outputs. So, I had to come up with a simple time-based rendering algorithm that animated drawing geometries.
After struggling for a few hours to figure out how coordinate systems are computed in this library with respect to the canvas size, I managed to animate drawing a single line. As soon as the animation was complete, I had to switch it with a completed render (a trick no user would notice). This felt like a great achievement.
However, no matter what I tried, I failed miserably at animating anything more than one line. After spending many more hours, I figured out that I had made a terrible mistake; something that rocked the foundations of my approach.
Animations are Asynchronous and Recursion is Synchronous
You see, p5.js renders 60 frames per second (by default). This means that the code (including my animation algorithm) gets called 60 times a second. This is an implementation of what we would call as asynchronous code in the web development world.
In other words, an asynchronous line of code does not wait for its previous line to complete. It gets triggered as soon as the call stack makes it possible for it to be executed. This by itself is not an issue at all.
However, my animation algorithm was no ordinary algorithm; it was a recursive one. In a recursive algorithm, each line of code needs to execute ONLY AFTER the previous line of code is complete.
In other words, recursion and animation do not go hand-in-hand at all. So, how in the world would it be possible to animate recursion then?
Web Development Using Game Development
As hard as I could think, I could not see how I could solve this problem. So, instead of breaking my head over this problem, I went in search of someone else who had faced a similar problem.
Lo and behold, this problem is a standard one in the video game development industry. I found my solution as well there. The trick is to take advantage of the fact that my recursion algorithm does not run infinitely.
It is finite recursion, with a pre-defined base case. If you need more insights into how this works, check out my essay on how recursion works.
What this allowed me to do was to completely pre-compute my entire recursive algorithm beforehand, and save each of the animation states as “objects”.
Cross-stitch curve after iteration 3 and 4 — Geometry illustrated by the author
I could then call these objects asynchronously (as soon as each object became available) in my p5.js animation algorithm. So, in essence, I developed two separate algorithms:
1. One to pre-compute my recursive algorithm, and
2. One to animate my pre-computed states.
With all this complete, you would think that my job was done. But there was more work to do.
The Final Touches for Animated Recursion
If I were the only user of this web software, my job would have been done. But I had to ensure that my web software worked reliably on a range of devices such as mobile phones, tablets, laptops, and monitors.
I had to compute the canvas size based on screen size and compute the geometry sizes based on those numbers. For added user-friendliness, I added the following features:
1. Faster animation speeds at higher iterations.
2. Thinner pen-strokes at higher iterations.
3. A “black” leading line, simulating the turtle (from Python).
The finished product looked like this:
Cross Stitch Curve Web Software — Final Implementation
If you are interested in playing with this model yourself, you can access it here. I am by no means an expert on this topic, but I hope that you could take a thing or two home from my experience.
I am currently working on more interesting recursive web software applications. If that sort of thing interests you, keep an eye on this space.
If you are interested in the hassle-free Python version of the recursion algorithm, you can get it here.
If you’d like to get notified when interesting content gets published here, consider subscribing.
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept”, you consent to the use of ALL the cookies.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
Cookie
Duration
Description
cookielawinfo-checkbox-advertisement
1 year
Set by the GDPR Cookie Consent plugin, this cookie is used to record the user consent for the cookies in the "Advertisement" category .
cookielawinfo-checkbox-analytics
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional
11 months
The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
CookieLawInfoConsent
1 year
Records the default button state of the corresponding category & the status of CCPA. It works only in coordination with the primary cookie.
viewed_cookie_policy
11 months
The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Cookie
Duration
Description
_gat
1 minute
This cookie is installed by Google Universal Analytics to restrain request rate and thus limit the collection of data on high traffic sites.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Cookie
Duration
Description
__gads
1 year 24 days
The __gads cookie, set by Google, is stored under DoubleClick domain and tracks the number of times users see an advert, measures the success of the campaign and calculates its revenue. This cookie can only be read from the domain they are set on and will not track any data while browsing through other sites.
_ga
2 years
The _ga cookie, installed by Google Analytics, calculates visitor, session and campaign data and also keeps track of site usage for the site's analytics report. The cookie stores information anonymously and assigns a randomly generated number to recognize unique visitors.
_ga_R5WSNS3HKS
2 years
This cookie is installed by Google Analytics.
_gat_gtag_UA_131795354_1
1 minute
Set by Google to distinguish users.
_gid
1 day
Installed by Google Analytics, _gid cookie stores information on how visitors use a website, while also creating an analytics report of the website's performance. Some of the data that are collected include the number of visitors, their source, and the pages they visit anonymously.
CONSENT
2 years
YouTube sets this cookie via embedded youtube-videos and registers anonymous statistical data.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
Cookie
Duration
Description
IDE
1 year 24 days
Google DoubleClick IDE cookies are used to store information about how the user uses the website to present them with relevant ads and according to the user profile.
test_cookie
15 minutes
The test_cookie is set by doubleclick.net and is used to determine if the user's browser supports cookies.
VISITOR_INFO1_LIVE
5 months 27 days
A cookie set by YouTube to measure bandwidth that determines whether the user gets the new or old player interface.
YSC
session
YSC cookie is set by Youtube and is used to track the views of embedded videos on Youtube pages.
yt-remote-connected-devices
never
YouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
yt-remote-device-id
never
YouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
Comments