Skip to content

Wheel zoom uncontrollable on high-resolution touchpad: fixed per-event speed, laggy synchronous redraw for each event #947

Description

@andersk

Two problems with the wheel event handler compound to make zooming completely uncontrollable on a touchpad with high-resolution scrolling, which emits wheel events with small deltaY at a high frequency:

  1. The handler ignores the event’s deltaMode and the magnitude of deltaY: it only takes the sign into account. So the high event frequency leads to much more zooming than the user intended.

const speed = zoomOptions.wheel.speed;
const percentage = event.deltaY >= 0 ? 2 - 1 / (1 - speed) : 1 + speed;

  1. The handler redraws the chart synchronously for each event, rather coalescing multiple events across a requestAnimationFrame callback. If the redraw is even just a little slower than the time between events, a backlog of events builds up in the queue, and the chart lags farther and farther behind real time.

zoom(chart, amount, 'zoom', 'wheel');

Reproduction

https://jsfiddle.net/anderskaseorg/ezy5guf2/

<canvas id="ctx">
<script type="module">
import { Chart, LinearScale, PointElement, ScatterController } from "https://esm.sh/chart.js@4.5.1";
import zoomPlugin from "https://esm.sh/chartjs-plugin-zoom@2.2.0";
Chart.register(LinearScale, PointElement, ScatterController, zoomPlugin);
const chart = new Chart(ctx, {
  type: "scatter",
  data: {
    datasets: [{
      data: [...Array(10000).keys()].map(() => ({ x: Math.random(), y: Math.random() })),
    }],
  },
  options: { plugins: { zoom: { zoom: { wheel: { enabled: true } } } } },
});
</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions