Skip to content

Commit a0fa811

Browse files
authored
Add scroll capture functionality to WebAgg backend (#30403)
* Add scroll capture functionality to WebAgg backend * lint
1 parent 3a8ad1d commit a0fa811

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
WebAgg scroll capture control
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The WebAgg backend now provides the ability to capture scroll events to prevent
5+
page scrolling when interacting with plots. This can be enabled or disabled via
6+
the new `.FigureCanvasWebAggCore.set_capture_scroll` and
7+
`.FigureCanvasWebAggCore.get_capture_scroll` methods.

lib/matplotlib/backends/backend_webagg_core.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ def __init__(self, *args, **kwargs):
178178
# Track mouse events to fill in the x, y position of key events.
179179
self._last_mouse_xy = (None, None)
180180

181+
# Control whether scroll events prevent default browser behavior
182+
self._capture_scroll = False
183+
181184
def show(self):
182185
# show the figure window
183186
from matplotlib.pyplot import show
@@ -224,6 +227,28 @@ def set_image_mode(self, mode):
224227
self._current_image_mode = mode
225228
self.handle_send_image_mode(None)
226229

230+
def set_capture_scroll(self, capture):
231+
"""
232+
Set whether the scroll events on the canvas will scroll the page.
233+
234+
Parameters
235+
----------
236+
capture : bool
237+
"""
238+
if self._capture_scroll != capture:
239+
self._capture_scroll = capture
240+
self.send_event("capture_scroll", capture_scroll=capture)
241+
242+
def get_capture_scroll(self):
243+
"""
244+
Get whether scroll events are currently captured by the canvas.
245+
246+
Returns
247+
-------
248+
bool
249+
"""
250+
return self._capture_scroll
251+
227252
def get_diff_image(self):
228253
if self._png_is_old:
229254
renderer = self.get_renderer()
@@ -335,6 +360,8 @@ def handle_refresh(self, event):
335360
# Normal toolbar init would refresh this, but it happens before the
336361
# browser canvas is set up.
337362
self.toolbar.set_history_buttons()
363+
# Send the current capture_scroll state to newly connected clients
364+
self.send_event('capture_scroll', capture_scroll=self._capture_scroll)
338365
self.draw_idle()
339366

340367
def handle_resize(self, event):

lib/matplotlib/backends/web_backend/js/mpl.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ mpl.figure = function (figure_id, websocket, ondownload, parent_element) {
2424

2525
this.supports_binary = this.ws.binaryType !== undefined;
2626

27+
this.capture_scroll = false;
28+
2729
if (!this.supports_binary) {
2830
var warnings = document.getElementById('mpl-warnings');
2931
if (warnings) {
@@ -313,6 +315,9 @@ mpl.figure.prototype._init_canvas = function () {
313315
} else {
314316
event.step = -1;
315317
}
318+
if (fig.capture_scroll) {
319+
event.preventDefault();
320+
}
316321
on_mouse_event_closure('scroll')(event);
317322
});
318323

@@ -524,6 +529,10 @@ mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {
524529
}
525530
};
526531

532+
mpl.figure.prototype.handle_capture_scroll = function (fig, msg) {
533+
fig.capture_scroll = msg['capture_scroll'];
534+
};
535+
527536
mpl.figure.prototype.updated_canvas_event = function () {
528537
// Called whenever the canvas gets updated.
529538
this.send_message('ack', {});

0 commit comments

Comments
 (0)