render_ipycanvas

render_ipycanvas class

Reactively render an ipycanvas canvas.

Usage Source

render_ipycanvas(
    _fn: Optional[ValueFn[ValueT]] = None,
    *,
    width: Optional[str] = None,
    height: Optional[str] = None,
    fill: Optional[bool] = None,
    fillable: Optional[bool] = None,
    rate_policy: Optional[RatePolicy] = None,
    rate_delay: Optional[float] = None,
)

@render_ipycanvas is a decorator that creates a render function – a function that returns the canvas to display and re-runs when the reactive values it reads change:

from ipycanvas import Canvas

from shinywidgets import render_ipycanvas


@render_ipycanvas
def canvas():
    c = Canvas(width=300, height=200)
    c.fill_style = "steelblue"
    c.fill_rect(20, 20, 100, 100)
    return c

The render function may return an ipycanvas.Canvas, ipycanvas.MultiCanvas, ipycanvas.RoughCanvas, or ipycanvas.MultiRoughCanvas widget (requires pip install 'shinywidgets[ipycanvas]'). The canvas keeps its pixel width/height (which are drawing-buffer sizes, not layout sizes): in a filling layout the output fills its container and the canvas is centered within it (shrinking to fit, aspect preserved), never stretched. Size the canvas through the constructor’s width/height, not widget.layout.height – a Layout height opts out of filling, and since the buffer pixels are fixed, the browser can only rescale the existing bitmap to fit.

Note

Accessing the rendered widget: the render function gains two read-only attributes: .value and .widget, both the rendered canvas.

Responding to user interaction: read widget state reactively with reactive_read() on .widget, or register event callbacks like on_mouse_down()/on_mouse_move() that set reactive.values.

Mutating the widget: draw on .widget from anywhere (e.g., a reactive.effect or an asyncio task) and the browser canvas updates in place. With shiny < 1.9, canvas updates made from a background task may not reach the browser until the next input event. Note that ipycanvas.hold_canvas() has no effect under shinywidgets (each draw command is sent individually).

Parameters

width : Optional[str] = None

A CSS length unit (e.g., "400px" or "100%") for the output’s width.

height : Optional[str] = None

A CSS length unit for the output’s height. When None (the default), the output is designed to fill the height of its parent container (see fill and fillable).

fill : Optional[bool] = None

Whether the output should grow or shrink to fit its parent container. When None (the default), this is True if height is not specified.

fillable : Optional[bool] = None

Whether the output container should fill available space (scrolling its contents on overflow). When None (the default), this is True if height is not specified.

Examples

from ipycanvas import Canvas
from shiny import App, ui
from shinywidgets import output_widget, render_ipycanvas

app_ui = ui.page_fluid(output_widget("canvas"))


def server(input, output, session):
    @render_ipycanvas
    def canvas():
        c = Canvas(width=300, height=200)
        c.fill_style = "steelblue"
        c.fill_rect(20, 20, 100, 100)
        return c


app = App(app_ui, server)

See also

output_widget(): in Shiny Core, the UI needs this to hold the output (Shiny Express displays it where the render function is defined).