View notebook on Github Download

Interactive drawing example

A simple drawing app:

  • Draw dots by clicking with LMB.

  • Toggle color by clicking RMB.

[1]:
import numpy as np
import jupyter_rfb
[2]:
class Drawingapp(jupyter_rfb.RemoteFrameBuffer):
    def __init__(self):
        super().__init__()
        self.pixel_ratio = 1 / 8
        w, h = 600, 400
        self.css_width = f"{w}px"
        self.css_height = f"{h}px"
        self.resizable = False
        self.array = (
            np.ones((int(h * self.pixel_ratio), int(w * self.pixel_ratio), 4), np.uint8)
            * 5
        )
        self.pen_colors = [(1, 0.2, 0, 1), (0, 1, 0.2, 1), (0.2, 0, 1, 1)]
        self.pen_index = 0

    def handle_event(self, event):
        event_type = event["type"]
        if event_type == "pointer_down":
            if event["button"] == 1:
                # Draw
                x = int(event["x"] * self.pixel_ratio)
                y = int(event["y"] * self.pixel_ratio)
                self.array[y, x] = 255 * np.array(self.pen_colors[self.pen_index])
                self.request_draw()
            elif event["button"] == 2:
                # Toggle color
                self.pen_index = (self.pen_index + 1) % len(self.pen_colors)

    def get_frame(self):
        return self.array


app = Drawingapp()
app.display()
snapshot
[2]:
<__main__.Drawingapp object at 0x1092852b0>

After some clicking …

[3]:
# We can also generate some clicks programatically :)
for x, y in [
    (503, 37),
    (27, 182),
    (182, 383),
    (396, 235),
    (477, 151),
    (328, 308),
    (281, 16),
]:
    app.handle_event({"type": "pointer_down", "button": 1, "x": x, "y": y})
app.handle_event({"type": "pointer_down", "button": 2, "x": 0, "y": 0})
for x, y in [
    (226, 115),
    (135, 253),
    (351, 220),
    (57, 11),
    (345, 87),
    (67, 175),
    (559, 227),
]:
    app.handle_event({"type": "pointer_down", "button": 1, "x": x, "y": y})
[4]:
app.snapshot()
[4]:
snapshot
[ ]: