Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Canvas

WaterUI does not yet ship a first-party immediate-mode canvas, but you can integrate custom renderers today using the same primitives the framework uses internally (Native, Metadata, and platform hooks). This chapter outlines the approach so you can render charts, maps, or drawing surfaces until the dedicated waterui_canvas crate lands.

Wrap a Native View

Backends expose a Native<T> view that hands control to the renderer. Create a minimal wrapper that stores your model and drive it with reactive bindings:

#![allow(unused)]
fn main() {
use waterui::prelude::*;
use waterui::reactive::binding;
use waterui::widget::suspense::Suspense;
use waterui_core::{Environment, Native, View};
use waterui::Binding;

pub struct Chart {
    pub points: Vec<(f32, f32)>,
}

impl View for Chart {
    fn body(self, _env: &Environment) -> impl View {
        Native(self)
    }
}

async fn stream_points(points: Binding<Vec<(f32, f32)>>) -> impl View {
    // Replace with actual async updates (WebSocket, sensor data, etc.)
    Chart { points: points.get() }
}

pub fn realtime_chart() -> impl View {
    let points = binding(vec![(0.0, 0.0)]);
    Suspense::new(stream_points(points.clone()));
    Chart { points: points.get() }
}
}

Each backend implements the trait that turns Native<Chart> into the appropriate drawing surface (SwiftUI Canvas, HTML <canvas>, GTK4 DrawingArea, etc.). The binding keeps the view reactive, and Suspense handles asynchronous updates.

Pointer Input

Combine GestureObserver with your native view to capture pointer coordinates, then forward them to the backing renderer via bindings or environment services.

Looking Ahead

The upcoming waterui_canvas crate will package these patterns with a cross-platform immediate-mode API (paths, fills, gradients) plus hit-testing utilities. Until then, native wrappers provide a bridge for teams that need advanced drawing today.