Skip to content

Commit cb7ab45

Browse files
authored
Merge pull request #109 from martinRenou/sketchy
Add RoughCanvas
2 parents 44e9b16 + 3cc4560 commit cb7ab45

19 files changed

+1515
-687
lines changed

docs/source/drawing_paths.rst

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
Drawing paths
2+
=============
3+
4+
There are two ways for creating and drawing a path in ipycanvas.
5+
6+
Using Path2D
7+
------------
8+
9+
You can define a Path2D given an SVG path. Note that once the path is created, it is read only, you cannot dynamically change the path value.
10+
Using the Path2D class is very useful and efficient when you want to reuse the same path multiple times.
11+
12+
- ``Path2D(value)``: Creates a Path2D given the SVG path string value.
13+
14+
.. code:: Python
15+
16+
from ipycanvas import Canvas, Path2D
17+
18+
canvas = Canvas(width=350, height=350)
19+
20+
path1 = Path2D('M80 80 A 45 45, 0, 0, 0, 125 125 L 125 80 Z')
21+
path2 = Path2D('M230 80 A 45 45, 0, 1, 0, 275 125 L 275 80 Z')
22+
path3 = Path2D('M80 230 A 45 45, 0, 0, 1, 125 275 L 125 230 Z')
23+
path4 = Path2D('M230 230 A 45 45, 0, 1, 1, 275 275 L 275 230 Z')
24+
25+
canvas.fill_style = 'green'
26+
canvas.fill(path1)
27+
28+
canvas.fill_style = 'purple'
29+
canvas.fill(path2)
30+
31+
canvas.fill_style = 'red'
32+
canvas.fill(path3)
33+
34+
canvas.fill_style = 'blue'
35+
canvas.fill(path4)
36+
37+
canvas
38+
39+
.. image:: images/path2d.png
40+
41+
42+
Using Path commands
43+
-------------------
44+
45+
A path is a list of points, connected by segments of lines that can be of different shapes, curved or not,
46+
of different width and of different color. A path can be closed. To make shapes using paths, we take some
47+
extra steps:
48+
49+
- First, you create the path with ``begin_path``
50+
- Then you use drawing commands to add shapes into the path
51+
- Once the path has been created, you can ``stroke`` or ``fill`` the path to render it
52+
53+
Here are the functions used to perform these steps:
54+
55+
- ``begin_path()``: Creates a new path. Once created, future drawing commands are directed into the path and used to build the path up.
56+
- Path commands like ``line_to`` and ``arc``
57+
- ``close_path()``: Adds a straight line to the path, going to the start of the current path.
58+
- ``stroke()``: Draws the shape by stroking its outline.
59+
- ``fill(rule)``: Draws a solid shape by filling the path's content area. The given fill rule is applied, possible rules are `nonzero` and `evenodd`.
60+
61+
.. code:: Python
62+
63+
from ipycanvas import Canvas
64+
65+
canvas = Canvas(width=100, height=100)
66+
67+
# Draw simple triangle shape
68+
canvas.begin_path()
69+
canvas.move_to(75, 50)
70+
canvas.line_to(100, 75)
71+
canvas.line_to(100, 25)
72+
canvas.fill()
73+
74+
canvas
75+
76+
.. image:: images/triangle.png
77+
78+
79+
Path commands
80+
+++++++++++++
81+
82+
Here are the available draw commands:
83+
84+
- ``move_to(x, y)``: Moves the pen to the coordinates specified by x and y. This does not actually draw anything.
85+
- ``line_to(x, y)``: Add a straight line to the current path by connecting the path’s last point to the specified (x, y) coordinates.
86+
- ``arc(x, y, radius, start_angle, end_angle, anticlockwise=False)``: Add a circular arc centered at (x, y) with a radius
87+
of ``radius`` to the current path. The path starts at ``start_angle`` and ends at ``end_angle`` in radians, and travels in the direction given by
88+
``anticlockwise`` (defaulting to clockwise: False).
89+
- ``arc_to(x1, y1, x2, y2, radius)``: Add a circular arc to the current path. Using the given control points (``x1``, ``y1``)
90+
and (``x2``, ``y2``) and the ``radius``.
91+
- ``ellipse(x, y, radius_x, radius_y, rotation, start_angle, end_angle, anticlockwise=False)``: Add an ellipse centered at ``(x, y)`` with
92+
the radii ``radius_x`` and ``radius_y`` to the current path.
93+
- ``quadratic_curve_to(cp1x, cp1y, x, y)``: Add a quadratic Bezier curve to the current path.
94+
It requires two points: the first one is a control point and the second one is the end point. The starting point is the latest point in the current path, which can be changed using ``move_to()`` before creating the quadratic Bezier curve.
95+
- ``bezier_curve_to(cp1x, cp1y, cp2x, cp2y, x, y)``: Add a cubic Bezier curve to the current path.
96+
It requires three points: the first two are control points and the third one is the end point. The starting point is the latest point in the current path, which can be changed using ``move_to()`` before creating the Bezier curve.
97+
- ``rect(x, y, width, height)``: Draws a rectangle whose top-left corner is specified by (``x``, ``y``) with the specified ``width`` and ``height``.
98+
99+
100+
Examples
101+
++++++++
102+
103+
Stroke arcs
104+
'''''''''''
105+
106+
.. code:: Python
107+
108+
from math import pi
109+
110+
from ipycanvas import Canvas
111+
112+
canvas = Canvas(width=200, height=200)
113+
114+
# Draw smiley face
115+
canvas.begin_path()
116+
canvas.arc(75, 75, 50, 0, pi * 2, True) # Outer circle
117+
canvas.move_to(110, 75)
118+
canvas.arc(75, 75, 35, 0, pi, False) # Mouth (clockwise)
119+
canvas.move_to(65, 65)
120+
canvas.arc(60, 65, 5, 0, pi * 2, True) # Left eye
121+
canvas.move_to(95, 65)
122+
canvas.arc(90, 65, 5, 0, pi * 2, True) # Right eye
123+
canvas.stroke()
124+
125+
canvas
126+
127+
.. image:: images/smiley.png
128+
129+
Fill bezier curves
130+
''''''''''''''''''
131+
132+
.. code:: Python
133+
134+
from ipycanvas import Canvas
135+
136+
canvas = Canvas(width=200, height=200)
137+
138+
# Cubic curves example
139+
canvas.begin_path()
140+
canvas.move_to(75, 40)
141+
canvas.bezier_curve_to(75, 37, 70, 25, 50, 25)
142+
canvas.bezier_curve_to(20, 25, 20, 62.5, 20, 62.5)
143+
canvas.bezier_curve_to(20, 80, 40, 102, 75, 120)
144+
canvas.bezier_curve_to(110, 102, 130, 80, 130, 62.5)
145+
canvas.bezier_curve_to(130, 62.5, 130, 25, 100, 25)
146+
canvas.bezier_curve_to(85, 25, 75, 37, 75, 40)
147+
canvas.fill()
148+
149+
canvas
150+
151+
.. image:: images/heart.png
152+
153+
Change the fill rule
154+
''''''''''''''''''''
155+
156+
.. code:: Python
157+
158+
from math import pi
159+
from ipycanvas import Canvas
160+
161+
canvas = Canvas(width=100, height=100)
162+
163+
canvas.begin_path()
164+
canvas.arc(50, 50, 30, 0, pi * 2, True)
165+
canvas.arc(50, 50, 15, 0, pi * 2, True)
166+
canvas.fill('evenodd')
167+
168+
canvas
169+
170+
.. image:: images/fill_rule.png

0 commit comments

Comments
 (0)