Closed ghost closed 3 years ago
Hello!
It would indeed be really nice. I made a small attempt for fast animations on the following PR: https://github.com/martinRenou/ipycanvas/pull/75.
It's basically transpiling the Python code into JavaScript code in order to execute it on the page in a very fast manner (no communication between back-end and fron-end involved during the animation). I am unsure if this implementation will integrate well with the current way of doing things in ipycanvas. There might be some difficult corner cases concerning canvas state... Anyway, it's just a POC and not usable right now (although feel free to give it a try locally).
you have the infrastructure to handle callback from canvas events
Using events might still be slow (you still rely on the communication between back-end and front-end).
Concerning your specific animation. You might be able to speed it up by using the MultiCanvas
(see the documentation for its usage). Because you only have the earth and sun that move right? The background does not seem to change much. Also I see you import hold_canvas
but don't use it, I highly recommend using it, it will speed up you animation even more ;)
for i in range(200):
with hold_canvas(ctx):
draw()
time.sleep(0.03)
Yes, hold_canvas
changed everything. Thanks
Transpiling python seems a project on it's own, perhaps not what an ipycanvas user expects from this library. I choose it today because of it's simplicity. Having the Canvas API + a lot of JS example is a big advantage.
Btw, I upvote the snake case to camel case conversion. All the examples on the net about Canvas are of course in camel case javascript
Transpiling python seems a project on it's own, perhaps not what an ipycanvas user expects from this library
The idea would be to make it transparent to users though. But agreed, simple is better. I am not 100% sure I want to finish this PR anyway.
Btw, I upvote the snake case to camel case conversion. All the examples on the net about Canvas are of course in camel case javascript
I disagree. I understand the point that examples out there are written in JavaScript (although I already wrote a few Notebook examples so it should be enough for starting playing with it), but this is a Python library and I want to respect the PEP as much as possible.
Note that the example in the fast animation PR is written in Camel case simply because I did not have time to write the translation between Python API to JavaScript API in the transpiler.
Closing for triage, please reopen it if needed
Hi Martin, could we reopen this issue?
If you execute the following with the jupyter-server and client on the same machine, it animates 'fairly smooth'. But it's not very smooth. I guess the main thing that prevents the smoothness is the different timings of the monitor refresh (when the browser updates the pixels) and the python sleep (or interpreter fwiw). A callback from requestAnimationFrame and drawing in python (just calling draw) could remove this timing jitter I think.
Any ideas?
from time import sleep
from ipycanvas import Canvas, hold_canvas
canvas = Canvas(width=512, height=512)
display(canvas)
def draw():
with hold_canvas():
canvas.fill_style = 'white'
canvas.fill_rect(t,t,10,10)
canvas.fill_style = 'black'
canvas.fill_rect(t+1,t+1,10,10)
t=0
while True:
draw()
t = (t+1)%512
sleep(1/60.)
Oh, and, many thanks already :) This really is a very nice way for to draw onto a canvas from Python!
A callback from requestAnimationFrame and drawing in python (just calling draw) could remove this timing jitter I think.
I'm honestly not entirely sure that's a good idea. It might not change the performance. And this design would not work at all in the case of multiple clients.
You might want to try to reduce the number of draw calls you're making.
Hi Martin, nice job your ipycanvas.
I quickly simplified and ported this codepen to a python notebook. The resulting animation flickers, because from the nb there is no way, afaik, to have the
draw()
function called by the browser'srequestAnimationFrame
Any suggestion on how to implement it? In
src/widget.ts
andipycanvas/canvas.py
you have the infrastructure to handle callback from canvas events. It seems a good place to start.Anyway I'm doing some test. I'd appreciate if you could describe how to build ipycanvas in local
This is the ported code: