from ipywidgets import Label, HTML, HBox, Image, VBox, Box, HBox
from ipyevents import Event 
from IPython.display import display
from time import sleep
from ipycanvas import Canvas, hold_canvas
import numpy as np

# Initialize a canvas and an html element to show event info
canvas = Canvas(width=800, height=500)   
h = HTML('Event info')

# Set up some random points to draw
x = np.array(np.random.rayleigh(250, 100))
y = np.array(np.random.rayleigh(250, 100))
size = np.random.randint(1, 3, 100)

# Event handling
d = Event(source=canvas, watched_events=['click']) # , 'keydown', 'mouseenter'
def handle_event(event):
    h.value = str(event['relativeX'])
d.on_dom_event(handle_event)

# Display the widgets
display(canvas, h)

# Animation loop
for i in range(200): # while(True) for infinite
    with hold_canvas(canvas):
        canvas.clear() # Clear the old animation step       
        canvas.fill_style = 'green' 
        canvas.fill_rects(x, y, size) # Draw the new frame 
        x += 1 # Update positions
    sleep(0.02) # Animation frequency ~50Hz = 1./50. seconds
from ipywidgets import Label, HTML, HBox, Image, VBox, Box, HBox
from ipyevents import Event 
from IPython.display import display
from time import sleep
from ipycanvas import Canvas, hold_canvas
import numpy as np

# Initialize a canvas and an html element to show event info
canvas = Canvas(width=800, height=500)   
h = HTML('Event info')

# Set up some random points to draw
x = np.array(np.random.rayleigh(250, 100))
y = np.array(np.random.rayleigh(250, 100))
size = np.random.randint(1, 3, 100)

# Event handling
d = Event(source=canvas, watched_events=['click']) # , 'keydown', 'mouseenter'
def handle_event(event):
    h.value = str(event['relativeX'])
d.on_dom_event(handle_event)

# Display the widgets
display(canvas, h)
from threading import Timer

class RepeatedTimer(object):
    def __init__(self, interval, function, *args, **kwargs):
        self._timer     = None
        self.interval   = interval
        self.function   = function
        self.args       = args
        self.kwargs     = kwargs
        self.is_running = False
        self.start()

    def _run(self):
        self.is_running = False
        self.start()
        self.function(*self.args, **self.kwargs)

    def start(self):
        if not self.is_running:
            self._timer = Timer(self.interval, self._run)
            self._timer.start()
            self.is_running = True

    def stop(self):
        self._timer.cancel()
        self.is_running = False
        
from time import sleep

def update():
    global x
    with hold_canvas(canvas):
        canvas.clear() # Clear the old animation step       
        canvas.fill_style = 'green' 
        canvas.fill_rects(x, y, size) # Draw the new frame 
        x += 1 # Update positions


rt = RepeatedTimer(0.02, update) # it auto-starts, no need of rt.start()    
rt.stop() # better in a try/finally block to make sure the program ends!