Skip to the tool
CALCPARK

Gamepad Response Visualizer

Watch your controller’s sticks live with trails, simulate radial, axial and scaled deadzones and response curves, run a circularity test and export the results as JSON.

Runs on your device
Loading the tool…

How to use it

  1. Connect the controller and press any button; it appears in the Controller panel. Pick it from the list if more than one is connected.
  2. Move the sticks and watch the scopes: the trail shows the last two seconds, the “Over time” plots show each axis and both triggers for the last ten seconds.
  3. Set the deadzone shape, inner/outer sizes, anti-deadzone and curve to what your game or driver uses. The red dot and the response-curve graph update immediately; the settings are kept in the page link.
  4. Take your hands off and press Measure drift for the 3-second resting check, judged against the inner deadzone.
  5. Push a stick fully to the edge, press Circularity test and rotate it slowly through two full turns in 6 seconds. Read the error, coverage and min/max radius, then download the JSON or the stick image if you want to keep them.

Example

A right stick rests at X +0.300, Y 0.000. With the default scaled radial deadzone of 0.10 the processed output is (0.300 − 0.10) ÷ (1 − 0.10) = +0.222; a plain radial deadzone would pass +0.300 through unchanged, and an axial deadzone of 0.35 would silence it completely. Rolling the same stick around the rim reaches a radius of 1.00 on the axes and 1.08 on the diagonals: coverage 100%, mean error 4.1%, verdict “very round”. A controller with a square gate reaches 1.41 on the diagonals instead and is reported as over-range.

How the processing works

m            = √(x² + y²)                        raw deflection
scaled radial: m′ = (m − inner) / (outer − inner), 0 inside, 1 beyond
radial       : m′ = m when m > inner, else 0
axial        : each axis rescaled on its own
curve        : m″ = m′ ^ exponent     (linear 1, squared 2, cubic 3)
anti-deadzone: out = anti + (1 − anti) · m″   when m″ > 0
circularity  : error = mean |r_bin − 1| over the 72 directions reached

The Gamepad API gives each axis as a value from −1 to +1 and each button as 0–1; the page reads navigator.getGamepads() every frame and redraws the canvases from those numbers. The standard mapping (17 buttons, 4 axes) lets Xbox and PlayStation names be shown; other pads get numbered buttons and consecutive axis pairs as sticks. The drift measurement is the same 3-second statistic as in the Gamepad Tester (mean offset and largest excursion). The circularity outline is the maximum radius per 5° bin; bins that never received a reading above half deflection count as uncovered.

Sources: W3C Gamepad specification – standard mapping, MDN – Gamepad API.

Everything shown is the browser’s view of the controller after the operating system and the browser’s own processing; the page does not read the controller’s internal sensors, its USB or Bluetooth report rate, or input latency, and it cannot change the controller’s calibration.

Questions

Why do the diagonals go beyond 1.0 in the circularity test?
Many controllers report each axis independently to ±1, so a stick pushed into the corner of a square gate reads about (1, 1) – a radius of 1.41. Round gates and drivers that clamp the vector to the unit circle give values close to 1.0 on every direction. Games normally clamp the magnitude, so a result above 1.0 is not a fault by itself; unevenness between directions is what matters.
What deadzone and curve should I use?
Set the inner deadzone just above the resting drift offset the drift test reports (0.05–0.15 for a healthy stick). Scaled radial keeps full range and smooth movement; axial helps when you want pure left/right or up/down input. A squared or cubic curve gives finer aiming near the centre at the cost of a slower mid-range – try each and watch the red dot.
Does the “Over time” plot show the controller’s polling rate?
No. The plot has one point per browser animation frame, so a 1000 Hz controller shows the same density as a 125 Hz one. Browsers do not expose the report rate; the Mouse Polling Rate Tester explains the equivalent limitation for mice.
The visualizer stopped updating after I unplugged and reconnected the pad.
Press a button on the reconnected controller; browsers only list a gamepad again after fresh input. The page shows a warning while a selected controller is missing and switches back to it as soon as it reappears.