Skip to content

Paths#

A path is a sequence of straight line segments and/or Bezier curves. A path may be filled and/or stroked. A path may have attached arrow to beginning and/or end.

Paths are drawn in Nelsie by constructing a Path instance and calling .add() method on a box. Path can be stroked or filled.

from nelsie import Path, Stroke, Point


@deck.slide()
def path_demo(slide):
    stroke = Stroke(color="orange", width=40)
    path = Path(fill_color="blue", stroke=stroke) \
               .move_to(Point(204, 300)) \
               .line_to(Point(819, 300)) \
               .line_to(Point(512, 600))
    slide.add(path)

Path methods#

Path constructor create an empty instance of a path. You can create line segments or Bezeier curves by calling the following methods:

  • .move_to(point) -- move the cursor to a given position without visible effect
  • .move_by(x, y) -- move the cursor by a given (x, y) offset, relative to the last position set by any *_to method
  • .line_to(point) -- create a line segment
  • .line_by(x, y) -- create a line segment that ends at the given (x, y) offset, relative to the last position set by any *_to method
  • .quad_to(p1, p) -- create a quadratic bezier curve
  • .cubic_to(p1, p2, p) -- create a cubic bezier curve
  • .close() -- create a line segment to the initial point of the path
@deck.slide()
def path_demo(slide):
    path = Path(fill_color="red") \
        .move_to(Point(200, 600)) \
        .quad_to(Point(500, 200), Point(800, 600)) \
        .close()
    slide.add(path)

Path coordinates#

Path coordinates can be given as:

  • float or a string with digits, (e.g. 100, "100") - a position in pixels relative to a box where a path is drawn
  • string in format "XX%" (e.g. "50%") - a position relative to the box where the path is drawn with respect to its size.
  • LayoutExpr - a position defined as a layout expression (see Layout expressions)
@deck.slide()
def path_demo(slide):
    path = Path(fill_color="red") \
        .move_to(Point("50%", "50%")) \
        .line_to(Point("100%", "100%")) \
        .line_to(Point("50%", "100%"))
    slide.add(path)
@deck.slide()
def path_demo(slide):
    box = slide.text("Hello world", TextStyle(size=80), bg_color="orange")

    # box.p() returns Point that is relative to the box
    path = Path(fill_color="red") \
        .move_to(box.p(0, 1.0)) \
        .line_to(Point("100%", "100%")) \
        .line_to(Point("50%", "100%"))
    slide.add(path)

Rect and Oval classes#

Rect and Oval classes are convenience classes that create a path with a rectangle or oval shape.

from nelsie import Oval, Rect


@deck.slide()
def path_demo(slide):
    shape = Rect(Point(400, 500), Point(600, 700), fill_color="orange")
    slide.add(shape)
    stroke = Stroke(color="orange", width=10)
    shape = Oval(Point(200, 200), Point(400, 400), fill_color="green", stroke=stroke)
    slide.add(shape)

Stroke class#

Stroke class defines how a path is stroked; you can configure a color, width, and line dash.

from nelsie import Stroke


@deck.slide()
def stroke_demo(slide):
    box = slide.box(width=700, height=140, m_bottom=60)
    box.add(Path(stroke=Stroke(color="red", width=10)).move_to(Point(0, 0)) \
        .line_to(Point(700, 0)))
    box.add(Path(stroke=Stroke(color="green", width=20, dash_array=[10, 20], dash_offset=15)) \
         .move_to(Point(0, "50%")) \
         .line_to(Point(700, "50%")))
    stroke = Stroke(color="blue", width=30, dash_array=[30, 10, 5, 10])
    box.add(Path(stroke=stroke).move_to(Point(0, "100%")).line_to(Point(700, "100%")))

Arrows#

You can attach an arrow to the beginning and/or end of a path. An arrow is created as an instance of Arrow and can be passed to the constructor of a can be passed to the constructor of Path in the parameters arrow_start and arrow_end. A color, size, angle, line width and position of the inner point can be configured.

from nelsie import Arrow

@deck.slide()
def arrow_demo(slide):
    box = slide.box(width=700, height=220)
    arrow1 = Arrow(size=80)
    stroke = Stroke(color="black", width=10)
    box.add(
        Path(stroke=stroke, arrow_start=arrow1, arrow_end=arrow1)
            .move_to(Point(0, 0))
            .line_to(Point(700, 0)),
    )

Color of arrows#

If parameter color is not defined, then arrow will have the same color as the path.

@deck.slide()
def arrow_demo(slide):
    box = slide.box(width=700, height=220)
    stroke = Stroke(color="green", width=10)
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80)) \
        .move_to(Point(0, 0)) \
        .line_to(Point(700, 0)))
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, color="red")) \
        .move_to(Point(0, 120)) \
        .line_to(Point(700, 120)))

Size of arrows#

@deck.slide()
def arrow_demo(slide):
    box = slide.box(width=700, height=220)
    stroke = Stroke(color="black", width=10)
    path = Path(stroke=stroke, arrow_end=Arrow(size=30)) \
        .move_to(Point(0, 0)) \
        .line_to(Point(700, 0))
    box.add(path)
    path = Path(stroke=stroke, arrow_end=Arrow(size=80)) \
        .move_to(Point(0, 150)) \
        .line_to(Point(700, 150))
    box.add(path)
    path = Path(stroke=stroke, arrow_end=Arrow(size=120)) \
        .move_to(Point(0, 300)) \
        .line_to(Point(700, 300))
    box.add(path)

Angle of arrows#

from nelsie import Arrow


@deck.slide()
def arrow_demo(slide):
    box = slide.box(width=700, height=220)
    stroke = Stroke(color="black", width=10)
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, angle=60))
                .move_to(Point(0, 0))
                .line_to(Point(700, 0)))
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, angle=45))
                .move_to(Point(0, 150))
                .line_to(Point(700, 150)))
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, angle=20))
                .move_to(Point(0, 300))
                .line_to(Point(700, 300)))

Stroked arrows#

If stroked_width is not None then the arrow is not filled but stroked.

@deck.slide()
def arrow_demo(slide):
    box = slide.box(width=700, height=220)
    stroke = Stroke(color="black", width=10)
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80))
            .move_to(Point(0, 0))
            .line_to(Point(700, 0)))
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, stroke_width=10))
            .move_to(Point(0, 150))
            .line_to(Point(700, 150)))
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, stroke_width=30))
            .move_to(Point(0, 300))
            .line_to(Point(700, 300)))

Inner point#

@deck.slide()
def arrow_demo(slide):
    box = slide.box(width=700, height=220)
    stroke = Stroke(color="black", width=10)
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, inner_point=0.5))
            .move_to(Point(0, 0))
            .line_to(Point(700, 0)))
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, inner_point=1.0))
            .move_to(Point(0, 150))
            .line_to(Point(700, 150)))
    box.add(Path(stroke=stroke, arrow_end=Arrow(size=80, inner_point=2.5))
            .move_to(Point(0, 300))
            .line_to(Point(700, 300)))