Skip to content

Commit 3267014

Browse files
committed
Add filter property
1 parent 2df4ebe commit 3267014

File tree

7 files changed

+103
-7
lines changed

7 files changed

+103
-7
lines changed

dev-environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ dependencies:
1111
- wheel
1212
- twine
1313
- jupytext
14-
- black=21
14+
- black=22.1.0

docs/source/images/filter.png

40.7 KB
Loading

docs/source/styles_and_colors.rst

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,82 @@ Then use it as a ``fill_style`` or ``stroke_style``:
140140
141141
.. image:: images/pattern.png
142142

143+
Filters
144+
-------
145+
146+
You can apply filters such as blurring and grayscaling to your drawings using the ``filter`` property. This property is similar to the filter CSS property and accepts the same values.
147+
148+
The ``filter`` property is a ``string`` with the following syntax:
149+
150+
.. code:: Python
151+
152+
canvas.filter = '<filter-function1> [<filter-function2>] [<filter-functionN>]'
153+
canvas.filter = 'none'
154+
155+
The following filter functions are supported:
156+
157+
- ``url()``:
158+
A CSS url(). Takes an IRI pointing to an SVG filter element, which may be embedded in an external XML file.
159+
160+
- ``blur()``:
161+
A CSS <length>. Applies a Gaussian blur to the drawing. It defines the value of the standard deviation to the Gaussian function, i.e., how many pixels on the screen blend into each other; thus, a larger value will create more blur. A value of 0 leaves the input unchanged.
162+
163+
- ``brightness()``:
164+
A CSS <percentage>. Applies a linear multiplier to the drawing, making it appear brighter or darker. A value under 100% darkens the image, while a value over 100% brightens it. A value of 0% will create an image that is completely black, while a value of 100% leaves the input unchanged.
165+
166+
- ``contrast()``:
167+
A CSS <percentage>. Adjusts the contrast of the drawing. A value of 0% will create a drawing that is completely black. A value of 100% leaves the drawing unchanged.
168+
169+
- ``drop-shadow()``:
170+
Applies a drop shadow effect to the drawing. A drop shadow is effectively a blurred, offset version of the drawing's alpha mask drawn in a particular color, composited below the drawing. This function takes up to five arguments:
171+
172+
- <offset-x>: Specifies the horizontal distance of the shadow.
173+
- <offset-y>: Specifies the vertical distance of the shadow.
174+
- <blur-radius>: The larger this value, the bigger the blur, so the shadow becomes bigger and lighter. Negative values are not allowed.
175+
- <color>: The shadow color.
176+
177+
- ``grayscale()``:
178+
A CSS <percentage>. Converts the drawing to grayscale. A value of 100% is completely grayscale. A value of 0% leaves the drawing unchanged.
179+
180+
- ``hue-rotate()``:
181+
A CSS <angle>. Applies a hue rotation on the drawing. A value of 0deg leaves the input unchanged.
182+
183+
- ``invert()``:
184+
A CSS <percentage>. Inverts the drawing. A value of 100% means complete inversion. A value of 0% leaves the drawing unchanged.
185+
186+
- ``opacity()``:
187+
A CSS <percentage>. Applies transparency to the drawing. A value of 0% means completely transparent. A value of 100% leaves the drawing unchanged.
188+
189+
- ``saturate()``:
190+
A CSS <percentage>. Saturates the drawing. A value of 0% means completely un-saturated. A value of 100% leaves the drawing unchanged.
191+
192+
- ``sepia()``:
193+
A CSS <percentage>. Converts the drawing to sepia. A value of 100% means completely sepia. A value of 0% leaves the drawing unchanged.
194+
195+
- ``none``:
196+
No filter is applied. Initial value.
197+
198+
.. code:: Python
199+
200+
from ipycanvas import Canvas
201+
202+
canvas = Canvas(width=400, height=300)
203+
204+
canvas.fill_style = 'green'
205+
canvas.filter = 'blur(1px) contrast(1.4) drop-shadow(-9px 9px 3px #e81)'
206+
canvas.font = '48px serif'
207+
canvas.fill_text('Hello world!', 20, 150)
208+
209+
canvas
210+
211+
.. image:: images/filter.png
212+
213+
.. warning::
214+
Applying a filter can be slow, especially if you draw many shapes.
215+
216+
.. danger::
217+
This property is **not supported by Safari and Internet Explorer**
218+
143219
RoughCanvas
144220
-----------
145221

examples/particle_system.ipynb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@
4646
"canvas.fill_rects(x, y, size)"
4747
]
4848
},
49+
{
50+
"cell_type": "code",
51+
"execution_count": null,
52+
"metadata": {},
53+
"outputs": [],
54+
"source": [
55+
"blurred_canvas = Canvas(width=800, height=500)\n",
56+
"blurred_canvas.filter = \"blur(1px) drop-shadow(-9px 9px 3px #e81)\"\n",
57+
"\n",
58+
"blurred_canvas.draw_image(canvas)\n",
59+
"\n",
60+
"blurred_canvas"
61+
]
62+
},
4963
{
5064
"cell_type": "markdown",
5165
"metadata": {},
@@ -206,7 +220,7 @@
206220
"name": "python",
207221
"nbconvert_exporter": "python",
208222
"pygments_lexer": "ipython3",
209-
"version": "3.9.7"
223+
"version": "3.10.2"
210224
}
211225
},
212226
"nbformat": 4,

examples/plotting.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@
531531
"x = np.linspace(-5, 5, 100)\n",
532532
"y = np.linspace(-5, 5, 100)\n",
533533
"x_grid, y_grid = np.meshgrid(x, y)\n",
534-
"color = np.sin(x_grid + y_grid ** 2) + np.cos(x_grid ** 2 + y_grid ** 2)\n",
534+
"color = np.sin(x_grid + y_grid**2) + np.cos(x_grid**2 + y_grid**2)\n",
535535
"\n",
536536
"HeatmapPlot(x, y, color, scheme=branca.colormap.linear.RdYlBu_05)"
537537
]

ipycanvas/canvas.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,10 @@ class Canvas(_CanvasBase):
514514
#: the junction becomes. Default to ``10.``.
515515
miter_limit = Float(10.0)
516516

517+
#: (str) Filter effects such as blurring and grayscaling. It is similar to the CSS filter property and accepts the same values.
518+
#: This property has no effect on Safari, see https://bugs.webkit.org/show_bug.cgi?id=198416
519+
filter = Unicode("none")
520+
517521
_line_dash = List()
518522

519523
#: (float) Specifies where to start a dash array on a line. Default is ``0.``.
@@ -549,6 +553,7 @@ class Canvas(_CanvasBase):
549553
"shadow_offset_y": 14,
550554
"shadow_blur": 15,
551555
"shadow_color": 16,
556+
"filter": 17,
552557
}
553558

554559
def __init__(self, *args, **kwargs):

src/widget.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class CanvasModel extends DOMWidgetModel {
264264
'textBaseline', 'direction', 'globalCompositeOperation',
265265
'lineWidth', 'lineCap', 'lineJoin', 'miterLimit', 'lineDashOffset',
266266
'shadowOffsetX', 'shadowOffsetY', 'shadowBlur', 'shadowColor',
267+
'filter',
267268
];
268269

269270
initialize(attributes: any, options: any) {
@@ -637,7 +638,7 @@ class CanvasModel extends DOMWidgetModel {
637638
// a scalar
638639
const numPolygons = args[0];
639640

640-
// always array
641+
// always array
641642
const points = getArg(args[1], buffers);
642643

643644
// array or scalar
@@ -666,7 +667,7 @@ class CanvasModel extends DOMWidgetModel {
666667
this.ctx.beginPath();
667668
this.ctx.moveTo(points.getItem(start), points.getItem(start+1));
668669

669-
// draw all points of the polygon (except start)
670+
// draw all points of the polygon (except start)
670671
for(let idp = start+2; idp < stop; idp += 2){
671672
this.ctx.lineTo(points.getItem(idp), points.getItem(idp + 1));
672673
}
@@ -684,7 +685,7 @@ class CanvasModel extends DOMWidgetModel {
684685
// a scalar
685686
const numPolygons = args[0];
686687

687-
// always array
688+
// always array
688689
const points = getArg(args[1], buffers);
689690

690691
// array or scalar
@@ -701,7 +702,7 @@ class CanvasModel extends DOMWidgetModel {
701702
this.ctx.beginPath();
702703
this.ctx.moveTo(points.getItem(start), points.getItem(start+1));
703704

704-
// draw all points of the polygon (except start)
705+
// draw all points of the polygon (except start)
705706
for(let idp = start+2; idp < stop; idp += 2){
706707
this.ctx.lineTo(points.getItem(idp), points.getItem(idp + 1));
707708
}

0 commit comments

Comments
 (0)