Checkboxland

Render anything as HTML checkboxes

Demos

Overview

Checkboxland is a JavaScript library for rendering anything as HTML checkboxes.

You can use it to display animations, text, images, video, and arbitrary data. It also supports plugins, so you can add your own APIs.

Checkboxland is dependency-free, framework-agnostic, and fun! 🙃

Why does this even exist? Here's some background.

Limitations

Having lots of elements on a webpage can impact runtime performance. Checkboxes are no exception. Checkboxland attempts to mitigate some of these issues, but you'll likely run into performance issues if you are displaying large grids (1500+ checkboxes), and trying to update them rapidly.

For best results, stay below 1500 checkboxes. Some good sizes in this range include 32x32, 48x24, and 64x16.

Setup

Install this package via npm:

npm install checkboxland

Import it into your application, and create a checkbox grid:

import { Checkboxland } from 'checkboxland';

// Create a 16x16 checkbox grid inside `#my-container`
const cbl = new Checkboxland({
  dimensions: '16x16',
  selector: '#my-container'
});

The Checkboxland class accepts a few possible arguments:

Note: if you really want to load Checkboxland with a <script> tag, consider using an inline es6 module, as shown below:

<script type="module">
  import { Checkboxland } from 'https://unpkg.com/checkboxland?module';
  window.Checkboxland = Checkboxland;
</script>

An Example

Let's display a heart on a checkbox grid:

import { Checkboxland } from 'checkboxland';

const cbl = new Checkboxland({
  dimensions: '8x7',
  selector: '#my-container'
});

// Create a data representation of the heart.
const heart = [
  [0,1,1,0,0,1,1,0],
  [1,0,0,1,1,0,0,1],
  [1,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,1],
  [0,1,0,0,0,0,1,0],
  [0,0,1,0,0,1,0,0],
  [0,0,0,1,1,0,0,0],
];

// This updates the grid with the data we provided.
cbl.setData(heart);

(note: you can play with this example on Codepen and fork it to build your own demos)

a grid of checkboxes displaying the shape of a heart

So what happened?

We created a JavaScript matrix (an array of arrays) to represent the grid. Each location in the matrix represents a checkbox, where:

By passing this matrix to our setData() method, we update the checkbox grid on the page.

More Checkboxland Examples

For more ways to interact with the checkbox grid, see the API methods below.

Low-level API

The low-level API lets you update the checkbox grid with raw data.

getCheckboxValue

Gets the value of a single checkbox in the checkbox grid.

Requires an (x,y) coordinate to identify the checkbox location.

Note: the top-left corner of the grid represents the origin (0,0).

.getCheckboxValue(x, y)

Arguments

Returns

(number): Returns a 0, 1, or 2 (where 0 represents "unchecked", 1 represents "checked", and 2 represents "indeterminate").

setCheckboxValue

Sets the value of a single checkbox in the checkbox grid.

Requires an (x, y) coordinate to identify the checkbox location.

Note: the top-left corner of the grid represents the origin (0,0).

.setCheckboxValue(x, y, newValue)

Arguments

Returns

Nothing

getData

Get a data matrix representing the current state of the checkbox grid.

.getData()

Arguments

None

Returns

(array): A matrix (array of arrays), representing the full state of the checkbox grid.

setData

Sets the values in the checkbox grid to those in the provided matrix.

By default, the matrix will overwrite the existing data in the grid, starting at the top-left corner. Options exist for more targeted data setting.

.setData(data, [options])

Arguments

Returns

Nothing

clearData

Clears all data from the checkbox grid. Result: all checkboxes in the grid become unchecked.

.clearData()

Arguments

None

Returns

Nothing

getEmptyMatrix

A utility that returns an empty matrix, with the dimensions of the existing checkbox grid.

Optionally, an object can be provided to customize the pre-filled value, or the dimensions of the returned matrix.

.getEmptyMatrix([options])

Arguments

Returns

(array): A matrix (array of arrays), with the dimensions of the existing checkbox grid containing only 0 values (unless otherwise specified).

Extended API

Checkboxland comes with built-in plugins that extend the API with higher-level functionality. The following are the API methods provided by these "core" plugins.

print

Prints text to the checkbox grid. This text overwrites the existing checkbox grid, starting in the top left corner.

Most of the characters in the default font are 5x7 checkboxes in size. Supported characters include the following:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789`~!@#$%^&*()-_+=[]{}|\/;:"',.<>?

For a working example, see the textbox demo.

.print(text, [options])

None, UNLESS options.dataOnly is set to true. If this is the case, it returns a matrix (array of arrays).

marquee

Animates a block of data, by making it scroll across the checkbox grid from right to left.

For a working example, see the marquee demo.

.marquee(data, [options])

Arguments

Returns

Nothing

Clean up

To cancel a marquee in progress, call the cleanUp method:

.marquee.cleanUp()

renderImage

Renders the provided image as checkboxes. Tested formats include PNG, JPEG, WEBP, and GIF (not animated).

Note: when loading an image from an external domain using an HTMLImageElement, you will need to include the crossorigin="anonymous" attribute. The image host will also need to send an Access-Control-Allow-Origin header.

See examples using HTMLImageElement, file uploads, url loading, and drag-and-drop.

.renderImage(dataSource, [options])

Arguments

Returns

Nothing

renderVideo

Renders the provided video as checkboxes. Tested formats include MP4, WEBM, and MediaStreams.

Note: when loading an video from an external domain with an HTMLVideoElement, you will need to include the crossorigin="anonymous" attribute. The video host should also send an Access-Control-Allow-Origin header.

See examples using HTMLVideoElement, file uploads, url loading, drag-and-drop, and webcam.

.renderVideo(dataSource, [options])

Arguments

Returns

Nothing

Clean up

To cancel an autoplaying checkbox video, call the cleanUp method:

.renderVideo.cleanUp()

transitionWipe

Transition between the current checkbox grid state and a future state by wiping across the screen.

For a working example, see the wipe demo.

.transitionWipe(newData, [options])

Arguments

Returns

Nothing

Clean up

To cancel a transition in progress, call the cleanUp method:

.transitionWipe.cleanUp()

dataUtils

Perform a variety of transformations (or actions) on a matrix of data, and return the result. These transformation do not affect the checkbox grid.

.dataUtils(actionName, matrix, [options])

Arguments

Supported actionNames:

Returns

(array): A matrix (array of arrays), representing the transformed data.

onClick

Registers an eventHandler, which is called when the checkbox grid is clicked. Also provides data about the location of the click.

For a working example, see the "On Click" demo.

.onClick(eventHandler)

Arguments

When called, the eventHandler is passed a data object, as defined below:

Returns

Nothing

Clean up

To remove the onClick event listener from your checkbox grid, call the cleanUp method:

.onClick.cleanUp()

Using Plugins

Checkboxland supports plugins, which extend the API and provide higher-level functionality.

Here's a (realistic, but fake) example on how use a plugin to extend Checkboxland:

import { Checkboxland } from 'checkboxland';
import mirrorPlugin from 'checkboxland-mirror';

Checkboxland.extend(mirrorPlugin);

const cbl = new Checkboxland();

// Mirror the data on the grid
cbl.mirror();

You can see more examples of plugins being used in Checkboxland's core files.

Existing Plugins

(if you write a 3rd-party plugin for Checkboxland, I'll list it here)

Creating a Plugin

Checkboxland plugins are just JavaScript functions that get special access to Checkboxland data.

Plugins can access all of Checkboxland's properties and low-level API methods on the this object. This includes:

Note: do not access Checkboxland's internal this._data object directly. Instead, use this.getData() and this.setData().

An Example

Here's an example of a plugin that logs various pieces of data to the JavaScript console:

import { Checkboxland } from 'checkboxland';

// Define the plugin's name and the function to be executed
const myPlugin = {
  name: 'logData',
  exec: (propertyName) => {
    if (propertyName === 'element') {
      console.log(this.displayEl);
    } else
    if (propertyName === 'dimensions') {
      console.log(`width: ${this.dimensions[0]}`);
      console.log(`height: ${this.dimensions[1]}`);
    } else
    if (propertyName === 'matrix') {
      console.log(this.getData());
    }
  }
  cleanUp: () => {
    // An optional method for cleaning up when you're done
    // using the plugin (useful for removing event listeners,
    // clearing timeouts, etc.)
    console.log('clean up was called');
  }
}

// Register the plugin
Checkboxland.extend(myPlugin);

const cbl = new Checkboxland({ dimensions: '4x2' });

// Call the plugin's function via its name
cbl.logData('element'); // => <div id="checkboxland">...</div>
cbl.logData('dimensions'); // => 'width: 4, height: 2'
cbl.logData('matrix'); // => (2) [Array(4), Array(4)]
cbl.logData.cleanUp(); // => 'clean up was called'

For more plugin examples, see these plugins built into Checkboxland.