Conveniences when Coding on the Canvas

Including a few you will not find anywhere else!

Welcome readers from ◎ Your Guide to Coding Creativity on the Canvas

Conveniences — Yawn? Well… when you are cruising with code, these are the things that make you feel like rolling down the window and blasting your favorite tune!

We will use the ZIM JavasScript Canvas Framework. For other canvas options, please see ◎ Your Guide to Selecting a JavaScript Canvas Library or Framework.

Characters ©Hanna Barbara — go Velma!

Take a look at this Button!

You can code along with us if you want. We will use the Kids’ Editor then copy or type this code and press TEST.

new Button().sca(2).center();
Image for post
Image for post
Button on the Canvas in ZIM

To change how the button looks we can set the button parameters in the round brackets () as we make the button. For info on parameters see ◎ Your Guide to Coding Concepts with the Colorful Canvas. Type and test:

new Button(100,100,"GO",pink,green)
Image for post
Image for post
Button with width, height, label, background and roll color parameters

So far so good but what if we wanted a corner of 0. Parameters go in order. The corner parameter is the 11th parameter. It comes after the text color and the border settings. Here are the parameters as listed in the ZIM Docs.

Image for post
Image for post
ZIM Button Parameters from ZIM Docs

Going back to the default button with a corner of 0, our once-simple Button does not look very simple anymore. We have to put a placeholder null (or undefined) for every unspecified parameter. Type this, if you dare!

new Button(null,null,null,null,null,null,null,null,null,null,0)

This is unmanageable. A solution would be to make the button and then afterwards set a corner property to 0 to change the button. But that is a two step process.

In ZIM DUO (version 2) we solved this problem!

We made it so you can use traditional parameters in order OR you can pass a single parameter that is a Configuration Object in the form of an Object Literal with properties that match the parameter names. We have two ways to deal with parameters so we call this the ZIM DUO technique.

Image for post
Image for post
ZIM DUO technique launched in ZIM DUO (version 2)

An Object Literal is a JavaScript construct with the following format: {property: value, property:value}. This looks like CSS but really, since it came first, CSS looks like an Object Literal.

Below, you will see that we are back to our simple button again but now with no corner! How very convenient! (Note that the order of the properties in the configuration object does not matter.) It is up to you to choose between the two formats. Sometimes it is good to go with the shorter format and sometimes you like using the config object for clarity.

Type and TEST:

new Button({corner:0}).sca(2).center();
Image for post
Image for post
Button with configuration object as parameter

As far as we know, ZIM is the only framework in the world that offers the dual parameter convenience. You can use this for your own classes. See zob() in the ZIM Docs (short for ZIM object). Stand-alone code is on GitHub so you can include in your library or framework independent of ZIM.

Image for post
Image for post
ZIM Docs with many parameters that use ZIM DUO

But I Want Different Color Circles! Waaaah!

ZIM has a Tile() class to easily tile an object into columns and rows. CLEAR your code, type and TEST the following:

new Tile(new Circle(50, purple), 8, 5, 10, 10)
Image for post
Image for post
ZIM Tile with 8 columns, 5 rows and spacing of 10

What if you wanted random purple, green and yellow colors? We could pick a random color ahead of time. Here is how we do that using one of the JavaScript conveniences called an Array.

An array is a list of things. In some languages, the things have to be of the same type but it does not matter in JavaScript. However, usually it is good practice to make them of the same type and then store things of different types in an object literal so you can label what the contents are. An array uses index numbers starting at 0 to access its elements. There are methods of the array to sort, add and remove items, find the index of an element, etc. See ZIM Kids Magic for an easy description or ZIM Skool Lesson 05 for a more complete description.

const colors = [purple, green, yellow]; // Array
let color = colors[0]; // color would be purple
color = colors[colors.length-1]; // yellow
// we can use Math.random() to get a number between 0 and .9999
// we can multiply that by the length of the array
// and then use Math.floor() to round down to a whole number
// and then get the color in the array at that number
// OR we can use the handy ZIM rand()
// See the ZIM Docs for the conveniences of ZIM rand()
color = colors[rand(colors.length-1)];// or we can use the handy ZIM shuffle()
// to shuffle the array
// then get the first element ;-)
color = shuffle(colors)[0];// these are some code conveniences in ZIM
// that are independent of the canvas but handy

Unfortunately, getting a random color will not give us a tile of random colors but rather a tile of all the same color of what was picked:

const colors = [purple, green, yellow];
let color = shuffle(colors)[0];
new Tile(new Circle(50, color), 8, 5, 10, 10)
Image for post
Image for post
Tiling a randomly picked color. Yellow this time…

We could build the tile ourselves by looping for the number of columns and rows, making and placing a circle with a random color each loop. But this is work which is why we made the Tile convenience class in the first place!

In ZIM VEE (version 5) we solved this problem

We added dynamic parameters we call ZIM VEE values. You can pass dynamic parameters to a class or method and the values get picked by the class or method. (Internally, we use a ZIM Pick() class which is available outside of ZIM on GitHub.) There are different types as follows:

  1. an array [one,two,three] picks randomly
  2. a range {min:50, max:100} will pick from range
  3. a series(one,two,three) will pick the next in order
  4. a function(){return value} will pick the return value
  5. a {noPick:[1,2,3]} object to bypass ZIM VEE
  6. a combination of any of these for recursive picking
  7. anything else will be picked as is

So, can you see how to get random colors in our Tile? Type this and TEST:

const colors = [purple, green, yellow];
new Tile(new Circle(50, colors), 8, 5, 10, 10)
Image for post
Image for post
Tile using ZIM VEE value to get random colors from array

Here is the Tile with a series. We could also pass in an array of shapes and randomly tile different shapes or pass in a series of components and tile the components in order. Here we will just tile circles with a series of color. Type this TEST:

const colors = series(purple, green, yellow);
new Tile(new Circle(50, colors), 8, 5, 10, 10)
Image for post
Image for post
Tile using ZIM VEE value to get a series of colors

The dynamic parameter are not just for Tile. Here are a few more examples to show how convenient these are. As far as we know, a system of dynamic parameters is unique to the ZIM JavaScript Canvas Framework.

  1. Emitting different particles with Emitter
  2. Calling an interval function at a range of times
  3. Setting styles randomly, in series or functionally
Companion Cube © Valve Corporation

On the Chain Gang!

One convenience that helps ZIM be a fraction the size of other canvas frameworks is Chaining. Chaining is when you add methods onto methods, etc. Let’s give an example then we will describe further.

// without chaining (105 characters):const rect = new Rectangle();
rect.scale = 3;
rect.alpha = 0;;
// with chaining (58 characters):new Rectangle().sca(3).alp(0).center().animate({alpha:1});// chaining 55% the size in this case
// or on separate lines (can comment out lines too):
new Rectangle()

Methods are dotted to objects. For chaining to work, each method must return the object. In a method, the object is represented by the keyword this. ZIM methods return this and can be chained. Sometimes a method needs to return a value — like hitTestPoint() will return true or false, so then the method cannot be chained. The on() method for events should not be chained either.

ZIM provides a set of short chainable methods that match traditional transform properties and other functionality. Here are some — can you guess what they do? If not, you can check them out in the ZIM Docs under METHODS > Short Chainable.

pos(), loc(), mov(), sca(), alp(), hov(), rot(), reg(), siz(),
ske(), tap(), hov(), cur(), top(), bot(), ord(), sha()

Other methods can be chained too such as

center(), centerReg(), animate(), cache(), setMask(), etc.
tap() and change() are chainable ways to capture events.
Characters © Studio Ghibli

I Am Feeling Loopy!

Loops are a convenience that all programming languages have to run a block of code as many times as specified in the loop. Usually, there is a counter that we call an iterator and so we often store this in a variable called i. If we loop within a loop then we move to j, then k.

Here is an example of a loop that writes the loop number, starting at 0, to the console. To see the console you can press F12 or Function F12 or open the console through the Browser menu (under developer tools or more tools) and then the console tab. Type this in the online editor and press TEST then F12. See the result of the code in the console (ignore the ace editor warnings).

// LOOP (you do not need to type the comments)
// start condition: i will be 0
// loop condition: as long as i is less than 10
// what to do after each loop: increase i by 1
for (let i=0; i < 10; i++) {
console.log(i); // 0-9
Image for post
Image for post
Output from a for loop in the Browser console (F12)

This is called a for loop. It is the most common type of loop. There are a few other types such as a while loop and a foreach loop. Loops are great for looping through an Array to get each value of the array.

Instead of console.log() we can use the ZIM convenience function called zog(). zog() does the same as console.log() but is shorter. You can also use different colors like zogr(), zogb(), zogy(), zogp(), and more. ZIM has a number of three-letter wrapper methods that are short cuts to various JavaScript commands. Although the DOM is not the focus of ZIM, there are wrapper functions to help on the DOM. For instance, zid() replaces document.getElementById() and zet() is the same as jQuery $().

Image for post
Image for post
Convenient wrapper functions at the bottom of ZIM Docs

Type, TEST and F12 this to see each name. You can try the colors too!

const names = ["Dr Abstract", "Pragma", "OwMe Cat"];
for (let i=0; i < names.length; i++) {
Image for post
Image for post
Looping through an Array and using zog() to log to console

The for loop is not very pleasant to use as there are three steps separated by semicolons (;) and the last step does not get one. When learning to code and even after years of coding, it is quite common to make mistakes with this format.

ZIM Loop

The ZIM loop is very convenient and easy to remember because it works the same way as the on(), interval() and timeout(). You tell ZIM loop what to loop through and it calls a function each time and gives the function relevant information. Let’s try a few examples:

loop(10, i=>{
const names = ["Dr Abstract", "Pragma", "OwMe Cat"];
loop(names, name=>{
Image for post
Image for post

Wow! 59% the size of the JavaScript loops

We often want to loop through a Container to get its children. Here is a comparison between the for loop and the ZIM loop to do that:

// a default Tile with 9 circles in a 3x3 gridconst circles = new Tile().center();// start alpha at .1 and increase by .1 each timefor (let i=0; i < circles.numChildren; i++) {
ZIM LOOPcircles.loop((circle, i)=>{
Image for post
Image for post
Looping through children of a container with a ZIM loop

Breaking and Continuing in Loops

Sometimes we want to go to the next loop. For this, we use the continue keyword in a traditional loop or we use a return for a ZIM loop.

Sometimes we want to end the loop completely. For this we use the break keyword in a traditional loop or we return a value for a ZIM loop.

This gets a little advanced, we just bring it up to note that a return value for the loop can be handy in some cases. For instance, testing if something in the loop is good or bad, or getting a total that is lower than maximum, etc.

Thank you ©Mr Rogers :: as a kid, I loved that train loop


We hope you don’t mind us telling you that Dr Abstract got chills reviewing these innovations! In this guide, we have explored four examples of conveniences:

  1. Regular parameters or a configuration object (ZIM DUO)
  2. Dynamic parameters (ZIM VEE)
  3. Chaining and short chainable methods
  4. Looping and the handy loop() function/method

Along the way we have seen other conveniences like rand(), shuffle(), Tile(), zog(). We explored more JavaScript programming basics of Arrays which is a list of things and for loops which are handy for looping through arrays.

Each class, method and function in ZIM is a convenience too! Single line drag and drop, multiple hit tests, scaling frame, and more. Please see the ZIM About page for a complete list.

Image for post
Image for post
A sideways glance at canvas conveniences

Further reading

Another exciting convenience on the canvas is STYLE. Please see ◎ Your Guide to STYLE on the Canvas.

If you were looking specifically for conveniences of the canvas compared to the HTML DOM then please see ◎ Your Guide to When to Use a JavaScript Canvas Library or Framework.

To explore all about coding on the canvas please visit ◎ Your Guide to Coding Creativity on the Canvas.

All the best! Dr Abstract.

Image for post
Image for post

Follow us on Twitter at ZIM Learn and here is ZIM Learn on YouTube!

Inventor, Founder of ZIM JavaScript Canvas Framework and Nodism, Professor of Interactive Media at Sheridan, Canadian New Media Awards Programmer and Educator

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store