#simulator #graphics #embedded #no-std

no-std embedded-graphics-web-simulator

A web simulator using rust-embedded library with wasm

4 releases (2 breaking)

0.3.0 Jan 10, 2022
0.2.1 Nov 21, 2021
0.1.2 Apr 1, 2020
0.1.1 Mar 31, 2020

#533 in WebAssembly

31 downloads per month


161 lines

Embedded Graphics Web Simulator

The web simulator is based on embedded-graphics-simulator. This is a sample project demonstrating using a no_std rust-embedded library with Webassembly.

The Web Simulator allows you to use a browser to test embedded-graphics code and run graphics. There is no need to install SDL and its development libraries for running the project. You can see the demo here.

For Development

This library is intended to be used in Rust + Webassembly projects. Check the examples which illustrate how to use the library. Look at the examples in the Embedded Graphics Simulator project for inspiration. You can use wasm-pack to create a ready to go project and add this library as a dependency.

Usage example:

use embedded_graphics_web_simulator::{
    display::WebSimulatorDisplay, output_settings::OutputSettingsBuilder,
use wasm_bindgen::prelude::*;
use web_sys::console;

use embedded_graphics::{
    mono_font::{ascii::FONT_6X9, MonoTextStyle},
    prelude::{Point, Primitive, WebColors},
    primitives::{Circle, PrimitiveStyle},

use tinybmp::Bmp;

// When the `wee_alloc` feature is enabled, this uses `wee_alloc` as the global
// allocator.
// If you don't want to use `wee_alloc`, you can safely delete this.
#[cfg(feature = "wee_alloc")]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

// This is like the `main` function, except for JavaScript.
pub fn main_js() -> Result<(), JsValue> {
    // This provides better error messages in debug mode.
    // It's disabled in release mode so it doesn't bloat up the file size.

    let document = web_sys::window().unwrap().document().unwrap();

    let output_settings = OutputSettingsBuilder::new()
    let mut text_display = WebSimulatorDisplay::new((128, 64), &output_settings, None);
    let mut img_display = WebSimulatorDisplay::new(
        (128, 128),

    let style = MonoTextStyle::new(&FONT_6X9, Rgb565::CSS_WHITE);

    if Text::new("Hello, wasm world!", Point::new(10, 30), style)
        .draw(&mut text_display)
        console::log_1(&"Couldn't draw text".into());

    // Load the BMP image
    let bmp = Bmp::from_slice(include_bytes!("./assets/rust-pride.bmp")).unwrap();
    let image = Image::new(&bmp, Point::new(32, 32));
    if image.draw(&mut img_display).is_err() {
        console::log_1(&"Couldn't draw image".into());

    if Circle::new(Point::new(29, 29), 70)
        .into_styled(PrimitiveStyle::with_stroke(Rgb565::CSS_WHITE, 1))
        .draw(&mut img_display)
        console::log_1(&"Couldn't draw circle".into());

    img_display.flush().expect("Couldn't update");

How it works

Embedded Graphics Web Simulator implements DrawTarget for the HTML <canvas> element. It will attach a <canvas> either to the document body, or to a user-supplied parent element. To minimize overhead, draw operations need to be explicitly flush()ed whenver you want to see an actual update.


This project is based on the embedded-graphics library, originally by @jamwaffles

Built with wasm-pack

Thanks to all contributors :)


~203K SLoC