-
Notifications
You must be signed in to change notification settings - Fork 43
/
index.html
763 lines (563 loc) · 38.8 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Checkboxland - Render anything as HTML checkboxes</title>
<meta name="description" content="The Checkboxland JavaScript library renders anything as HTML checkboxes, from animations and text to images and video.">
<meta name="keywords" content="HTML, Checkboxes, Checkboxland">
<meta name="robots" content="follow, index">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta property="og:title" content="Checkboxland">
<meta property="og:description" content="Render anything as HTML checkboxes">
<meta property="og:url" content="https://bryanbraun.com/checkboxland/">
<meta property="og:type" content="website">
<meta property="og:image" content="https://bryanbraun.com/checkboxland/docs/img/checkboxland-logo.png">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-D0c+hzoDMMxO+ZYOgA6FKzW2ZJnDBo9Qnm0gGo4Kxsg='; style-src 'self' 'unsafe-inline'; font-src data: fonts.gstatic.com;">
<link rel="icon" type="image/png" sizes="16x16" href="docs/favicon.png">
<link rel="stylesheet" type="text/css" href="docs/css/styles.css" />
<link rel="stylesheet" type="text/css" href="docs/css/cbl-normalize.css" />
</head>
<body>
<div class="page">
<aside class="sidebar">
<div id="logo" class="checkbox-logo cbl-normalize"></div>
<nav>
<h3>The Basics</h3>
<ul>
<li><a href="#demos">Demos</a></li>
<li><a href="#overview">Overview</a></li>
<li><a href="#limitations">Limitations</a></li>
<li><a href="#setup">Setup</a></li>
<li><a href="#an-example">An Example</a></li>
</ul>
</nav>
<nav>
<h3>Methods</h3>
<ul>
<li><a href="#low-level-api">Low-level API</a>
<ul>
<li><a href="#getcheckboxvalue">getCheckboxValue</a></li>
<li><a href="#setcheckboxvalue">setCheckboxValue</a></li>
<li><a href="#getdata">getData</a></li>
<li><a href="#setdata">setData</a></li>
<li><a href="#cleardata">clearData</a></li>
<li><a href="#getemptymatrix">getEmptyMatrix</a></li>
</ul>
</li>
<li><a href="#extended-api">Extended API</a>
<ul>
<li><a href="#print">print</a></li>
<li><a href="#marquee">marquee</a></li>
<li><a href="#transitionwipe">transitionWipe</a></li>
<li><a href="#datautils">dataUtils</a></li>
<li><a href="#onclick">onClick</a></li>
<li><a href="#renderimage">renderImage</a></li>
<li><a href="#rendervideo">renderVideo</a></li>
</ul>
</li>
</ul>
</nav>
<nav>
<h3>Advanced Usage</h3>
<ul>
<li><a href="#using-plugins">Using Plugins</a></li>
<li><a href="#creating-a-plugin">Creating a Plugin</a></li>
</ul>
</nav>
</aside>
<main class="main">
<h1 class="title">Checkboxland</h1>
<h2 class="subtitle">Render anything as HTML checkboxes</h2>
<div id="demos" class="demobox cbl-normalize">
<div id="checkboxland" class="demoframe"></div>
<h3 class="demo-title">Demos</h3>
<form id="demoboxForm" class="demobox-form">
<!-- note: the image thumbnails show a screenshot of a 34x15 grid captured in Safari -->
<input type="radio" id="wave-demo" class="visuallyhidden" name="demoRadios" value="wave" checked="true" />
<label for="wave-demo" class="demo-option">
<span class="demo-name">Wave</span>
<img class="demo-thumbnail" src="docs/img/demo-wave.png" />
</label>
<input type="radio" id="marquee-demo" class="visuallyhidden" name="demoRadios" value="marquee" />
<label for="marquee-demo" class="demo-option">
<span class="demo-name">Marquee</span>
<img class="demo-thumbnail" src="docs/img/demo-marquee.png" />
</label>
<input type="radio" id="ripple-demo" class="visuallyhidden" name="demoRadios" value="ripple" />
<label for="ripple-demo" class="demo-option">
<span class="demo-name">Ripple</span>
<img class="demo-thumbnail" src="docs/img/demo-ripple.png" />
</label>
<input type="radio" id="snake-demo" class="visuallyhidden" name="demoRadios" value="snake" />
<label for="snake-demo" class="demo-option">
<span class="demo-name">Snake</span>
<img class="demo-thumbnail" src="docs/img/demo-snake.png" />
</label>
<input type="radio" id="pinwheel-demo" class="visuallyhidden" name="demoRadios" value="pinwheel" />
<label for="pinwheel-demo" class="demo-option">
<span class="demo-name">Pinwheel</span>
<img class="demo-thumbnail" src="docs/img/demo-pinwheel.png" />
</label>
<input type="radio" id="clock-demo" class="visuallyhidden" name="demoRadios" value="clock" />
<label for="clock-demo" class="demo-option">
<span class="demo-name">Clock</span>
<img class="demo-thumbnail" src="docs/img/demo-clock.png" />
</label>
<input type="radio" id="webcam-demo" class="visuallyhidden" name="demoRadios" value="webcam" />
<label for="webcam-demo" class="demo-option">
<span class="demo-name">Webcam</span>
<img class="demo-thumbnail" src="docs/img/demo-webcam.png" />
</label>
<input type="radio" id="game-of-life-demo" class="visuallyhidden" name="demoRadios" value="gameOfLife" />
<label for="game-of-life-demo" class="demo-option">
<span class="demo-name">Game of Life</span>
<img class="demo-thumbnail" src="docs/img/demo-game-of-life.png" />
</label>
<input type="radio" id="video-demo" class="visuallyhidden" name="demoRadios" value="video" />
<label for="video-demo" class="demo-option">
<span class="demo-name">Video</span>
<img class="demo-thumbnail" src="docs/img/demo-video.png" />
</label>
<input type="radio" id="lasers-demo" class="visuallyhidden" name="demoRadios" value="lasers" />
<label for="lasers-demo" class="demo-option">
<span class="demo-name">Lasers</span>
<img class="demo-thumbnail" src="docs/img/demo-lasers.png" />
</label>
<input type="radio" id="spiral-demo" class="visuallyhidden" name="demoRadios" value="spiral" />
<label for="spiral-demo" class="demo-option">
<span class="demo-name">Spiral</span>
<img class="demo-thumbnail" src="docs/img/demo-spiral.png" />
</label>
<input type="radio" id="pulse-demo" class="visuallyhidden" name="demoRadios" value="pulse" />
<label for="pulse-demo" class="demo-option">
<span class="demo-name">Pulse</span>
<img class="demo-thumbnail" src="docs/img/demo-pulse.png" />
</label>
<input type="radio" id="icons-demo" class="visuallyhidden" name="demoRadios" value="icons" />
<label for="icons-demo" class="demo-option">
<span class="demo-name">Icons</span>
<img class="demo-thumbnail" src="docs/img/demo-icons.png" />
</label>
<input type="radio" id="checkerboard-demo" class="visuallyhidden" name="demoRadios" value="checkerboard" />
<label for="checkerboard-demo" class="demo-option">
<span class="demo-name">Checkerboard</span>
<img class="demo-thumbnail" src="docs/img/demo-checkerboard.png" />
</label>
<input type="radio" id="wipe-demo" class="visuallyhidden" name="demoRadios" value="wipe" />
<label for="wipe-demo" class="demo-option">
<span class="demo-name">Wipe</span>
<img class="demo-thumbnail" src="docs/img/demo-wipe.png" />
</label>
<input type="radio" id="image-demo" class="visuallyhidden" name="demoRadios" value="image" />
<label for="image-demo" class="demo-option">
<span class="demo-name">Image</span>
<img class="demo-thumbnail" src="docs/img/demo-image.png" />
</label>
<input type="radio" id="qr-code-demo" class="visuallyhidden" name="demoRadios" value="qrCode" />
<label for="qr-code-demo" class="demo-option">
<span class="demo-name">QR Code</span>
<img class="demo-thumbnail" src="docs/img/demo-qr-code.png" />
</label>
<input type="radio" id="on-click-demo" class="visuallyhidden" name="demoRadios" value="onClick" />
<label for="on-click-demo" class="demo-option">
<span class="demo-name">On Click</span>
<img class="demo-thumbnail" src="docs/img/demo-on-click.png" />
</label>
</form>
<div class="demo-source"><a href="https://github.com/bryanbraun/checkboxland/tree/main/docs/demos">(view source code for the demos here)</a></div>
</div>
<h2>Overview</h2>
<p>Checkboxland is a JavaScript library for rendering anything as HTML checkboxes.</p>
<p>You can use it to display animations, text, images, video, and arbitrary data. It also supports plugins, so you can add your own APIs.</p>
<p>Checkboxland is dependency-free, framework-agnostic, and fun! 🙃</p>
<small>Why does this even exist? <a href="https://www.bryanbraun.com/2020/06/06/checkboxland/">Here's some background</a>.</small>
<h2>Limitations</h2>
<p>Having lots of elements on a webpage <a href="https://web.dev/dom-size/">can impact runtime performance</a>. 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.</p>
<p>For best results, stay below 1500 checkboxes. Some good sizes in this range include <code>32x32</code>, <code>48x24</code>, and <code>64x16</code>.</p>
<h2>Setup</h2>
<p>Install this package via npm:</p>
<pre><code>npm install checkboxland</code></pre>
<p>Import it into your application, and create a checkbox grid:</p>
<pre><code class="js language-js">import { Checkboxland } from 'checkboxland';
// Create a 16x16 checkbox grid inside `#my-container`
const cbl = new Checkboxland({
dimensions: '16x16',
selector: '#my-container'
});</code></pre>
<p>The Checkboxland class accepts a few possible arguments:</p>
<ul>
<li><code>dimensions</code> (string): A string representing the checkbox grid dimensions in a '{width}x{height}' format. <em>Default: '8x8'.</em></li>
<li><code>selector</code> (string | Element): A <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector">selector</a> to the container element where Checkboxland should render the checkbox grid. Or you can pass an <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element">Element</a> or <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement">HTMLElement</a> directly. <em>Default: '#checkboxland'.</em></li>
<li><code>fillValue</code> (number): The type of checkbox you want to pre-populate the grid with. <em>Default: 0 (unchecked).</em></li>
</ul>
<p><em>Note: if you really want to load Checkboxland with a <code><script></code> tag, consider using an <a href="https://jakearchibald.com/2017/es-modules-in-browsers/">inline es6 module</a>, as shown below:</em></p>
<pre><code class="language-markup"><script type="module">
import { Checkboxland } from 'https://unpkg.com/checkboxland?module';
window.Checkboxland = Checkboxland;
</script></code></pre>
<h2 id="an-example">An Example</h2>
<p>Let's display a heart on a checkbox grid:</p>
<pre><code class="js language-js">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);</code></pre>
<small><p><em>(note: you can <a href="https://codepen.io/bryanbraun/pen/YzwoxpB">play with this example on Codepen</a> and fork it to build your own demos)</em></p></small>
<p><img src="docs/img/checkbox-heart.png" width="115" height="102" alt="a grid of checkboxes displaying the shape of a heart" /></p>
<p>So what happened?</p>
<p>We created a JavaScript matrix (an array of arrays) to represent the grid. Each location in the matrix represents a checkbox, where:</p>
<ul>
<li>0 = <img src="docs/img/unchecked.png" class="cb-16x16" alt="a single, unchecked, checkbox" /> (unchecked)</li>
<li>1 = <img src="docs/img/checked.png" class="cb-16x16" alt="a single, checked, checkbox" /> (checked)</li>
<li>2 = <img src="docs/img/indeterminate.png" class="cb-16x16" alt="a single, indeterminate, checkbox" /> (indeterminate)</li>
</ul>
<p>By passing this matrix to our <code>setData()</code> method, we update the checkbox grid on the page.</p>
<h3>More Checkboxland Examples</h3>
<ul>
<li><a href="https://codepen.io/bryanbraun/pen/YzwoxpB">A heart with Checkboxland (Codepen)</a></li>
<li><a href="https://stackblitz.com/edit/react-zzafmo?file=src%2FCheckboxImages.js">Integrating Checkboxland with React (Stackblitz)</a></li>
<li><a href="https://github.com/bryanbraun/checkboxland/tree/main/docs/demos">The Checkboxland demos (source code on Github)</a></li>
<li><a href="https://github.com/healeycodes/doom-checkboxes">DOOM via Checkboxes (source code on Github)</a></li>
</ul>
<p>For more ways to interact with the checkbox grid, see the API methods below.</p>
<h2>Low-level API</h2>
<p>The low-level API lets you update the checkbox grid with raw data.</p>
<h3>getCheckboxValue</h3>
<p>Gets the value of a single checkbox in the checkbox grid.</p>
<p>Requires an (x,y) coordinate to identify the checkbox location.</p>
<p><em>Note: the top-left corner of the grid represents the origin (0,0)</em>.</p>
<pre><code>.getCheckboxValue(x, y)</code></pre>
<h4 id="getcheckboxvalue-arguments">Arguments</h4>
<ul>
<li><code>x</code> (number): The x-coordinate of the checkbox you are targeting.</li>
<li><code>y</code> (number): The y-coordinate of the checkbox you are targeting.</li>
</ul>
<h4 id="getcheckboxvalue-returns">Returns</h4>
<p>(number): Returns a 0, 1, or 2 (where 0 represents "unchecked", 1 represents "checked", and 2 represents "indeterminate").</p>
<h3>setCheckboxValue</h3>
<p>Sets the value of a single checkbox in the checkbox grid.</p>
<p>Requires an (x, y) coordinate to identify the checkbox location.</p>
<p><em>Note: the top-left corner of the grid represents the origin (0,0)</em>.</p>
<pre><code>.setCheckboxValue(x, y, newValue)</code></pre>
<h4 id="setcheckboxvalue-arguments">Arguments</h4>
<ul>
<li><code>x</code> (number): The x-coordinate of the checkbox you are targeting.</li>
<li><code>y</code> (number): The y-coordinate of the checkbox you are targeting.</li>
<li><code>newValue</code> (number): The value of the checkbox you are setting. Must be 0, 1, or 2 (0 represents "unchecked", 1 represents "checked", and 2 represents "indeterminate").</li>
</ul>
<h4 id="setcheckboxvalue-returns">Returns</h4>
<p>Nothing</p>
<h3>getData</h3>
<p>Get a data matrix representing the current state of the checkbox grid.</p>
<pre><code>.getData()</code></pre>
<h4 id="getdata-arguments">Arguments</h4>
<p>None</p>
<h4 id="getdata-returns">Returns</h4>
<p>(array): A matrix (array of arrays), representing the full state of the checkbox grid.</p>
<h3>setData</h3>
<p>Sets the values in the checkbox grid to those in the provided matrix.</p>
<p>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.</p>
<pre><code>.setData(data, [options])</code></pre>
<h4 id="setdata-arguments">Arguments</h4>
<ul>
<li><code>data</code> (array): A matrix (array of arrays), containing the data you want to set to the checkbox grid.</li>
<li><code>options</code> (object)
<ul>
<li><code>x</code> (number): The x-coordinate where you want to begin setting data. <em>Default: 0.</em></li>
<li><code>y</code> (number): The y-coordinate where you want to begin setting data. <em>Default: 0.</em></li>
<li><code>fillValue</code> (number): If the data you are setting won't fill the whole checkbox grid, you can optionally provide a checkbox value (0, 1, or 2) which will then be used to fill the leftover areas. <em>Default: <code>undefined</code>.</em></li>
</ul>
</li>
</ul>
<h4 id="setdata-returns">Returns</h4>
<p>Nothing</p>
<h3>clearData</h3>
<p>Clears all data from the checkbox grid. Result: all checkboxes in the grid become unchecked.</p>
<pre><code>.clearData()</code></pre>
<h4 id="cleardata-arguments">Arguments</h4>
<p>None</p>
<h4 id="cleardata-returns">Returns</h4>
<p>Nothing</p>
<h3>getEmptyMatrix</h3>
<p>A utility that returns an empty matrix, with the dimensions of the existing checkbox grid.</p>
<p>Optionally, an object can be provided to customize the pre-filled value, or the dimensions of the returned matrix.</p>
<pre><code>.getEmptyMatrix([options])</code></pre>
<h4 id="cleardata-arguments">Arguments</h4>
<ul>
<li><code>options</code> (object)
<ul>
<li><code>fillValue</code> (number): The value you want to pre-populate the returned matrix with. <em>Default: 0.</em></li>
<li><code>width</code> (number): The width of the returned matrix (in columns). <em>Defaults to the width of the existing checkbox grid.</em></li>
<li><code>height</code> (number): The height of the returned matrix (in rows). <em>Defaults to the height of the existing checkbox grid.</em></li>
</ul>
</li>
</ul>
<h4 id="cleardata-returns">Returns</h4>
<p>(array): A matrix (array of arrays), with the dimensions of the existing checkbox grid containing only <code>0</code> values (unless otherwise specified).</p>
<h2>Extended API</h2>
<p>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.</p>
<h3>print</h3>
<p>Prints text to the checkbox grid. This text overwrites the existing checkbox grid, starting in the top left corner.</p>
<p>Most of the characters in <a href="https://github.com/bryanbraun/checkboxland/blob/main/src/plugins/print/font-5x7.js">the default font</a> are 5x7 checkboxes in size. Supported characters include the following:</p>
<pre><code>ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789`~!@#$%^&*()-_+=[]{}|\/;:"',.<>?</code></pre>
<p>For a working example, see <a href="https://github.com/bryanbraun/checkboxland/blob/main/docs/demos/textbox/demo.js">the textbox demo</a>.</p>
<pre><code>.print(text, [options])</code></pre>
<h4 id="print-arguments">Arguments</h4>
<ul>
<li><code>text</code> (string): The text you want printed to the checkbox grid.</li>
<li><code>options</code> (object)
<ul>
<li><code>font</code> (object): An object containing character data for a custom font, if you want to use one. For a working example, see <a href="https://github.com/bryanbraun/checkboxland/blob/main/docs/demos/clock/demo.js">the clock demo</a>.</li>
<li><code>x</code> (number): The x-coordinate where the text should start on the checkbox grid. <em>Default: 0.</em></li>
<li><code>y</code> (number): The y-coordinate where the text should start on the checkbox grid. <em>Default: 0.</em></li>
<li><code>fillValue</code> (number): If the text data won't fill the whole checkbox grid, you can (0, 1, or 2) which will then be used to fill the leftover areas. <em>Default: <code>undefined</code>.</em></li>
<li><code>dataOnly</code> (boolean): If <code>true</code>, returns a data matrix for the text instead of updating the checkbox grid. <em>Default: <code>false</code></em></li>
</ul>
</li>
</ul>
<h4 id="print-returns">Returns</h4>
<p>None, UNLESS <code>options.dataOnly</code> is set to <code>true</code>. If this is the case, it returns a matrix (array of arrays).</p>
<h3>marquee</h3>
<p>Animates a block of data, by making it scroll across the checkbox grid from right to left.</p>
<p>For a working example, see <a href="https://github.com/bryanbraun/checkboxland/blob/main/docs/demos/marquee/demo.js">the marquee demo</a>.</p>
<pre><code>.marquee(data, [options])</code></pre>
<h4 id="marquee-arguments">Arguments</h4>
<ul>
<li><code>data</code> (array): A matrix (array of arrays), representing the block of data you want to scroll across the grid.</li>
<li><code>options</code> (object)
<ul>
<li><code>repeat</code> (boolean): Repeat the animation, once it is complete. <em>Default: <code>false</code></em></li>
<li><code>interval</code> (number): The number of milliseconds between each step in the animation. <em>Default: <code>200</code></em></li>
<li><code>fillValue</code> (number): If the scrolling data doesn't fill the whole checkbox grid, this checkbox value is used to fill the leftover areas. <em>Default: <code>0</code></em></li>
<li><code>callback</code> (function): A callback to be executed when the animation is complete.</li>
</ul>
</li>
</ul>
<h4 id="marquee-returns">Returns</h4>
<p>Nothing</p>
<h4 id="marquee-clean-up">Clean up</h4>
<p>To cancel a marquee in progress, call the <code>cleanUp</code> method:</p>
<pre><code>.marquee.cleanUp()</code></pre>
<h3>renderImage</h3>
<p>Renders the provided image as checkboxes. Tested formats include PNG, JPEG, WEBP, and GIF (not animated).</p>
<p>Note: when loading an image from an external domain using an <code>HTMLImageElement</code>, you will need to include <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin">the crossorigin="anonymous" attribute</a>. The image host will also need to send <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin">an Access-Control-Allow-Origin header</a>.</p>
<p>See examples using <a href="./docs/demos/image-test/"><code>HTMLImageElement</code>, file uploads, url loading, and drag-and-drop</a>.</p>
<pre><code>.renderImage(dataSource, [options])</code></pre>
<h4 id="renderImage-arguments">Arguments</h4>
<ul>
<li><code>dataSource</code> (string | HTMLImageElement): A string containing the URL for an image (including data URLs), or an <code>HTMLImageElement</code> with the <code>src</code> defined (like an <code><img /></code> tag queried from the page).</li>
<li><code>options</code> (object)
<ul>
<li><code>threshold</code> (number): A number between 0-100, representing <a href="https://en.wikipedia.org/wiki/Thresholding_(image_processing)">the threshold value</a> for separating the video into dark and light regions. <em>Default: 50</em></li>
<li><code>dithering</code> (string): The dithering algorithm used to render the video. Accepts <code>ordered</code>, <code>atkinson</code>, <code>errorDiffusion</code>, or <code>none</code>. <em>Default: <code>none</code>.</em></li>
<li><code>x</code> (number): The x-coordinate where you want the image to begin. <em>Default: 0.</em></li>
<li><code>y</code> (number): The y-coordinate where you want the image to begin. <em>Default: 0.</em></li>
<li><code>fillValue</code> (number): If the image you are placing doesn't fill the whole checkbox grid, you can optionally provide a checkbox value (0, 1, or 2) which will then be used to fill the leftover areas. <em>Default: <code>undefined</code>.</em></li>
</ul>
</li>
</ul>
<h4 id="renderImage-returns">Returns</h4>
<p>Nothing</p>
<h3>renderVideo</h3>
<p>Renders the provided video as checkboxes. Tested formats include MP4, WEBM, and <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaStream">MediaStreams</a>.</p>
<p>Note: when loading an video from an external domain with an <code>HTMLVideoElement</code>, you will need to include <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin">the crossorigin="anonymous" attribute</a>. The video host should also send <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin">an Access-Control-Allow-Origin header</a>.</p>
<p>See examples using <a href="./docs/demos/video-test/"><code>HTMLVideoElement</code>, file uploads, url loading, drag-and-drop</a>, and <a href="./docs/demos/webcam-test/">webcam</a>.</p>
<pre><code>.renderVideo(dataSource, [options])</code></pre>
<h4 id="renderVideo-arguments">Arguments</h4>
<ul>
<li><code>dataSource</code> (string | HTMLVideoElement): A string containing the URL for a video (including data URLs), or an <code>HTMLVideoElement</code> with the <code>src</code> defined (like an <code><video /></code> tag queried from the page). Videos passed as URLs will play automatically with reasonable default settings. Videos passed as an <code>HTMLVideoElement</code> can be customized via <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#attributes">HTML attributes</a> and controlled via <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement">the HTMLMediaElement APIs</a>.</li>
<li><code>options</code> (object)
<ul>
<li><code>threshold</code> (number): A number between 0-100, representing <a href="https://en.wikipedia.org/wiki/Thresholding_(image_processing)">the threshold value</a> for separating the video into dark and light regions. <em>Default: 50</em></li>
<li><code>dithering</code> (string): The dithering algorithm used to render the video. Accepts <code>ordered</code>, <code>atkinson</code>, <code>errorDiffusion</code>, or <code>none</code>. <em>Default: <code>none</code>.</em></li>
<li><code>x</code> (number): The x-coordinate where you want the video to begin. <em>Default: 0.</em></li>
<li><code>y</code> (number): The y-coordinate where you want the video to begin. <em>Default: 0.</em></li>
<li><code>fillValue</code> (number): If the video you are placing won't fill the whole checkbox grid, you can optionally provide a checkbox value (0, 1, or 2) which will then be used to fill the leftover areas. <em>Default: <code>undefined</code>.</em></li>
</ul>
</li>
</ul>
<h4 id="renderVideo-returns">Returns</h4>
<p>Nothing</p>
<h4 id="renderVideo-clean-up">Clean up</h4>
<p>To cancel an autoplaying checkbox video, call the <code>cleanUp</code> method:</p>
<pre><code>.renderVideo.cleanUp()</code></pre>
<h3>transitionWipe</h3>
<p>Transition between the current checkbox grid state and a future state by wiping across the screen.</p>
<p>For a working example, see <a href="https://github.com/bryanbraun/checkboxland/blob/main/docs/demos/wipe/demo.js">the wipe demo</a>.</p>
<pre><code>.transitionWipe(newData, [options])</code></pre>
<h4 id="transitionwipe-arguments">Arguments</h4>
<ul>
<li><code>newData</code> (array): A matrix (array of arrays), representing the final state of the checkbox grid after the transition.</li>
<li><code>options</code> (object)
<ul>
<li><code>direction</code> (string): The direction of the wipe. Accepts <code>ltr</code> (left-to-right) and <code>rtl</code> (right-to-left). <em>Default: <code>ltr</code></em></li>
<li><code>interval</code> (number): The number of milliseconds between each step in the animation. <em>Default: <code>200</code></em></li>
<li><code>fillValue</code> (number): If the scrolling data doesn't fill the whole checkbox grid, this checkbox value is used to fill the leftover areas. <em>Default: <code>0</code></em></li>
<li><code>callback</code> (function): A callback to be executed when the animation is complete.</li>
</ul>
</li>
</ul>
<h4 id="transitionwipe-returns">Returns</h4>
<p>Nothing</p>
<h4 id="transitionwipe-clean-up">Clean up</h4>
<p>To cancel a transition in progress, call the <code>cleanUp</code> method:</p>
<pre><code>.transitionWipe.cleanUp()</code></pre>
<h3>dataUtils</h3>
<p>Perform a variety of transformations (or actions) on a matrix of data, and return the result. These transformation do not affect the checkbox grid.</p>
<pre><code>.dataUtils(actionName, matrix, [options])</code></pre>
<h4 id="datautils-arguments">Arguments</h4>
<ul>
<li><code>actionName</code> (string): The name of the transformation you want to apply to your matrix.</li>
<li><code>matrix</code> (array): A matrix (array of arrays), representing the data you want to transform.</li>
<li><code>options</code> (object): Options for the transformation.</li>
</ul>
<p><em>Supported <code>actionName</code>s:</em></p>
<ul>
<li><code>invert</code>: Inverts the provided matrix (all 0s become 1s and vice-versa). No options supported.</li>
<li><code>pad</code>: Adds padding around the provided matrix. Options include:
<ul>
<li><code>top</code> (number): The number of rows of padding on the top.</li>
<li><code>bottom</code> (number): The number of rows of padding on the bottom.</li>
<li><code>left</code> (number): The number of columns of padding on the left.</li>
<li><code>right</code> (number): The number of columns of padding on the right.</li>
<li><code>all</code> (number): Sets this padding value on all sides of the matrix.</li>
</ul>
</li>
</ul>
<h4 id="datautils-returns">Returns</h4>
<p>(array): A matrix (array of arrays), representing the transformed data.</p>
<h3>onClick</h3>
<p>Registers an <code>eventHandler</code>, which is called when the checkbox grid is clicked. Also provides <code>data</code> about the location of the click.</p>
<p>For a working example, see <a href="https://github.com/bryanbraun/checkboxland/blob/main/docs/demos/on-click/demo.js">the "On Click" demo</a>.</p>
<pre><code>.onClick(eventHandler)</code></pre>
<h4 id="onclick-arguments">Arguments</h4>
<ul>
<li><code>eventHandler</code> (function|object): A callback function, to be called when the checkbox grid is clicked. An <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventListener">eventListener interface object</a> is also valid.</li>
</ul>
<p>When called, the <code>eventHandler</code> is passed a <code>data</code> object, as defined below:</p>
<ul>
<li><code>data</code> (object): An object containing data about the click. Its properties include the following:</li>
<ul>
<li><code>x</code> (number): The x-coordinate of the checkbox that was clicked.</li>
<li><code>y</code> (number): The y-coordinate of the checkbox that was clicked.</li>
<li><code>checkbox</code> (HTMLInputElement): The DOM object representing the checkbox that was clicked.</li>
</ul>
</ul>
<h4 id="onclick-returns">Returns</h4>
<p>Nothing</p>
<h4 id="onclick-clean-up">Clean up</h4>
<p>To remove the <code>onClick</code> event listener from your checkbox grid, call the <code>cleanUp</code> method:</p>
<pre><code>.onClick.cleanUp()</code></pre>
<h2>Using Plugins</h2>
<p>Checkboxland supports plugins, which extend the API and provide higher-level functionality.</p>
<p>Here's a (realistic, but fake) example on how use a plugin to extend Checkboxland:</p>
<pre><code class="js language-js">import { Checkboxland } from 'checkboxland';
import mirrorPlugin from 'checkboxland-mirror';
Checkboxland.extend(mirrorPlugin);
const cbl = new Checkboxland();
// Mirror the data on the grid
cbl.mirror();</code></pre>
<p>You can see <a href="https://github.com/bryanbraun/checkboxland/blob/main/src/index.js">more examples of plugins being used in Checkboxland's core files</a>.</p>
<h3>Existing Plugins</h3>
<p><em>(if you write a 3rd-party plugin for Checkboxland, I'll list it here)</em></p>
<h2>Creating a Plugin</h2>
<p>Checkboxland plugins are just JavaScript functions that get special access to Checkboxland data.</p>
<p>Plugins can access all of Checkboxland's properties and <a href="">low-level API methods</a> on the <code>this</code> object. This includes:</p>
<ul>
<li><code>this.displayEl</code> (object) - The stored DOM element for the checkbox grid</li>
<li><code>this.dimensions</code> (array) - The dimensions of the checkbox grid, formatted like <code>[x, y]</code></li>
<li><code>this.getCheckboxValue()</code> (function) - <a href="#getCheckboxValue">See getCheckboxValue()</a></li>
<li><code>this.setCheckboxValue()</code> (function) - <a href="#setCheckboxValue">See setCheckboxValue()</a></li>
<li><code>this.getData()</code> (function) - <a href="#getData">See getData()</a></li>
<li><code>this.setData()</code> (function) - <a href="#setData">See setData()</a></li>
<li><code>this.clearData()</code> (function) - <a href="#clearData">See clearData()</a></li>
<li><code>this.getEmptyMatrix()</code> (function) - <a href="#getemptymatrix">See getEmptyMatrix()</a></li>
</ul>
<p><em>Note: do not access Checkboxland's internal <code>this._data</code> object directly. Instead, use <code>this.getData()</code> and <code>this.setData()</code>.</em></p>
<h3 id="an-example-plugin">An Example</h3>
<p>Here's an example of a plugin that logs various pieces of data to the JavaScript console:</p>
<pre><code class="js language-js">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'</code></pre>
<p>For more plugin examples, see <a href="https://github.com/bryanbraun/checkboxland/tree/main/src/plugins">these plugins built into Checkboxland</a>.</p>
<hr />
<div class="rc-text">
<a href="http://www.recurse.com" title="Made with love at the Recurse Center">
<span>Made with</span>
<i class="icon-svg">
<svg viewBox="0 0 511.626 511.627">
<path
d="M475.366,71.951c-24.175-23.606-57.575-35.404-100.215-35.404c-11.8,0-23.843,2.046-36.117,6.136 c-12.279,4.093-23.702,9.615-34.256,16.562c-10.568,6.945-19.65,13.467-27.269,19.556c-7.61,6.091-14.845,12.564-21.696,19.414 c-6.854-6.85-14.087-13.323-21.698-19.414c-7.616-6.089-16.702-12.607-27.268-19.556c-10.564-6.95-21.985-12.468-34.261-16.562 c-12.275-4.089-24.316-6.136-36.116-6.136c-42.637,0-76.039,11.801-100.211,35.404C12.087,95.552,0,128.288,0,170.162 c0,12.753,2.24,25.889,6.711,39.398c4.471,13.514,9.566,25.031,15.275,34.546c5.708,9.514,12.181,18.796,19.414,27.837 c7.233,9.042,12.519,15.27,15.846,18.699c3.33,3.422,5.948,5.899,7.851,7.419L243.25,469.937c3.427,3.429,7.614,5.144,12.562,5.144 s9.138-1.715,12.563-5.137l177.87-171.307c43.588-43.583,65.38-86.41,65.38-128.475C511.626,128.288,499.537,95.552,475.366,71.951 z">
</path>
</svg>
</i>
<span> at the </span><span class="green">Recurse Center</span>
</a>
</div>
</main>
</div>
<a href="https://github.com/bryanbraun/checkboxland" class="github-corner" aria-label="View source on GitHub">
<svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" class="octo-arm"></path>
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
</svg>
</a>
<script src="docs/js/vendor/anchor.min.js"></script>
<script type="module" src="docs/js/index.js"></script>
<script>
console.log(' ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ');
console.log('✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓');
console.log('✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓');
console.log('✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓');
console.log('✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓');
console.log('✓ ✓ ✓ ✓ ✓ ✓ ✓');
console.log('✓ ✓ ✓ ✓ ✓ ✓');
console.log('✓ ✓ ✓ ✓ ✓ ✓ ✓');
console.log('✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓');
console.log(' ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ');
</script>
</body>
</html>