fossunited / joy

Joy is a tiny creative coding library in Python.
MIT License
193 stars 19 forks source link

re-sizeable show function #20

Open rijfas opened 3 years ago

rijfas commented 3 years ago

it's kinda weird to set a static 300*300 dimension to the sketches, can we change the show() method and SVG class to have a width, height property (with default values 300 of course!) ? Here is an example:

class SVG:
    """SVG renders any svg element into an svg image.
    """
    def __init__(self, nodes, width=300, height=300):
        self.nodes = nodes
        self.width = width
        self.height = height

    def render(self):
        attrs = {
            "tag": "svg",
            "width": self.width,
            "height": self.height,
            "viewBox": f"-{self.width//2} -{self.height//2} {self.width} {self.height}",
            "fill": "none",
            "stroke": "black",
            "xmlns": "http://www.w3.org/2000/svg",
            "xmlns:xlink": "http://www.w3.org/1999/xlink"
        }
        svg_header = render_tag(**attrs)+ "\n"
        svg_footer = "</svg>\n"

        # flip the y axis so that y grows upwards
        node = Group(self.nodes) | Scale(sx=1, sy=-1)

        return svg_header + node._svg() + svg_footer

    def _repr_svg_(self):
        return self.render()

    def __str__(self):
        return self.render()

    def __repr__(self):
        return "SVG:{self.nodes}"

def show(*shapes, width=300, height=300):
    """Shows the given shapes.

    It also adds a border to the canvas and axis at the origin with
    a light color as a reference.

    Parameters:

        shapes:
            The shapes to show.

    Examples:

    Show a circle:

        >>> show(circle())

    Show a circle and square.

        >>> c = circle()
        >>> s = rect()
        >>> show(c, s)
    """
    markers = [
        Rectangle(width=width, height=height, stroke="#ddd"),
        Line(start=Point(x=-(width//2), y=0), end=Point(x=(width//2), y=0), stroke="#ddd"),
        Line(start=Point(x=0, y=-(height//2)), end=Point(x=0, y=(height//2)), stroke="#ddd")
    ]
    shapes = markers + list(shapes)
    img = SVG(shapes, width=width, height=height)

    from IPython.display import display
    display(img)