Drawing Multiple Sprites Of A Water Tank

Recently, I was pointed to a beautiful historical game for teaching simulation. It's a pipeline puzzle that also offers a way to evaluate the pressure in the pipeline depending on how the pipeline is connected.
Originally built in Smalltalk, it was recently ported to JavaScript . It works, but it stil had an issue: the tank icon always showed it was empty. That's because there were no sprites showing it filled in different stages.
We decided to remedy the situation using Glamorous Toolkit .
The challenge is to take this picture and draw multiple sprites with the tank with water inside. We start by loading the picture.
array := ZnClient new
	url: 'http://plumbin.ward.wiki.org/assets/pages/plumbin-in-wiki/tiles/tank.png'; get.
form := array readStreamDo: [:s | Form fromBinaryStream: s].
The first thing we need to do is to figure out where we should draw the blue square. So, we create a little tool based on BlDevCrossover to help us investigate. This is a decorator that can be added to any element and shows the position of the mouse within the bounds of the element:
element := form asElement.
BlDevCrossover on: element.
element asScalableElement
Once we know the coordinates, we an now try it. Ah, but how do we draw on a form? We first need a canvas. We know that the canvas can be instantiated by querying Bloc preferableSpartaCanvas. To learn how we draw on it, we can just search in the environment:
Ok, so we can use fill. Let's try it quickly:
canvas := Bloc preferableSpartaCanvas extent: 40@40.
form asElement drawMeWithEffectsOnCanvas: canvas.
canvas fill
	paint: Color blue;
	path: (7@6 corner: 33@32);
	draw.
canvas
Looks good. Now we can produce multiple canvases:
canvases := (6 to: 32) collect: [ :y |
	canvas := Bloc preferableSpartaCanvas extent: 40 @ 40.
	form asElement drawMeWithEffectsOnCanvas: canvas.
	canvas fill
		paint: Color blue;
		path: (7 @ y corner: 33 @ 32);
		draw.
	canvas ]
And now we can export them as PNGs:
canvases doWithIndex: [ :each :i | 
	PNGReadWriter
		putForm: each asForm
		onFileNamed: 'tank' , i asString , '.png' ].
'.' asFileReference
That's it. We started from a problem and we worked our way through it in the same uniform environment. Along the way, we constructed a custom tool to answer a question. We searched for similar examples. We prototyped and explored the results. All integrated.
This article is based on a Twitter thread I wrote recently.