Web Experiment: Mathnimatics

Some time ago I did one of my first web experiments in HTML5 using the Canvas element, it was a simple “solve this equation for every pixel of an image” to create mathematical images easily from an equation written by the user, I wasn’t sure how long it will take to evaluate the equation for every pixel (due to being executed in the Javascript VM) but it turned out to be so fast that I could execute it in realtime (using a low resolution canvas I could get 60 fps).

Today I recovered that code and made some optimizations on the way the render loop was handled, I think now it is between two and four times faster. It is a good time to talk about it in this blog.

Mathnimatics

Click on the image to try it

If you want to know how it is done read the rest of the post.

I feel proud of this experiment for being the first one I made trying to create a web app (or web toy as I like to call them), but also because some people even clicked the link of Flattr I put next to it (which gave me I think 10 euros in revenue!). You can check the old version here.

How to use it

You write an equation in the textarea below the canvas, the result of that equation should be a number between the range 0-1, then it gets mapped to the intensity of the pixel (0 is black, 1 is white). To make every pixel different you have different variables that you can use, like X and Y (normalized coordinates of that pixel, between 0 and 1), and to animate you can use the variable T (time in seconds since it started).

So its free to you imagination to create complex formulas to display strange images.

I added support to color if instead of returning a value an array of three values is returned.

You can also control the resolution of the canvas (to reduce the amount of pixels and speed up the computation).

Coding

It wasn’t really hard to code thanks to the eval function in Javacript, it allows you to evaluate code on the fly from a string. What I did was to pack the user code inside a string wrapped with the code to create a function so instead of evaluating it for every pixel I just evalute it once, something like this:

eval( "function _foo(X,Y) { return " + user_code + ";}" );

Now I have the function parsed and ready to be executed, so I call it as many times as pixels has the image, passing as an argument to the function the X and Y of every pixel and storing the results in an array. But because the canvas has too many pixels to run it on real time, I created a temporary canvas with a smaller size and use it to render the pixels, then draw that temporary canvas on to the screen canvas using the drawImage which allows to pass another Canvas as input.

The cool thing about using a temporary canvas is that when the temporary canvas is painted on to the screen, you can stretch it and a linear interpolation of the pixels is made, so it looks neat even when executing it with an small resolution.

This isnt something new, there are lots of people who had done the same before, some of them using directly the GPU Shaders (thanks to WebGL) so it runs hundreds of times faster letting them have incredible results (like this amazing raytracer+scene all written in a single shader!). But that doesnt work in all the browsers due to the WebGL limitations, and shaders tend to be hard to code by non-expert users.

Optimizing it

The improvement I made for this version was to put the for loop inside the function instead of calling it NxM times, and also precompute all the vars I can and hardcode them inside the code when parsing the function.

I also try to do not create objects so the Garbage Collector don’t mess up with the execution flow, so I pass the same buffer containing the pixels from the canvas to the function and modify them directly there, instead of using a copy as I did before.

Share it

Feel free to play with this experiment and share your own creations here (I recommend to check the examples before to see all the possibilities and read the Help to discover some useful vars).

If you have an interesting equation paste it here in the comments and I will upload it to the demos section (giving you full credit).

2 Responses to “Web Experiment: Mathnimatics”

  1. Pasquale Elguezabal Says:

    THANK YOU SO MUCH I love this tutorial

  2. tamapolis : Javi Agenjo's personal blog » Blog Archive » Web Experiment: Simple Coding Says:

    […] code your image or animation similar to what I did in previous web experiments like hotcoding or mathnimatics.You code and you press control+enter to execute. There are lots of webs where you can code on the […]

Leave a Reply


1 + = two