Skip to content

Repository files navigation

pixels

A Rust desktop client and library for pixels, a collaborative, r/place-style pixel canvas built for a community event.

You can run the full GUI client to draw on the shared canvas, or pull in pixels-canvas as a plain library and script the canvas yourself with no window and no rendering, just the API.

preview

Features

  • Live canvas rendered with macroquad, auto-refreshing from the server every few seconds
  • Four tools: move/pan, brush (paint a pixel), color picker (sample a pixel), and image placer (stamp a local image)
  • egui side panel for color selection and tool switching, with a tooltip while you're on cooldown
  • Layered canvas where the live server layer and a translucent image-preview layer are composited via alpha blending
  • Server cooldown handled end-to-end, dimming the canvas and surfacing the remaining wait
  • Reusable core so the networking, color, and canvas logic live in dependency-light library crates

Workspace

The project is a Cargo workspace of three crates, layered bottom-up:

CrateKindPurpose
pixels-utillibraryCore primitives: Color (conversions, hex, alpha blend), the Pixels grid, and Cooldown
pixels-canvaslibraryCanvas, Layer, Element, and the HTTP Client that talks to the server
pixels-interfacebinaryThe GUI app: macroquad (render) + egui (panel) + bevy_ecs (systems)

Running the client

cargo run -p pixels-interface -- <refresh-token>

On launch you're asked whether to select a PNG/JPEG to paste onto the canvas; pick one to enable the image placer tool.

Controls

ActionInput
Move / panM, then drag
BrushB, then click
Pick colorI, then click
Place imageP, then click
Zoomscroll wheel

Using pixels-canvas as a library

pixels-canvas has no GUI dependencies. It authenticates, fetches the canvas, and sets pixels on its own. Add it as a path (or git) dependency and drive the canvas directly:

use pixels_canvas::prelude::*;use pixels_util::color::Color;fnmain() -> Result<(),CanvasError>{// Authenticates with your refresh token and pulls the current canvas.letmut canvas = Canvas::new(std::env::var("REFRESH_TOKEN").unwrap())?;println!("canvas is {}x{}", canvas.width(), canvas.height());// Read a pixel.ifletSome(color) = canvas.get_pixel(10,10){println!("pixel (10,10) = #{}", color.to_hex(ColorMode::RGB));}// Write a pixel (respects the server-side cooldown).match canvas.set_pixel(10,10,Color::from_rgb(255,0,0)){Ok(()) => println!("placed!"),Err(CanvasError::Cooldown(secs)) => println!("wait {secs}s"),Err(CanvasError::Client(e)) => eprintln!("request failed: {e}"),}// Refresh the local copy from the server.
canvas.update_main_layer()?;Ok(())}

Key entry points:

  • Canvas::new(refresh) authenticates and loads the canvas
  • Canvas::get_pixel / set_pixel read and write single pixels
  • Canvas::update_main_layer re-fetches the live canvas from the server
  • Canvas::get_layers_merged returns the composited canvas for rendering
  • Color / Pixels (from pixels-util) work with pixel data offline

Building

cargo build # all crates
cargo run -p pixels-interface -- <refresh-token>

License

See License.md.

About

some client stuff for a community event which is similar to r/place

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages