{"id":15369820,"url":"https://github.com/electrovir/ws2812draw","last_synced_at":"2025-04-15T13:51:54.414Z","repository":{"id":42481101,"uuid":"227953063","full_name":"electrovir/ws2812draw","owner":"electrovir","description":"Easy to use package for drawing to a ws2812 LED matrix","archived":false,"fork":false,"pushed_at":"2022-04-04T01:03:53.000Z","size":578,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-16T03:12:38.951Z","etag":null,"topics":["draw","led","matrix","raspberry-pi","ws2812"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/ws2812draw","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/electrovir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-14T02:10:10.000Z","updated_at":"2022-11-19T06:21:35.000Z","dependencies_parsed_at":"2022-09-12T18:00:43.422Z","dependency_job_id":null,"html_url":"https://github.com/electrovir/ws2812draw","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Fws2812draw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Fws2812draw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Fws2812draw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/electrovir%2Fws2812draw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/electrovir","download_url":"https://codeload.github.com/electrovir/ws2812draw/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240300058,"owners_count":19779554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["draw","led","matrix","raspberry-pi","ws2812"],"created_at":"2024-10-01T13:38:51.765Z","updated_at":"2025-02-27T18:30:59.687Z","avatar_url":"https://github.com/electrovir.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WS2812 Draw\n\nDraw to a ws2812 LED matrix ([like this one](https://www.amazon.com/dp/B01DC0IPVU)) with a Raspberry Pi. Uses the C library [rpi_ws281x](https://github.com/jgarff/rpi_ws281x).\n\nTested on a [Raspberry Pi 4 model b](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/).\n\n# Install\n\n```\nnpm install ws2812draw\n```\n\n# Hardware Setup\n\nOn a fresh install of Raspian Pi OS on a Raspberry Pi, no software setup is required beyond installing Node.js and running `npm install` in this directory.\n\nHardware wise, this uses [Pin 12 aka BCM 18](https://pinout.xyz/pinout/pin12_gpio18) for the LED matrix's data line. Further explanations for which GPIO pins _can_ be used at the C library level are contained in the [rpi_ws281x library's README](https://github.com/jgarff/rpi_ws281x#gpio-usage). However, this package currently doesn't interface with that since I found it works easiest to just leave it on the default (`BCM 18`).\n\nI found that my 32x8 LED matrix can be fully driven at _very high brightness_ by the Raspberry Pi's 5v power pin: No external power supply is needed for the LEDs.\n\n# Quick test\n\n1. Clone this repo\n2. CD to it\n3. run `npm install`\n4. run `npm run example`\n\n# Sudo\n\nRoot access is required to access the Raspberry Pi's lower levels and draw to the matrix.\n\nWhen running your scripts, you can prefix your commands with `sudo -E env \"PATH=$PATH\"` so you don't need to install Node.js inside your root user.\n\nExample:\n\n```bash\nsudo -E env \\\"PATH=$PATH\\\" node dist/tests/example-simple.js\n```\n\n# API\n\nSee [`index.ts`](https://github.com/electrovir/ws2812draw/blob/master/src/index.ts) for exported members.\n\n## Draw Still Image\n\nPass in a 2D array of colors to `drawStill`. This function has _relatively_ poor performance if drawing many frames in succession. Poor performance here means about 60 fps on a 8x32 LED matrix (bigger matrices quickly drop off). However, this method should be preferred for its ease of use for still images that doesn't change rapidly.\n\n\u003c!-- example-link: src/readme-examples/draw-still.example.ts --\u003e\n\n```TypeScript\nimport {drawStillImage, LedColor} from 'ws2812draw';\n\n// must be between 0 and 255 inclusive\nconst brightness: number = 100;\nconst imageMatrix: LedColor[][] = [\n    [\n        LedColor.Black,\n        LedColor.Red,\n        LedColor.Orange,\n    ],\n    [\n        LedColor.Black,\n        LedColor.Red,\n        LedColor.Orange,\n    ],\n];\n\ndrawStillImage({brightness, imageMatrix});\n```\n\nNote that on my 8x32 LED matrix this example above doesn't draw as a rectangle, it draws in a line. This is because the array height doesn't match up correctly with the LED matrix height.\n\n### Drawing a Scrolling Image\n\nDraws an image that can be wider (or thinner) than the actual LED display. It then scrolls the image across the LED matrix. This function returns an `EventEmitter` which can be used to detect when the scrolling is done or to instruct the scrolling to stop.\n\n\u003c!-- example-link: src/readme-examples/draw-scrolling-image.example.ts --\u003e\n\n```TypeScript\nimport {drawScrollingImage, LedColor, MatrixPaddingOption} from 'ws2812draw';\n\n// without options\ndrawScrollingImage({\n    width: 32,\n    brightness: 50,\n    imageMatrix: [\n        [\n            LedColor.Black,\n            LedColor.Red,\n            LedColor.Orange,\n        ],\n        [\n            LedColor.Black,\n            LedColor.Red,\n            LedColor.Orange,\n        ],\n    ],\n});\n\nconst emitter = drawScrollingImage({\n    width: 32,\n    brightness: 50,\n    imageMatrix: [\n        [\n            LedColor.Black,\n            LedColor.Red,\n            LedColor.Orange,\n        ],\n        [\n            LedColor.Black,\n            LedColor.Red,\n            LedColor.Orange,\n        ],\n    ],\n    // the options input is optional\n    scrollOptions: {\n        loopCount: -1,\n        frameDelayMs: 100,\n        loopDelayMs: 0,\n        padding: MatrixPaddingOption.Left,\n        padBackgroundColor: LedColor.Black,\n        emptyFrameBetweenLoops: false,\n        scrollDirection: 'left',\n    },\n});\n\nemitter.on('loop', (loopCount) =\u003e {\n    console.log(`Loop ${loopCount} finished!`);\n});\n\nsetTimeout(() =\u003e {\n    emitter.emit('stop'); // do this to instantly stop the scrolling\n}, 5000);\n```\n\n## Draw Text\n\nDraws text. All text is converted into uppercase. Supports a-z and 0-9, in addition to some special characters and punctuation. Options passed in can be an array for each individual character or a single option for the whole string.\n\n\u003c!-- example-link: src/readme-examples/draw-text.example.ts --\u003e\n\n```TypeScript\nimport {drawText, LedColor, MatrixPaddingOption} from 'ws2812draw';\n// options are optional\n\n// without options\ndrawText({brightness: 50, text: 'Hi!'});\n\n// with options\ndrawText({\n    brightness: 50,\n    text: 'Hi!',\n    letterOptions: {\n        foregroundColor: LedColor.Red,\n        backgroundColor: LedColor.Blue,\n        monospace: false,\n    },\n});\n\n// with alignment options\ndrawText({\n    brightness: 50,\n    text: 'Hi!',\n    letterOptions: {\n        foregroundColor: LedColor.Red,\n        backgroundColor: LedColor.Blue,\n    },\n    alignmentOptions: {\n        width: 32,\n        padding: MatrixPaddingOption.Left,\n        padColor: LedColor.Blue,\n    },\n});\n```\n\n### Supported characters\n\nTo get a full list of supported string characters use the following function:\n\n\u003c!-- example-link: src/readme-examples/get-supported-characters.example.ts --\u003e\n\n```TypeScript\nimport {getSupportedLetters} from 'ws2812draw';\n\nconsole.log(getSupportedLetters());\n```\n\n### Registering characters\n\nTo register your own custom characters along with a matrix mask for that character, use the following function. The matrix mask must be 8 elements in height and 2-6 (inclusive) elements wide.\n\nExample:\n\n\u003c!-- example-link: src/readme-examples/register-custom-letter.example.ts --\u003e\n\n```TypeScript\nimport {registerCustomLetter} from 'ws2812draw';\n\nregisterCustomLetter('\u003c', [\n    // prettier-multiline-arrays-set-threshold: 8\n    [0, 0, 0, 1, 1],\n    [0, 0, 1, 1, 0],\n    [0, 1, 1, 0, 0],\n    [1, 1, 0, 0, 0],\n    [1, 1, 0, 0, 0],\n    [0, 1, 1, 0, 0],\n    [0, 0, 1, 1, 0],\n    [0, 0, 0, 1, 1],\n]);\n```\n\nThis function can also be used to override any default character masks. (For example, registering a custom letter to `'a'` will override the mask for the letter `a`.)\n\n### Draw Scrolling Text\n\nThe draw text function above isn't smart at all about a string being wider than the actual display; it just draws the text and whatever fits is what you see. The following function will scroll a string of text with speed control and other configuration options.\n\n`letterOptions` is the same as in the `drawText` function explained above. `scrollOptions` is the same as in the `drawScrollingImage` function explained further above.\n\nExample:\n\n\u003c!-- example-link: src/readme-examples/draw-scrolling-text.example.ts --\u003e\n\n```TypeScript\nimport {drawScrollingText} from 'ws2812draw';\n\ndrawScrollingText({\n    brightness: 100,\n    text: 'Hello world!',\n    width: 32,\n});\n```\n\n## High Performance Drawing\n\n`drawStillImage` has relatively low performance because it re-initializes the LED board on every call. For high performance drawing, manually initialize the board and then call `drawFrame` as many times as desired afterwards.\n\n### Initialize the LED board once\n\n\u003c!-- example-link: src/readme-examples/init-board.example.ts --\u003e\n\n```TypeScript\nimport {initLedBoard} from 'ws2812draw';\n\ninitLedBoard({\n    brightness: 100,\n    dimensions: {\n        width: 32,\n        height: 8,\n    },\n});\n```\n\nMake sure to call `cleanUp`, as explained in a later section, when done drawing.\n\n### Draw a frame\n\nThis can be run within a loop for high frame rates. I'm getting nearly 100 fps (vs `drawStillImage`'s 60 fps) on a 8x32 board. Larger boards will have lower frame rates.\n\nAny rows or cells beyond than the initialized dimensions previously given to `initLedBoard` are ignored. Fewer rows or cells will result in a messed up drawing.\n\nExample:\n\n\u003c!-- example-link: src/readme-examples/draw-frame.example.ts --\u003e\n\n```TypeScript\nimport {drawFrame, LedColor} from 'ws2812draw';\n\ndrawFrame([\n    [\n        LedColor.Black,\n        LedColor.Red,\n        LedColor.Orange,\n    ],\n    [\n        LedColor.Black,\n        LedColor.Red,\n        LedColor.Orange,\n    ],\n]);\n```\n\n### Clean up\n\n\u003c!-- example-link: src/readme-examples/clean-up.example.ts --\u003e\n\n```TypeScript\nimport {cleanUp} from 'ws2812draw';\n\ncleanUp();\n```\n\nAfter `drawFrame` is done being used, run this to free up memory.\n\n## Colors\n\nColors are stored in hex so they're easier to read. See the [`LedColor` enum](https://github.com/electrovir/ws2812draw/blob/master/src/color.ts) for defaults. For custom colors, use the following format with blue, green, and red channels:\n\n```\n0xBBGGRR\n```\n\nNote that drawing `0xFFFFFF` will be a _very_ bright white. For comparison, the default white color is only `0x0c0c0c`. You'll need to experiment with custom colors to calibrate their brightnesses with each other. The `LedColor` enum has been calibrated to provide colors that are all nearly the same in brightness.\n\n# Running tests\n\n## Examples\n\nThere are several smaller example scripts to showcase and test the LED board's functionality. Each script will ask for sudo permissions as they are required to access the LED board.\n\n-   `npm run example`\n-   `npm run example:simple`\n-   `npm run example:text`\n\n## Full tests\n\n```bash\n# this will ask you for your password in order to use sudo\nnpm test [test-index]\n```\n\nIf no test-index is given, all the tests will run. This takes several minutes, must run with a LED display attached in order for anything to happen, and must be inspected manually.\n\n# Speed stats\n\n-   WxH: average fps with zero delay between drawFrame calls (using `npm run example`)\n-   32x8: ~100 fps\n-   64x8: ~50 fps\n-   96x8: ~33 fps\n\nAs you can see, the framerate is directly related to the number of LEDs which the board is cycling through.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felectrovir%2Fws2812draw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felectrovir%2Fws2812draw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felectrovir%2Fws2812draw/lists"}