{"id":20333330,"url":"https://github.com/daneelsan/minimal-zig-wasm-canvas","last_synced_at":"2025-04-11T21:33:36.533Z","repository":{"id":41143878,"uuid":"481456540","full_name":"daneelsan/minimal-zig-wasm-canvas","owner":"daneelsan","description":"A minimal example showing how HTML5's canvas, wasm memory and zig can interact.","archived":false,"fork":false,"pushed_at":"2024-02-03T02:36:55.000Z","size":285,"stargazers_count":112,"open_issues_count":4,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-25T17:46:58.349Z","etag":null,"topics":["html5-canvas","javascript","wasm","webassembly","zig"],"latest_commit_sha":null,"homepage":"","language":"Zig","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/daneelsan.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-14T03:45:38.000Z","updated_at":"2025-02-26T12:10:45.000Z","dependencies_parsed_at":"2024-02-03T03:36:58.711Z","dependency_job_id":null,"html_url":"https://github.com/daneelsan/minimal-zig-wasm-canvas","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Fminimal-zig-wasm-canvas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Fminimal-zig-wasm-canvas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Fminimal-zig-wasm-canvas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneelsan%2Fminimal-zig-wasm-canvas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daneelsan","download_url":"https://codeload.github.com/daneelsan/minimal-zig-wasm-canvas/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248483456,"owners_count":21111455,"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":["html5-canvas","javascript","wasm","webassembly","zig"],"created_at":"2024-11-14T20:30:49.789Z","updated_at":"2025-04-11T21:33:36.505Z","avatar_url":"https://github.com/daneelsan.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Minimal zig-wasm-canvas example\n\nA minimal example showing how HTML5's canvas, wasm memory and zig can interact.\n\nhttps://daneelsan.github.io/minimal-zig-wasm-canvas/\n\n![checkerboard](./checkerboard.gif)\n\nThis example was mostly adapted from: https://wasmbyexample.dev/examples/reading-and-writing-graphics/reading-and-writing-graphics.rust.en-us.html. The difference (aside from using Zig instead of Rust), is that this example\ndoes not depend on any external package, library or extra bindings. As with most Zig related projects, the `zig` command is everything you will need.\n\n## Summary\n\n`checkerboard.zig` defines a global 8 by 8 pixel array: `checkerboard_buffer`.\nThere are two functions exported: `getCheckerboardBufferPointer()` and `colorCheckerboard(...)`.\n`getCheckerboardBufferPointer()` returns a pointer to the start of `checkerboard_buffer`, which will be used inside `script.js` (described later). The other function, `colorCheckerboard(...)`, is in charge of (re-)coloring the different squares in the checkerboard according to colors passed down by `script.js`.\n\n`checkerboard.zig` is compiled into the wasm module `checkerboard.wasm` by `build.zig` (see the [Build Section](#build)).\n\n`script.js` first creates a [WebAssembly.Memory](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory), named `memory`, which will be used by the wasm module's memory. Next step is to compile and instantiate the fetched wasm module using [WebAssembly.instantiateStreaming()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming). The returned object is a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which contains the `instance` field ([WebAssembly.Instance](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance)). This is where all the exported symbols from `checkerboard.wasm` will be stored.\n\nWhat follows is mostly straightforward:\n\n-   Create a _Uint8Array_ from the WebAssembly.Memory `memory` buffer, called `wasmMemoryArray`.\n-   Get the `\"checkerboard\"` canvas defined in `index.html` and create an [ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) object from the canvas' context, called `imageData`.\n-   In a loop:\n    -   Call `colorCheckerboard(...)`, passing down random RGB colors. This will modify the values inside `checkerboard_buffer`.\n    -   Extract the contents of the `checkerboard_buffer`, which is an slice of `wasmMemoryArray` offseted by `getCheckerboardBufferPointer()` and of length `8 * 8 * 4` (bytes).\n    -   Copy the contents of the previous slice, i.e. the contents of `checkerboard_buffer`, into the `imageData`'s data.\n    -   Put the `imageData` into the canvas.\n\n## Build\n\nThe default (and only) target for this example is `wasm32-freestanding-musl`.\n\nThe latest zig version used to build this project is:\n```shell\n$ zig version\n0.12.0-dev.2341+92211135f\n```\n\nTo build the wasm module, run:\n\n```shell\n$ zig build\n\n$ ls zig-out/lib/ checkerboard.*\ncheckerboard.wasm\n\n$ wc -c zig-out/bin/checkerboard.wasm \n580 zig-out/bin/checkerboard.wasm\n```\n\nNote: `build.zig` specifies various wasm-ld parameters. For example, it sets the initial memory size\nand maximum size to be 2 pages, where each page consists of 64kB. Use the `--verbose` flag to see the complete list of flags the build uses.\n\n## Run\n\nStart up the server in this repository's directory:\n\n```shell\npython3 -m http.server\n```\n\nGo to your favorite browser and type to the URL `localhost:8000`. You should see the checkboard changing colors.\n\n## Resources\n\n-   https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API\n-   https://github.com/ern0/howto-wasm-minimal\n-   https://wasmbyexample.dev/examples/reading-and-writing-graphics/reading-and-writing-graphics.rust.en-us.html\n-   https://radu-matei.com/blog/practical-guide-to-wasm-memory/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaneelsan%2Fminimal-zig-wasm-canvas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaneelsan%2Fminimal-zig-wasm-canvas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaneelsan%2Fminimal-zig-wasm-canvas/lists"}