Skip to content

Coding the Tree pt. 1 (simple)

Diamond edited this page Dec 4, 2023 · 7 revisions

This is the page to read if you're participating in or planning to participate in the Blinking Lights event.

Important

This guide assumes you're writing JavaScript. The Python library will look somewhat similar. Refer to the christmas-py-example repository for more information.

Note

In order to keep things simple, this page will only be covering how to interact with the tree using images. For how to interact with the LEDs themselves, see Coding the Tree pt. 2 (advanced).

Quick Start

The recommended way to interact with christmasd for beginners is to use either the JavaScript client library or the Python client library supplied prior to the event:

You may see examples of how they're used here:

Important

You must follow the instructions listed in each repository's README page!

Basics

First, a program must establish a connection to the Websocket server. For testing, you may head to blinktest.acmcsuf.com to obtain a simulator session that will contain a Websocket URL for experimenting. See Testing for more information.

We'll assume this Websocket URL is in a url variable:

const url = "wss://..."; // may also be "ws://..."

christmas-js-example exposes an LEDCanvas type that contains these methods in the order of operation:

  1. connect() starts the connection to the server.
  2. canvasInfo() gets the dimensions of the drawing canvas from the server. Images sent to the server must be in this size (but not always, see below!)
  3. draw() sends the given image to the server to be drawn.

A bare minimum program may look like so:

import { LEDCanvas } from "christmas-client-js";

const canvas = new LEDCanvas("ws://...");
await canvas.connect();
const canvasInfo = await canvas.canvasInfo();
canvas.draw(canvasInfo, image);

Loading an Image

christmas-js-example provides first-class support for the image.js library. If canvas.draw is given an image created using this library, it will automatically rescale the image to the needed size, so if you're using this library, you won't need to worry about sizing the images. Of course, the library may not rescale the image properly, in which you'll have to do the rescaling yourself.

As an example, loading an image using image.js and drawing it is very straightforward:

import * as imagejs from "image-js";

const image = await imagejs.Image.load("path-to-image.jpg");
canvas.draw(canvasInfo, image);

Note

We need to give draw() the canvasInfo that we fetched above. This is to let draw() know how to rescale the image. You must always pass it this parameter.

Tip

Have a GIF? You can use ezgif.com/split to split your GIFs into individual frames and load them all in a for loop. You may also choose to use a GIF library such as gif-frames to extract frames out of the GIF and display them without relying on other tools.

Example Snippet
const canvas = new LEDCanvas("ws://...");
await canvas.connect();

const canvasInfo = await canvas.canvasInfo();

const images = [];
for (let i = 0; i < 10; i++) {
  const frame = await imagejs.Image.load(`frame-${i}`);
  images.push(frame);
}

let frame = 0;
setInterval(() => {
  canvas.draw(canvasInfo, frame[i]);
  frame++;
  if (frame == images.length) {
    frame = 0;
  }
}, 100) // 100ms delay every frame => 10 fps

Testing

To test your code without having access to the physical tree, you may choose to head to blinktest.acmcsuf.com. Here, you will be greeted with a simple canvas containing all the LED points that the actual tree would have, as well as a text console containing the Websocket URL (starting with wss://).

Screenshot of the testing interface

To start testing, click the wss:// URL, which will copy it to your clipboard. Copy this into your url variable above and run your code. You will see the changes in real time.

Clone this wiki locally