In my previous couple of posts, I explored some methods for coding some imperfection into the drawing of basic geometric shapes, where the imperfection was created through the use of a fractal subdivision process. First I drew circles, then rectangles. These imperfect curves have proven to be a rich source for some experiments in generative art, and below I share several variations on a common theme.
Click on each screencap to see randomized images generated in real time. Each page has a button at the bottom to allow for exporting the image that is created: the image will be opened up in a new window, and you can then right click on the image and select “save as…” to save the image in PNG format.
After checking out the live demos, scroll down to the bottom of the page for the full source code for all of these applications, and also to read my notes about how the images are created.
The complete code for all of the above examples can be downloaded here: MorphingCurve.zip
About the code
The canvas applications linked above all use the same basic code. What varies are the line colors and fill colors, along with some parameters that control the evolution of the sweeping shape over time.
Part of the creation of these images involves a classic generative art technique: change a shape slowly, and draw it again repeatedly as it evolves without erasing the previous images. The stacked images create an evolving and flowing structure.
To create the morphing shape, a randomly generated closed curve is created using a fractal subdivision process, as outlined in my previous post here. This curve slowly morphs into another randomly generated closed curve, by linearly interpolating between the radius values for the initial curve and the destination curve. Once the curve completely morphs into the destination curve, we reset the destination curve and the shape then begins to morph from its current configuration into the next destination curve.
As the shape morphs, we gradually move its center across the canvas, creating the traced-out structures you see above.
To better understand the morphing shape which sweeps across the canvas, click on the image below to see a single shape morph repeatedly from one curve to another. This will explain it much better than words can:
Now all you have to do is imagine this shape sweeping across the canvas, stacking on top of older unerased images.
The final images look three-dimensional, but this is just a by-product of the stacking and sweeping of the drawings. To give more of a 3D hint, I squeeze the curves somewhat in the x direction so that the shapes appear to be foreshortened by perspective, but apart from this there is no real 3D projection occurring.
The different effects are created by either using a fill inside the shape or no fill, plus some changes in the coloring which is done either with solid colors or gradients. Note that because gradients must be defined by global coordinates, the easiest way to make the gradient move across the canvas along with the shape is to define the gradient once, then use a canvas transformation to position the curve as it is drawn. Have a look into the source code to see the gradient and transformations in action.
After a particularly nice image is generated in the canvas, you might wish to save it. The image can be saved by transfering the canvas into a displayed image, which can then be saved by the user after right-clicking. After some experimentation and disappointing browser inconsistencies, and collecting bits of code from various places around the internet, I put together a solution that seems to work in every modern browser.
First the code makes a copy of the displayed canvas onto an off-screen canvas. This is done to add some elements which are not part of the displayed canvas: a solid background color as well as a little rectangleworld.com URL in the top right corner (I made sure the URL would appear in a spot that could be easily edited out in case you don’t want it there!).
Then we use the
toDataURL() method to create a data URL from the canvas which represents the canvas image exported to PNG format:
var dataURL = exportCanvas.toDataURL("image/png");
We open a new browser window:
var imageWindow = window.open("", "fractalLineImage", "left=0,top=0,width="+displayWidth+", height="+displayHeight+", toolbar=0,resizable=0");
Then we write some html into the new window, creating an empty image:
imageWindow.document.write("<title>Export Image</title>") imageWindow.document.write("<img id='exportImage'" + " alt=''" + " height='" + displayHeight + "'" + " width='" + displayWidth + "'" + " style='position:absolute;left:0;top:0'/>"); imageWindow.document.close();
Finally we copy the data URL created above into the empty <img> in the newly opened window, by setting the source of the image:
var exportImage = imageWindow.document.getElementById("exportImage"); exportImage.src = dataURL;
Creating large images
This is HTML and the images are meant for monitor display rather than high quality printing. But I have been able to increase the size of the canvas to produce some nice large images for large monitors. For example, click on the preview image below to see a 1920 X 1080 image I generated from a modified version of the same basic code as above:
There is certainly a limit to the size of a canvas and the image created through the
toDataURL() method, but I don’t happen to know what the limits are. (I experimented with very large images, and browsers weren’t able to handle them when they got too large). Interestingly, the large image above could not be right-click saved from Chrome, but Chrome allowed me to copy the image to the clipboard, which could then be pasted into an image editing program.