I’m trying to draw a picture in the server code and pass it to the client. I have zero problems to draw the picture in the client code by the below code. However, I have troubles to generate the same picture in the server code and pass it to the client. As I am completely new to Anvil I am probably missing rather basic things.
Looking forward for your guidance as I am trying to understand the concept of passing objects from server- to client code via this example better.
Thanks.
def form_show(self, **event_args):
"""This method is called when the column panel is shown on the screen"""
c=self.painting_canvas
c.fill_stayle='black'
c.begin_path()
c.move_to(0,0)
c.line_to(0,50)
c.line_to(50,50)
c.line_to(50,0)
c.close_path()
c.stroke()
Welcome to the Forum!
As I understand it, every Canvas object exists in a browser’s memory space.
The Server code runs on a completely different computer, across the network, so it does not have access to anything in the browser’s memory.
Even if a Server could create a Canvas, I am not aware of any way to send a copy of a Canvas across the wire, in either direction.
Could you tell us more about the problem you’re trying to solve? There are probably many other ways to solve it.
I am trying to recreate a sketch which is similar to a small technical drawing. Included in the drawing are just lines connected using xy coordinates, some arcs and annotations.
Previously I used in a non-Web-Python-Program Matplotlib for that purpose.
Although the calculations for that sketch are not really confidential, I’d prefer to generate the drawing in the Server (preferably in a loss less format like e.g. svg) and then view the result in the Client.
(as said before, I am completely new to Anvil and this is for me also part of the self tutoring process…)
Good news! Python library matplotlib is available Server-side. See a complete list of Server-importable libraries here:
So you may be able to use some of your existing code.
You can check the Tutorials and Examples for how to
- Use matplotlib to create an Image
- Pass that Image back to the browser for display.
If you want to create it on the server, you need to create a bitmap as suggested by @p.colbert and send it to the client. Then you can show it in an image component or in a canvas.
If you want to use a canvas (I definitely would!), you could have the server building a list of dictionaries, returning it to the client, and have the client draw the canvas. The list of dictionaries could be something like {'type': 'line', 'color': 1, 'x1': 10, 'y1': 20, 'x2':...}
. You could have a loop that interprets each dictionary and draws it, or, better, create a GraphicObject
class, initialize it with the dictionary, then have the loop drawing the objects. Something like this:
# in the form show event
objects = anvil.server.call('get_graphic_objects')
self.graphic_objects = [GraphicObject(o) for o in objects]
# in the canvas reset event
for o in self.graphic_objects:
o.draw(canvas)
An svg file is just like that list of dictionaries I described above: it’s a list of graphic objects and their attributes, just in different format. If you are ok with exposing the svg, then you are ok with exposing that dictionary. Actually, the svg is visible to anyone with a right click, while the list of dictionaries requires some hacking to be shown in clear.
An advantage of using a canvas rather than an image generated on the server, is that you can make it interactive. Both the svg and the canvas can manage click and other events, but for the svg you would need to inject the javascript for the event management inside the svg itself, while using a canvas you write the code as usual in python.