Анализ сайта twinstickgaming.com
Основное Готовность: 100%
Домен
twinstickgaming.com
Состояние доменного имени
?
Проверяем корректность доменного имени и наличие технических проблем на уровне домена.
Длина домена велика. Но если вы продвигаете запрос, входящий в название домена, то это хорошо.
Домен второго уровня идеален для продвижения.
Ответ сервера
200 Успешный ответ
HTTP-код ответа и цепочка редиректов
?
Код 200 — страница доступна. Коды 3xx — редиректы (цепочки замедляют загрузку и размывают ссылочный вес). Коды 4xx/5xx — ошибки, поисковик не сможет проиндексировать страницу.
Сервер настроен корректно.
Цепочка редиректов:
http://twinstickgaming.com
301 MovedPermanently
https://twinstickgaming.com/
200 OK
Безопасность
Сайт безопасен
Использование HTTPS и SSL-сертификат
?
HTTPS — обязательный стандарт. Google и Яндекс отдают предпочтение защищённым сайтам. Отсутствие SSL или просроченный сертификат ведут к предупреждениям в браузере и снижению позиций.
На сайте работает защищенный протокол ssl и сайт открывается по https.
Ssl-сертификат действителен до 04.10.2026 22:45:22.
Включён HSTS (Strict-Transport-Security) — защита от подмены на http.
HTTP автоматически перенаправляется на HTTPS.
Поздравляем! Сайт не содержится в реестре РКН.
Кодировка
UTF-8
Кодировка символов страницы
?
Стандарт — UTF-8. Неправильная кодировка вызывает нечитаемые символы и мешает поисковику корректно распознать текст страницы.
Указана кодировка на странице UTF-8.
Язык
en
Атрибут lang в HTML-теге
?
Атрибут lang (<html lang="ru">) сообщает поисковикам и браузерам, на каком языке написана страница. Помогает при ранжировании в региональном поиске.
Язык документа указан явно: en.
Скорость загрузки
~0,70сек
Время отклика сервера (TTFB)
?
Time To First Byte — время до получения первого байта от сервера. Норма до 200 мс. Медленный отклик ухудшает пользовательский опыт и ранжирование: Яндекс и Google учитывают скорость страниц.
Скорость загрузки сайта 0,70сек оптимальна.
Объем документа
57Кб
Размер HTML-кода страницы
?
Слишком большой HTML замедляет парсинг браузером и сканирование поисковым роботом. Рекомендуется не более 200 Кб.
Объем html-документа 57Кб оптимален.
Структура html-документа корректна.
Ресурсы
Ресурсы: 2
Внешние ресурсы страницы (CSS, JS, изображения)
?
Количество и тип подключённых ресурсов влияют на скорость загрузки. Большое число запросов увеличивает время рендеринга страницы.
Кол-во файлов ресурсов 2 достаточно.
Показать полный список ресурсов
| Тип | Название | Значение |
|---|---|---|
| stylesheet | css/style.css | |
| js | js/gamepad.js |
Серверные заголовки
Кол-во: 6
HTTP-заголовки ответа сервера
?
Заголовки сервера передают браузеру и поисковику служебную информацию: кеширование, безопасность (CSP, HSTS), сжатие (gzip). Правильная настройка ускоряет загрузку и повышает защищённость.
Найдены серверные заголовки 6шт. Подробнее про серверные заголовки.
Показать полный список серверных заголовков
| Ключ | Значение |
|---|---|
| Server | nginx |
| Date | Sun, 23 Aug 2026 14:13:48 GMT |
| Vary | Accept-Encoding |
| ETag | "e873-64ea05f6a8f2a" |
| Accept-Ranges | bytes |
| Strict-Transport-Security | max-age=31536000; |
CMS
Не определена
Система управления сайтом (движок)
?
CMS — это движок, на котором работает сайт (WordPress, 1C-Bitrix, Tilda и др.). Знание CMS помогает понять возможности SEO-оптимизации и подобрать подходящие инструменты. «Не определена» — вероятно, самописный сайт или нестандартная сборка.
CMS не определена. Вероятно, сайт самописный либо движок надёжно скрыт. Это не ошибка.
Веб-сервер
Программное обеспечение сервера
?
Веб-сервер — это ПО, которое отдаёт страницы посетителям (nginx, Apache, IIS, LiteSpeed и др.). Определяется по серверным заголовкам ответа (Server, X-Powered-By и т.п.). «Не определён» — сервер намеренно скрывает эти заголовки, это нормальная практика безопасности.
Сайт работает на веб-сервере nginx.
Мета-теги Готовность: 23%
Title
Gamepad Tester — Free Stick Drift Test, Controller Test Online | TwinStickGaming
Заголовок страницы в браузере и поисковой выдаче
?
Title — главный SEO-заголовок страницы. Влияет на CTR в поиске и ранжирование. Оптимальная длина: 50–70 символов. Ключевые слова — ближе к началу.
Устраните дубли в title: test(2)
Необходимо уменьшить число символов в title (текущее значение: 80, оптимально: от 40 до 45)
Description
The most advanced free online gamepad tester. Test stick drift, deadzone, circularity, button response and vibration for PS4, PS5 DualSense, and Xbox controllers. Instant results — no download needed.
Описание страницы в поисковой выдаче (сниппет)
?
Meta Description — текст под заголовком в выдаче. Напрямую на позиции не влияет, но влияет на CTR. Оптимальная длина: 120–160 символов.
Необходимо уменьшить число символов в description (текущее значение: 200, оптимально: от 120 до 130)
Keywords
stick drift test, gamepad tester, controller test, stick drift checker, controller drift test, joystick test, deadzone tester, circularity test, ps5 stick drift test, xbox controller test, controller drift check, joystick drift test, stickdrift test, deadzone controller test
Список ключевых слов страницы (устаревший тег)
?
Meta Keywords не учитывается Яндексом и Google для ранжирования с 2009–2012 годов. Заполнение не обязательно, но не вредит. Конкурент может использовать содержимое для анализа.
Keywords установлены.
Канонический Url
https://twinstickgaming.com/
Указывает поисковику основную версию страницы
?
Canonical (rel=canonical) предотвращает проблему дублей страниц. Должен точно совпадать с URL проверяемой страницы. Неправильный canonical может передать ссылочный вес на другую страницу.
Канонический Url прописан корректно.
Robots
index, follow
Директивы для поисковых роботов на уровне страницы
?
Meta Robots управляет индексацией конкретной страницы: index/noindex — индексировать ли, follow/nofollow — следовать ли по ссылкам. Noindex полностью исключает страницу из поиска.
Meta-тег robots со значениями index, follow не накладывает ограничений на индексирование и показ контента.
Адаптивность
width=device-width, initial-scale=1.0
Настройка масштабирования на мобильных устройствах
?
Тег viewport (<meta name="viewport">) сообщает браузеру, как масштабировать страницу на мобильных. Стандарт: width=device-width, initial-scale=1. Отсутствие — признак отсутствия мобильной версии.
Meta-тег viewport со значением-константой width=device-width задаёт ширину страницы в соответствии с размером экрана.
Meta-тег viewport со значением initial-scale=1.0 определяет масштаб 1:1, т.е. «не масштабировать».
Разметка OpenGraph
Кол-во: 5
Мета-теги для красивых превью в соцсетях
?
OpenGraph (og:title, og:description, og:image) управляет тем, как страница выглядит при репосте в социальных сетях и мессенджерах. Отсутствие OG-тегов — невзрачный превью при шеринге.
Разметка OpenGraph задана. Страница оптимизирована под социальные сети.
Показать полный список og мета-тегов
| Тип | Значение |
|---|---|
| og:type | website |
| og:title | Gamepad Tester — Free Stick Drift Test Online | TwinStickGaming |
| og:description | Test your PS4, PS5, and Xbox controller for stick drift, deadzone, circularity and button latency. Free, instant, no download needed. |
| og:url | https://twinstickgaming.com/ |
| og:site_name | TwinStickGaming |
Все мета-теги
Кол-во: 13
Полный список мета-тегов страницы
?
Таблица всех meta-тегов, включая нестандартные. Позволяет найти опечатки, дубли и лишние теги.
Найдены мета-теги 13шт. Мета-теги не видимы для человека и предназначены для обмена информацией между веб-страницей и поисковыми системами, браузерами и другими веб-службами. С ними роботы 🤖 и устройства ведут себя более ожидаемо.
Показать полный список мета-тегов
| Тип | Название | Значение |
|---|---|---|
| name | viewport | width=device-width, initial-scale=1.0 |
| name | description | The most advanced free online gamepad tester. Test stick drift, deadzone, circularity, button response and vibration for PS4, PS5 DualSense, and Xbox controllers. Instant results — no download needed. |
| name | keywords | stick drift test, gamepad tester, controller test, stick drift checker, controller drift test, joystick test, deadzone tester, circularity test, ps5 stick drift test, xbox controller test, controller drift check, joystick drift test, stickdrift test, deadzone controller test |
| name | robots | index, follow |
| name | author | TwinStickGaming |
| name | twitter:card | summary_large_image |
| name | twitter:title | Gamepad Tester — Free Stick Drift Test Online |
| name | twitter:description | The most advanced free online gamepad tester. Test stick drift, deadzone, circularity, and button response for PS4, PS5, and Xbox controllers. |
| property | og:type | website |
| property | og:title | Gamepad Tester — Free Stick Drift Test Online | TwinStickGaming |
| property | og:description | Test your PS4, PS5, and Xbox controller for stick drift, deadzone, circularity and button latency. Free, instant, no download needed. |
| property | og:url | https://twinstickgaming.com/ |
| property | og:site_name | TwinStickGaming |
Оптимизация Готовность: 82%
Структура
Ошибок нет
Семантические HTML-элементы страницы
?
Проверяет наличие основных структурных элементов: nav, header, footer, main. Корректная семантическая структура помогает поисковику понять архитектуру страницы.
Структура документа корректна (теги <html> и <body> присутствуют в одном экземпляре).
Контент
Ошибок нет
Объём и качество текстового содержимого
?
Анализирует объём полезного текста на странице. Слишком мало — страница может считаться малополезной. Слишком много — ухудшается читаемость и восприятие.
Слова из title 11 встречаются в тексте достаточно.
Абзацев с текстом 67 достаточно.
Среднее число слов в абзаце 24 достаточно.
Кол-во знаков контента 16665 на странице оптимально.
Кол-во слов 2707 на странице оптимально.
Заголовки
Ошибок нет
Иерархия заголовков H1–H6
?
H1 должен быть один и содержать ключевой запрос. H2–H6 описывают подразделы. Пропуск уровней (H1 → H3) и несколько H1 — типичные ошибки, снижающие понятность страницы для поисковика.
На странице присутствуют заголовки <h1> 1. Это прекрасно.
На странице присутствуют заголовки <h2> 9. Это хорошо.
На странице присутствуют заголовки <h3> 29.
Тошнота
5,83
Насколько одно слово доминирует в тексте
?
Классическая тошнота = √(частота самого повторяющегося слова). Норма до 7–8: текст воспринимается естественно. Выше — поисковик может счесть страницу переспамленной.
Тошнота превышает норму 5. Измените текст страницы!
Академич. тошнота
25,86%
Насколько текст перенасыщен ключевыми словами
?
Академическая тошнота = (частота слова / общее количество слов) × 100%. Показывает долю конкретного слова в тексте. Норма 5–15%.
Академическая тошнота превышает норму 5-15%. Измените текст страницы!
Семантическое ядро
20
Наиболее часто встречающиеся слова на странице
?
Топ слов по частоте использования. Показывает, какие слова доминируют в тексте с точки зрения поисковика.
Контент страницы содержит осмысленный текст и слова.
Показать список слов
| Слово | Кол-во | Частота |
|---|---|---|
| controller | 34 | 1,26% |
| button | 27 | 1,00% |
| deadzone | 24 | 0,89% |
| gamepad | 17 | 0,63% |
| controllers | 16 | 0,59% |
| tester | 15 | 0,55% |
| circularity | 14 | 0,52% |
| dualsense | 12 | 0,44% |
| connect | 12 | 0,44% |
| rumble | 11 | 0,41% |
| analog | 11 | 0,41% |
| browser | 10 | 0,37% |
| bluetooth | 10 | 0,37% |
| sticks | 10 | 0,37% |
| chrome | 9 | 0,33% |
| testing | 8 | 0,30% |
| circle | 8 | 0,30% |
| support | 8 | 0,30% |
| vibration | 7 | 0,26% |
| measures | 7 | 0,26% |
Индексация Готовность: 50%
Индексирование
Ошибок нет
Разрешено ли индексирование страницы
?
Проверяет, не закрыта ли страница от индексации через robots.txt, meta robots или X-Robots-Tag. Страница, закрытая от индексации, не появится в поисковой выдаче.
Анкоров на странице 17 оптимально. Поисковые роботы обязательно проиндексируют сайт.
Robots.txt
Найден корректный robots.txt
Файл управления сканированием сайта роботами
?
Robots.txt указывает поисковым роботам, какие страницы сканировать, а какие — нет. Ошибки в файле могут случайно закрыть важные разделы от индексации.
Кол-во редиректов для файла robots.txt 3 слишком большое! Это может вызывать затруднение при индексации поисковыми роботами!
Проверяемая страница не запрещена в robots.txt.
Robots.txt доступен по постоянному адресу
Цепочка редиректов для файла robots.txt:
http://twinstickgaming.com/robots.txt
301 MovedPermanently
https://twinstickgaming.com/robots.txt
301 MovedPermanently
https://twinstickgaming.com/
200 OK
Показать содержимое robots.txt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gamepad Tester — Free Stick Drift Test, Controller Test Online | TwinStickGaming</title>
<meta name="description" content="The most advanced free online gamepad tester. Test stick drift, deadzone, circularity, button response and vibration for PS4, PS5 DualSense, and Xbox controllers. Instant results — no download needed.">
<meta name="keywords" content="stick drift test, gamepad tester, controller test, stick drift checker, controller drift test, joystick test, deadzone tester, circularity test, ps5 stick drift test, xbox controller test, controller drift check, joystick drift test, stickdrift test, deadzone controller test">
<meta name="robots" content="index, follow">
<meta name="author" content="TwinStickGaming">
<link rel="canonical" href="https://twinstickgaming.com/">
<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:title" content="Gamepad Tester — Free Stick Drift Test Online | TwinStickGaming">
<meta property="og:description" content="Test your PS4, PS5, and Xbox controller for stick drift, deadzone, circularity and button latency. Free, instant, no download needed.">
<meta property="og:url" content="https://twinstickgaming.com/">
<meta property="og:site_name" content="TwinStickGaming">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Gamepad Tester — Free Stick Drift Test Online">
<meta name="twitter:description" content="The most advanced free online gamepad tester. Test stick drift, deadzone, circularity, and button response for PS4, PS5, and Xbox controllers.">
<!-- Schema.org -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "TwinStickGaming Gamepad Tester",
"url": "https://twinstickgaming.com/",
"description": "Free online gamepad tester with stick drift detection, deadzone calibration, circularity test, and vibration test for PS4, PS5, and Xbox controllers.",
"applicationCategory": "GameApplication",
"operatingSystem": "Any",
"browserRequirements": "Requires a browser that supports the Gamepad API",
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" }
}
</script>
<link rel="stylesheet" href="css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🎮</text></svg>">
</head>
<body>
<!-- ============================================================
HEADER
============================================================ -->
<header>
<div class="header-inner">
<a href="/" class="logo">
<div class="logo-icon">🎮</div>
TwinStick<span>Gaming</span>
</a>
<nav>
<a href="/" class="active">Gamepad Tester</a>
<a href="#how-it-works">How It Works</a>
<a href="#stick-drift">Stick Drift</a>
<a href="#faq">FAQ</a>
</nav>
</div>
</header>
<!-- ============================================================
HERO
============================================================ -->
<section class="hero">
<div class="hero-content">
<div class="hero-badge">
<span>🟢</span> Free Online Tool · No Download Required
</div>
<h1>The Ultimate <span class="gradient-text">Gamepad Tester</span> & Stick Drift Checker</h1>
<p class="hero-desc">
Instantly test your PS4, PS5 DualSense, or Xbox controller for stick drift, deadzone issues, circularity errors, and button latency — directly in your browser.
</p>
<div class="hero-stats">
<div class="stat">
<div class="stat-num">7</div>
<div class="stat-label">Test Modes</div>
</div>
<div class="stat">
<div class="stat-num">18</div>
<div class="stat-label">Buttons Tested</div>
</div>
<div class="stat">
<div class="stat-num">60fps</div>
<div class="stat-label">Real-Time Data</div>
</div>
</div>
<a href="#tester" class="hero-cta">🎮 Start Testing Now</a>
</div>
<div class="hero-visual">
<div class="hero-feature-list">
<div class="hero-feature"><span class="icon">📡</span> Live Stick Position</div>
<div class="hero-feature"><span class="icon">🎯</span> Drift Detection</div>
<div class="hero-feature"><span class="icon">⭕</span> Circularity Test</div>
<div class="hero-feature"><span class="icon">📏</span> Deadzone Calibrator</div>
<div class="hero-feature"><span class="icon">⚡</span> Button Latency</div>
<div class="hero-feature"><span class="icon">📳</span> Vibration / Rumble</div>
<div class="hero-feature"><span class="icon">🎮</span> PS4 / PS5 / Xbox</div>
<div class="hero-feature"><span class="icon">📊</span> Detailed Reports</div>
</div>
</div>
</section>
<!-- ============================================================
CONNECT PROMPT
============================================================ -->
<div id="connect-prompt" style="padding: 0 24px 48px; max-width: 1280px; margin: 0 auto;">
<div class="connect-card">
<span class="connect-icon">🎮</span>
<h2>Connect Your Controller to Start</h2>
<p>Plug in or connect your PS4, PS5, or Xbox controller, then press any button to activate it.</p>
<div class="compat-badges">
<span class="badge badge-ps">🎮 PS4 DualShock 4</span>
<span class="badge badge-ps">🎮 PS5 DualSense</span>
<span class="badge badge-xbox">🎮 Xbox One / Series</span>
<span class="badge badge-generic">🎮 Generic / PC Controllers</span>
</div>
<div class="connect-steps">
<div class="connect-step">
<div class="step-num">1</div>
<p>Connect via USB cable or Bluetooth to your PC/Mac</p>
</div>
<div class="connect-step">
<div class="step-num">2</div>
<p>Press any button on the controller to activate it</p>
</div>
<div class="connect-step">
<div class="step-num">3</div>
<p>The tester will auto-detect your controller and begin monitoring</p>
</div>
</div>
<p class="mt-24" style="font-size:0.8rem; color: var(--text-muted);">
Uses the browser's built-in <strong>Gamepad API</strong> — no extensions or downloads required. Best experienced in Chrome or Edge.
</p>
</div>
</div>
<!-- ============================================================
TESTER PANEL
============================================================ -->
<section id="tester">
<!-- Drift warning banner -->
<div class="drift-warning-banner" id="drift-warning-banner">
<span id="drift-warning-msg">Potential stick drift detected. Run the Drift Test for analysis.</span>
</div>
<!-- Controller header bar -->
<div class="controller-header">
<div class="controller-info-bar">
<span id="controller-type-badge" class="controller-type-badge type-generic">🎮 Controller</span>
<span id="controller-name" class="controller-name">Detecting...</span>
</div>
<div class="d-flex align-center gap-8">
<span style="font-size:0.75rem; color:var(--text-muted);">Player:</span>
<div class="controller-index-badge">
<div class="index-dot active" data-index="0">1</div>
<div class="index-dot" data-index="1">2</div>
<div class="index-dot" data-index="2">3</div>
<div class="index-dot" data-index="3">4</div>
</div>
</div>
</div>
<!-- Monitor row -->
<div class="monitor-row">
<div class="monitor-item">
<div class="monitor-label">L-Stick Magnitude</div>
<div class="monitor-val" id="monitor-lmag">0.000</div>
</div>
<div class="monitor-item">
<div class="monitor-label">R-Stick Magnitude</div>
<div class="monitor-val" id="monitor-rmag">0.000</div>
</div>
<div class="monitor-item">
<div class="monitor-label">Total Presses</div>
<div class="monitor-val" id="total-presses">0</div>
</div>
<div class="monitor-item">
<div class="monitor-label">Session Time</div>
<div class="monitor-val" id="monitor-session">00:00</div>
</div>
</div>
<!-- Row 1: Controller Visual + Sticks -->
<div class="tester-grid" style="margin-bottom:20px;">
<!-- Controller SVG -->
<div class="card">
<div class="card-header">
<span class="card-title"><span class="dot"></span> Controller Visual</span>
</div>
<div class="controller-svg-wrapper">
<svg viewBox="0 0 540 340" class="controller-svg" xmlns="http://www.w3.org/2000/svg">
<!-- ── CONTROLLER BODY ── -->
<path class="ctrl-body" d="
M 105 125
C 105 75, 145 45, 195 42
L 345 42
C 395 45, 435 75, 435 125
L 435 205
C 435 205, 480 238, 500 290
C 510 318, 482 328, 458 315
L 398 272
C 375 295, 320 312, 270 312
C 220 312, 165 295, 142 272
L 82 315
C 58 328, 30 318, 40 290
C 60 238, 105 205, 105 205
Z
"/>
<!-- ── TOUCHPAD ── -->
<rect id="svg-rect-17" class="ctrl-btn" x="200" y="118" width="140" height="82" rx="14"/>
<!-- ── LEFT STICK AREA ── -->
<circle class="ctrl-stick-area" cx="168" cy="218" r="42"/>
<circle id="svg-lstick-center" class="ctrl-stick-area" cx="168" cy="218" r="18" data-cx="168" data-cy="218"/>
<circle id="svg-lstick-dot" class="ctrl-stick-dot" cx="168" cy="218" r="12" fill="#2a2a5e"/>
<!-- ── RIGHT STICK AREA ── -->
<circle class="ctrl-stick-area" cx="358" cy="230" r="42"/>
<circle id="svg-rstick-center" class="ctrl-stick-area" cx="358" cy="230" r="18" data-cx="358" data-cy="230"/>
<circle id="svg-rstick-dot" class="ctrl-stick-dot" cx="358" cy="230" r="12" fill="#2a2a5e"/>
<!-- ── D-PAD ── -->
<!-- Center (always shown) -->
<rect x="232" y="193" width="22" height="22" fill="#0d0d22"/>
<!-- Up -->
<rect id="svg-rect-12" class="ctrl-btn" x="232" y="168" width="22" height="28" rx="4"/>
<!-- Down -->
<rect id="svg-rect-13" class="ctrl-btn" x="232" y="215" width="22" height="28" rx="4"/>
<!-- Left -->
<rect id="svg-rect-14" class="ctrl-btn" x="204" y="193" width="28" height="22" rx="4"/>
<!-- Right -->
<rect id="svg-rect-15" class="ctrl-btn" x="254" y="193" width="28" height="22" rx="4"/>
<!-- ── FACE BUTTONS ── -->
<!-- Cross / A (bottom) -->
<circle id="svg-circle-0" class="ctrl-btn" cx="406" cy="232" r="17"/>
<text id="svg-btn-0" x="406" y="237" text-anchor="middle" font-size="15" fill="#6677ff" font-weight="bold" pointer-events="none">×</text>
<!-- Circle / B (right) -->
<circle id="svg-circle-1" class="ctrl-btn" cx="428" cy="208" r="17"/>
<text id="svg-btn-1" x="428" y="213" text-anchor="middle" font-size="15" fill="#ff4455" font-weight="bold" pointer-events="none">○</text>
<!-- Square / X (left) -->
<circle id="svg-circle-2" class="ctrl-btn" cx="384" cy="208" r="17"/>
<text id="svg-btn-2" x="384" y="213" text-anchor="middle" font-size="15" fill="#ff55ff" font-weight="bold" pointer-events="none">□</text>
<!-- Triangle / Y (top) -->
<circle id="svg-circle-3" class="ctrl-btn" cx="406" cy="184" r="17"/>
<text id="svg-btn-3" x="406" y="189" text-anchor="middle" font-size="15" fill="#44ee88" font-weight="bold" pointer-events="none">△</text>
<!-- ── L1 / R1 BUMPERS ── -->
<path id="svg-rect-4" class="ctrl-btn" d="M 105 115 C 108 90 135 78 175 76 L 175 105 C 140 105 115 115 110 130 Z"/>
<text x="138" y="100" text-anchor="middle" font-size="11" fill="#aaa" pointer-events="none">L1</text>
<path id="svg-rect-5" class="ctrl-btn" d="M 435 115 C 432 90 405 78 365 76 L 365 105 C 400 105 425 115 430 130 Z"/>
<text x="402" y="100" text-anchor="middle" font-size="11" fill="#aaa" pointer-events="none">R1</text>
<!-- ── L2 / R2 TRIGGERS ── -->
<path id="svg-rect-6" class="ctrl-btn" d="M 83 100 C 87 58 120 36 175 40 L 175 76 C 135 78 108 90 105 115 Z"/>
<text x="110" y="62" text-anchor="middle" font-size="11" fill="#aaa" pointer-events="none">L2</text>
<!-- Trigger fill indicator -->
<clipPath id="l2-clip">
<path d="M 83 100 C 87 58 120 36 175 40 L 175 76 C 135 78 108 90 105 115 Z"/>
</clipPath>
<rect id="svg-l2-fill" x="83" y="36" width="92" height="0" fill="rgba(0,212,255,0.4)" clip-path="url(#l2-clip)" data-maxh="79" data-basey="36"/>
<path id="svg-rect-7" class="ctrl-btn" d="M 457 100 C 453 58 420 36 365 40 L 365 76 C 405 78 432 90 435 115 Z"/>
<text x="430" y="62" text-anchor="middle" font-size="11" fill="#aaa" pointer-events="none">R2</text>
<clipPath id="r2-clip">
<path d="M 457 100 C 453 58 420 36 365 40 L 365 76 C 405 78 432 90 435 115 Z"/>
</clipPath>
<rect id="svg-r2-fill" x="365" y="36" width="92" height="0" fill="rgba(0,212,255,0.4)" clip-path="url(#r2-clip)" data-maxh="79" data-basey="36"/>
<!-- ── SHARE / CREATE ── -->
<rect id="svg-rect-8" class="ctrl-btn" x="205" y="114" width="44" height="20" rx="10"/>
<text id="svg-btn-8" x="227" y="128" text-anchor="middle" font-size="9" fill="#888" pointer-events="none">Create</text>
<!-- ── OPTIONS ── -->
<rect id="svg-rect-9" class="ctrl-btn" x="291" y="114" width="44" height="20" rx="10"/>
<text id="svg-btn-9" x="313" y="128" text-anchor="middle" font-size="9" fill="#888" pointer-events="none">Options</text>
<!-- ── HOME / PS BUTTON ── -->
<circle id="svg-circle-16" class="ctrl-btn" cx="270" cy="230" r="20"/>
<text id="svg-btn-16" x="270" y="235" text-anchor="middle" font-size="10" fill="#888" pointer-events="none">PS</text>
<text id="svg-xbox-logo" x="270" y="235" text-anchor="middle" font-size="13" fill="#107c10" pointer-events="none" style="display:none">⬤</text>
<text id="svg-ps-logo" x="270" y="235" text-anchor="middle" font-size="10" fill="#0070cc" pointer-events="none">PS</text>
<!-- ── L3 / R3 labels ── -->
<text x="168" y="222" text-anchor="middle" font-size="9" fill="#333" pointer-events="none">L3</text>
<text x="358" y="234" text-anchor="middle" font-size="9" fill="#333" pointer-events="none">R3</text>
</svg>
</div>
</div>
<!-- Sticks Panel -->
<div class="card">
<div class="card-header">
<span class="card-title"><span class="dot"></span> Analog Sticks</span>
</div>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:20px;">
<!-- Left Stick -->
<div class="stick-panel">
<div style="font-size:0.75rem; font-weight:700; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-muted); margin-bottom:6px;">Left Stick (L3)</div>
<div class="stick-canvas-wrap">
<canvas id="left-stick-canvas" width="200" height="200" class="stick-canvas"></canvas>
<div class="stick-drift-badge" id="left-drift-badge"></div>
</div>
<div class="stick-values">
<div class="stick-val-item">
<div class="stick-val-label">X Axis</div>
<div class="stick-val-num" id="left-x-val">0.0000</div>
</div>
<div class="stick-val-item">
<div class="stick-val-label">Y Axis</div>
<div class="stick-val-num" id="left-y-val">0.0000</div>
</div>
</div>
<div class="stick-magnitude">
<span style="font-size:0.7rem; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em;">Magnitude</span>
<div class="stick-mag-bar-wrap">
<div class="stick-mag-bar" id="left-mag-bar"></div>
</div>
<span class="stick-mag-num" id="left-mag-num">0.0000</span>
</div>
</div>
<!-- Right Stick -->
<div class="stick-panel">
<div style="font-size:0.75rem; font-weight:700; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-muted); margin-bottom:6px;">Right Stick (R3)</div>
<div class="stick-canvas-wrap">
<canvas id="right-stick-canvas" width="200" height="200" class="stick-canvas"></canvas>
<div class="stick-drift-badge" id="right-drift-badge"></div>
</div>
<div class="stick-values">
<div class="stick-val-item">
<div class="stick-val-label">X Axis</div>
<div class="stick-val-num" id="right-x-val">0.0000</div>
</div>
<div class="stick-val-item">
<div class="stick-val-label">Y Axis</div>
<div class="stick-val-num" id="right-y-val">0.0000</div>
</div>
</div>
<div class="stick-magnitude">
<span style="font-size:0.7rem; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em;">Magnitude</span>
<div class="stick-mag-bar-wrap">
<div class="stick-mag-bar" id="right-mag-bar"></div>
</div>
<span class="stick-mag-num" id="right-mag-num">0.0000</span>
</div>
</div>
</div>
</div>
</div>
<!-- Row 2: Triggers + Buttons + Log -->
<div class="tester-grid-3" style="margin-bottom:20px;">
<!-- Triggers -->
<div class="card">
<div class="card-header">
<span class="card-title"><span class="dot"></span> Triggers (Analog)</span>
</div>
<div class="triggers-row" style="flex-direction:column; gap:16px; display:flex;">
<div class="trigger-item">
<div class="trigger-label">L2 / LT — Left Trigger</div>
<div class="trigger-bar-wrap">
<div class="trigger-bar" id="left-trigger-bar"></div>
<span class="trigger-val" id="left-trigger-val">0.000</span>
</div>
</div>
<div class="trigger-item">
<div class="trigger-label">R2 / RT — Right Trigger</div>
<div class="trigger-bar-wrap">
<div class="trigger-bar" id="right-trigger-bar"></div>
<span class="trigger-val" id="right-trigger-val">0.000</span>
</div>
</div>
</div>
<div style="margin-top:16px; padding-top:16px; border-top:1px solid var(--border);">
<div style="font-size:0.75rem; font-weight:700; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-muted); margin-bottom:10px;">Trigger Tips</div>
<ul style="font-size:0.78rem; color:var(--text-muted); list-style:none; display:flex; flex-direction:column; gap:6px;">
<li>▸ Full press should reach <strong>1.000</strong></li>
<li>▸ Any value at rest indicates trigger drift</li>
<li>▸ PS5 adaptive triggers show resistance zones</li>
</ul>
</div>
</div>
<!-- Buttons Grid -->
<div class="card" style="grid-column: span 2;">
<div class="card-header">
<span class="card-title"><span class="dot"></span> All Buttons</span>
<span style="font-size:0.75rem; color:var(--text-muted);">Press any button to test</span>
</div>
<div class="buttons-grid" id="buttons-grid">
<!-- Built by JS -->
</div>
</div>
</div>
<!-- Input Log -->
<div class="input-log card" style="margin-bottom:20px;">
<div class="card-header" style="padding: 12px 16px 0;">
<span class="card-title"><span class="dot"></span> Input Log</span>
<span style="font-size:0.72rem; color:var(--text-muted);">Most recent inputs</span>
</div>
<div class="input-log-inner" id="input-log-inner">
<div style="color:var(--text-muted); font-size:0.78rem; text-align:center; padding:16px;">Press buttons to see input log</div>
</div>
</div>
<!-- ── TESTS SECTION ── -->
<div class="drift-test-card">
<div class="test-tabs">
<button class="test-tab active" data-tab="drift">🎯 Drift Test</button>
<button class="test-tab" data-tab="circularity">⭕ Circularity Test</button>
<button class="test-tab" data-tab="deadzone">📏 Deadzone</button>
<button class="test-tab" data-tab="response">⚡ Response Time</button>
<button class="test-tab" data-tab="rumble">📳 Rumble / Haptics</button>
</div>
<!-- ── DRIFT TEST ── -->
<div class="test-pane active" id="pane-drift">
<h3 style="margin-bottom:4px;">Stick Drift Test</h3>
<p style="font-size:0.85rem; margin-bottom:20px;">Measures unwanted stick movement while the controller is at rest. Place the controller on a flat surface before testing.</p>
<div class="drift-test-layout">
<div>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:16px;">
<!-- Left stick result -->
<div class="drift-result-card">
<div class="drift-stick-label">Left Stick</div>
<div class="drift-score" id="left-drift-score">—</div>
<div class="drift-verdict" id="left-drift-verdict">Not tested</div>
<div class="drift-detail" id="left-drift-detail"></div>
</div>
<!-- Right stick result -->
<div class="drift-result-card">
<div class="drift-stick-label">Right Stick</div>
<div class="drift-score" id="right-drift-score">—</div>
<div class="drift-verdict" id="right-drift-verdict">Not tested</div>
<div class="drift-detail" id="right-drift-detail"></div>
</div>
</div>
<div style="background:var(--card2); border-radius:var(--radius-sm); padding:12px; font-size:0.8rem; color:var(--text-muted);">
<strong style="color:var(--text-dim);">How to read results:</strong><br>
<span style="color:var(--green);">PASS</span> = <4% drift |
<span style="color:var(--orange);">BORDERLINE</span> = 4–8% |
<span style="color:var(--red);">DRIFT DETECTED</span> = >8%
</div>
</div>
<div class="drift-controls">
<div class="drift-instructions" id="drift-instructions">
Press <strong>Start Drift Test</strong>, then place your controller down and do not touch it. The test runs for 5 seconds and measures any unwanted stick movement.
</div>
<div class="drift-countdown" id="drift-countdown">5.0s</div>
<div class="drift-progress" id="drift-progress">
<div class="drift-progress-bar" id="drift-progress-bar"></div>
</div>
<div style="display:flex; gap:10px;">
<button class="btn btn-primary btn-full" id="drift-start-btn">▶ Start Drift Test (5s)</button>
<button class="btn btn-secondary" id="drift-clear-btn">Reset</button>
</div>
<div style="background:var(--card2); border-radius:var(--radius-sm); padding:12px;">
<div style="font-size:0.75rem; font-weight:700; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-muted); margin-bottom:8px;">Real-Time Drift Monitor</div>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:8px;">
<div>
<div style="font-size:0.7rem; color:var(--text-muted); margin-bottom:4px;">Left Stick (live)</div>
<canvas id="drift-left-canvas" width="140" height="140" style="width:140px;height:140px;border-radius:50%;"></canvas>
</div>
<div>
<div style="font-size:0.7rem; color:var(--text-muted); margin-bottom:4px;">Right Stick (live)</div>
<canvas id="drift-right-canvas" width="140" height="140" style="width:140px;height:140px;border-radius:50%;"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ── CIRCULARITY TEST ── -->
<div class="test-pane" id="pane-circularity">
<h3 style="margin-bottom:4px;">Circularity Test</h3>
<p style="font-size:0.85rem; margin-bottom:20px;">Measures how circular your stick's range of motion is. A perfect circle = 100%. Low scores indicate worn or damaged stick mechanisms.</p>
<div class="circularity-layout">
<div class="circ-canvas-wrap">
<canvas id="circularity-canvas" width="300" height="300"></canvas>
</div>
<div>
<div class="circ-select-label">Select Stick to Test</div>
<div class="circ-stick-btns">
<button class="circ-stick-btn active" data-stick="left">Left Stick</button>
<button class="circ-stick-btn" data-stick="right">Right Stick</button>
</div>
<div class="circ-score-display">
<div class="circ-score-num" id="circ-score-num">—</div>
<div class="circ-score-label">Circularity Score</div>
</div>
<div class="circ-stats">
<div class="circ-stat">
<div class="circ-stat-label">Avg Radius</div>
<div class="circ-stat-val" id="circ-stat-radius">—</div>
</div>
<div class="circ-stat">
<div class="circ-stat-label">Std Deviation</div>
<div class="circ-stat-val" id="circ-stat-stdev">—</div>
</div>
<div class="circ-stat">
<div class="circ-stat-label">Points Sampled</div>
<div class="circ-stat-val" id="circ-stat-points">—</div>
</div>
<div class="circ-stat">
<div class="circ-stat-label">Verdict</div>
<div class="circ-stat-val" id="circ-stat-verdict">—</div>
</div>
</div>
<div class="drift-instructions mt-12" id="circ-instructions">
Select a stick and press Start. Rotate the stick slowly and evenly around the full edge of its range. Press Stop when you've completed at least 2 full rotations.
</div>
<div style="display:flex; gap:10px; margin-top:12px;">
<button class="btn btn-primary" id="circ-start-btn">▶ Start</button>
<button class="btn btn-danger" id="circ-stop-btn" style="display:none;">■ Stop</button>
<button class="btn btn-secondary" id="circ-clear-btn">Reset</button>
</div>
</div>
</div>
</div>
<!-- ── DEADZONE TEST ── -->
<div class="test-pane" id="pane-deadzone">
<h3 style="margin-bottom:4px;">Deadzone Visualizer & Calibrator</h3>
<p style="font-size:0.85rem; margin-bottom:20px;">Adjust the deadzone threshold and see how it affects stick input. Move the left stick to visualize active vs. dead zones in real time.</p>
<div class="deadzone-layout">
<div class="dz-slider-wrap">
<div class="dz-label">
<span>Deadzone Threshold</span>
<span class="dz-val" id="dz-val">5.0%</span>
</div>
<input type="range" id="deadzone-slider" min="0" max="0.30" step="0.005" value="0.05">
<div style="background:var(--card2); border-radius:var(--radius-sm); padding:14px; font-size:0.82rem; color:var(--text-dim); display:flex; flex-direction:column; gap:8px;">
<div><strong style="color:var(--text);">What is Deadzone?</strong></div>
<p>The deadzone is a small area around the center of the stick where input is ignored. This prevents unintended movement from minor stick imperfections or resting position variation.</p>
<p>Typical game deadzones range from <strong>3%–15%</strong>. If you have stick drift, increasing the deadzone can mask it — but this reduces precision.</p>
</div>
<div style="display:grid; grid-template-columns:1fr 1fr 1fr; gap:8px; margin-top:4px;">
<div style="background:var(--card2); border-radius:var(--radius-sm); padding:10px; text-align:center;">
<div style="font-size:0.65rem; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em;">Game Average</div>
<div style="font-size:1rem; font-weight:800; color:var(--accent);">5–12%</div>
</div>
<div style="background:var(--card2); border-radius:var(--radius-sm); padding:10px; text-align:center;">
<div style="font-size:0.65rem; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em;">PS5 Default</div>
<div style="font-size:1rem; font-weight:800; color:var(--accent);">~6%</div>
</div>
<div style="background:var(--card2); border-radius:var(--radius-sm); padding:10px; text-align:center;">
<div style="font-size:0.65rem; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.06em;">Xbox Default</div>
<div style="font-size:1rem; font-weight:800; color:var(--accent);">~8%</div>
</div>
</div>
</div>
<div class="dz-canvas-wrap">
<canvas id="deadzone-canvas" width="280" height="280"></canvas>
<div style="text-align:center; margin-top:8px; font-size:0.75rem; color:var(--text-muted);">🟠 Orange = Dead Zone 🔵 Cyan = Active Input</div>
</div>
</div>
</div>
<!-- ── RESPONSE TIME TEST ── -->
<div class="test-pane" id="pane-response">
<h3 style="margin-bottom:4px;">Button Response Time Test</h3>
<p style="font-size:0.85rem; margin-bottom:20px;">Measures the time between successive button presses using the browser's high-resolution timer. Useful for detecting input latency patterns.</p>
<div class="response-layout">
<div class="response-display">
<div class="response-time" id="response-time-display">—</div>
<div class="response-stats">
<div class="response-stat">
<span>Average:</span>
<span id="response-avg">—</span>
</div>
<div class="response-stat">
<span>Minimum:</span>
<span id="response-min">—</span>
</div>
<div class="response-stat">
<span>Maximum:</span>
<span id="response-max">—</span>
</div>
<div class="response-stat">
<span>Sample count:</span>
<span id="response-count">0</span>
</div>
</div>
</div>
<div style="background:var(--accent-dim); border:1px solid var(--border-bright); border-radius:var(--radius-sm); padding:12px; font-size:0.82rem; color:var(--text-dim);">
<strong style="color:var(--accent);">How to use:</strong> Press any button repeatedly to measure timing between presses. The timer measures consecutive intervals — ideal for testing button repeatability and detecting input lag patterns.
</div>
<div style="display:flex; gap:10px;">
<button class="btn btn-secondary" id="response-clear-btn">Reset Data</button>
</div>
<div style="font-size:0.78rem; font-weight:700; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-muted);">Press Log</div>
<div class="response-log" id="response-log">
<div style="color:var(--text-muted); font-size:0.78rem; text-align:center; padding:16px;">Press any button to start measuring</div>
</div>
</div>
</div>
<!-- ── RUMBLE TEST ── -->
<div class="test-pane" id="pane-rumble">
<h3 style="margin-bottom:4px;">Vibration / Rumble Test</h3>
<p style="font-size:0.85rem; margin-bottom:20px;">Test your controller's haptic motors. Supports dual-motor rumble (weak + strong). Requires Chrome or Edge browser.</p>
<div class="rumble-layout">
<div class="rumble-controls">
<div class="rumble-item">
<label>
<span>Weak Motor (High Frequency)</span>
<span id="rumble-weak-val">50%</span>
</label>
<input type="range" id="rumble-weak" min="0" max="1" step="0.01" value="0.5">
</div>
<div class="rumble-item">
<label>
<span>Strong Motor (Low Frequency)</span>
<span id="rumble-strong-val">80%</span>
</label>
<input type="range" id="rumble-strong" min="0" max="1" step="0.01" value="0.8">
</div>
<div class="rumble-item">
<label>
<span>Duration</span>
<span id="rumble-duration-val">500ms</span>
</label>
<input type="range" id="rumble-duration" min="50" max="3000" step="50" value="500">
</div>
<div class="rumble-item" style="grid-column:span 2;">
<div style="display:flex; gap:10px;">
<button class="btn btn-primary" id="rumble-test-btn">📳 Test Rumble</button>
<button class="btn btn-secondary" id="rumble-stop-btn">■ Stop</button>
</div>
</div>
</div>
<div>
<div style="font-size:0.75rem; font-weight:700; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-muted); margin-bottom:10px;">Quick Presets</div>
<div class="rumble-presets">
<button class="btn btn-secondary btn-sm rumble-preset" data-preset="gentle">🟢 Gentle</button>
<button class="btn btn-secondary btn-sm rumble-preset" data-preset="medium">🟡 Medium</button>
<button class="btn btn-secondary btn-sm rumble-preset" data-preset="strong">🔴 Strong</button>
<button class="btn btn-secondary btn-sm rumble-preset" data-preset="pulse">⚡ Pulse ×5</button>
<button class="btn btn-secondary btn-sm rumble-preset" data-preset="leftonly">← Left Only</button>
<button class="btn btn-secondary btn-sm rumble-preset" data-preset="rightonly">Right Only →</button>
</div>
</div>
<div class="rumble-status" id="rumble-status">
Checking vibration support...
</div>
</div>
</div>
</div><!-- /drift-test-card -->
</section><!-- /#tester -->
<!-- ============================================================
FEATURES OVERVIEW
============================================================ -->
<section class="content-section" id="how-it-works">
<div class="container">
<div class="section-label">How It Works</div>
<h2>Everything You Need to <span class="gradient-text">Test Your Controller</span></h2>
<p class="lead">TwinStickGaming uses your browser's built-in Gamepad API to give you real-time, frame-accurate data about your controller's performance — no software to install.</p>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">🎯</div>
<h3>Stick Drift Test</h3>
<p>Our 5-second automated drift test samples your sticks hundreds of times to detect even the smallest unwanted movement. Get a percentage score and directional drift analysis for both sticks.</p>
</div>
<div class="feature-card">
<div class="feature-icon">⭕</div>
<h3>Circularity Test</h3>
<p>Trace a circle with your stick and our algorithm calculates how close to a perfect circle your stick's range is. Low scores indicate worn potentiometers or damaged stick mechanisms.</p>
</div>
<div class="feature-card">
<div class="feature-icon">📏</div>
<h3>Deadzone Calibrator</h3>
<p>Visually see and adjust the deadzone threshold from 0–30%. Understand why deadzones exist and how they interact with stick drift to mask or amplify input problems.</p>
</div>
<div class="feature-card">
<div class="feature-icon">⚡</div>
<h3>Button Response Time</h3>
<p>Measure the interval between button presses with high-resolution timer accuracy. Identify inconsistent button behavior or sticky buttons that affect your gaming performance.</p>
</div>
<div class="feature-card">
<div class="feature-icon">📳</div>
<h3>Vibration / Rumble Test</h3>
<p>Test both haptic motors independently or together. Use presets or fine-tune weak/strong motor intensity and duration. Verify that PS5 DualSense and Xbox rumble are working correctly.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🎮</div>
<h3>Full Button Map</h3>
<p>See all buttons, D-pad directions, triggers, and bumpers in real time. Auto-detects PS4, PS5, and Xbox layouts with correct button labels (×○□△ vs A/B/X/Y).</p>
</div>
<div class="feature-card">
<div class="feature-icon">📡</div>
<h3>Real-Time Stick Monitor</h3>
<p>Live canvas visualization shows your stick position, movement trail, deadzone ring, and magnitude bar at 60fps. Color-coded drift indicators turn orange/red when drift is detected passively.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🔌</div>
<h3>Multi-Controller Support</h3>
<p>Connect up to 4 controllers simultaneously and switch between them using the player indicator dots. Each controller is auto-detected and displays its own session data.</p>
</div>
</div>
</div>
</section>
<!-- ============================================================
WHAT IS STICK DRIFT
============================================================ -->
<section class="content-section alt" id="stick-drift">
<div class="container">
<div class="info-grid">
<div class="info-text">
<div class="section-label">The Problem</div>
<h2>What Is <span class="gradient-text">Stick Drift</span>?</h2>
<p>Stick drift — also called controller drift, analog drift, or joystick drift — occurs when your controller's analog stick registers movement even when you're not touching it. This causes your character or camera to move on its own, ruining your gaming experience.</p>
<p>The primary cause is wear on the <strong>potentiometers</strong> (variable resistors) inside the analog stick module. As the stick is used, tiny particles of carbon wear off the resistive track, causing the electrical signal to fluctuate even at rest.</p>
<div class="info-callout">
<p><strong>Did you know?</strong> A class action lawsuit was filed against Sony in 2021 over DualSense stick drift, and the PS5's thumbstick drift problem has been widely reported. Xbox controllers are not immune either — the Xbox One and Series controllers use similar potentiometer-based sticks.</p>
</div>
<h3 style="margin-top:20px; margin-bottom:8px;">Common Signs of Stick Drift</h3>
<ul class="info-list">
<li>Character or camera moves without touching the controller</li>
<li>Menu cursor drifts to one side automatically</li>
<li>Unable to aim precisely — crosshair drifts off target</li>
<li>Stick feels "loose" or has less resistance than before</li>
<li>Stick doesn't return to perfect center when released</li>
<li>Input feels "mushy" or unresponsive in a certain direction</li>
</ul>
</div>
<div>
<div class="section-label">How to Test</div>
<h2>How to Test for <span class="gradient-text">Stick Drift Online</span></h2>
<p style="margin-bottom:20px;">Our gamepad tester makes it easy to check for stick drift in seconds:</p>
<div class="guide-steps" style="grid-template-columns:1fr; gap:16px;">
<div class="guide-step" style="flex-direction:row; align-items:flex-start; gap:14px;">
<div class="guide-step-num" style="flex-shrink:0;">1</div>
<div>
<h3>Connect Your Controller</h3>
<p>Plug in via USB or connect via Bluetooth, then press any button to activate it in your browser.</p>
</div>
</div>
<div class="guide-step" style="flex-direction:row; align-items:flex-start; gap:14px;">
<div class="guide-step-num" style="flex-shrink:0;">2</div>
<div>
<h3>Watch the Live Monitor</h3>
<p>Check the stick canvases. If the dot moves without you touching the stick, that's passive drift. An orange/red badge will appear.</p>
</div>
</div>
<div class="guide-step" style="flex-direction:row; align-items:flex-start; gap:14px;">
<div class="guide-step-num" style="flex-shrink:0;">3</div>
<div>
<h3>Run the Drift Test</h3>
<p>Open the Drift Test tab, click "Start Drift Test", then put down the controller. After 5 seconds you'll get a percentage score for each stick.</p>
</div>
</div>
<div class="guide-step" style="flex-direction:row; align-items:flex-start; gap:14px;">
<div class="guide-step-num" style="flex-shrink:0;">4</div>
<div>
<h3>Read Your Results</h3>
<p>Under 4% = No drift. 4–8% = Borderline (monitor it). Over 8% = Drift detected — consider repair, replacement, or increasing your in-game deadzone as a temporary fix.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============================================================
PLATFORM GUIDE
============================================================ -->
<section class="content-section">
<div class="container">
<div class="section-label">By Platform</div>
<h2>Stick Drift Test by <span class="gradient-text">Controller Type</span></h2>
<p class="lead">Our tester auto-detects your controller and shows correct button labels. Here's what to know per platform.</p>
<div class="platform-grid" style="grid-template-columns: repeat(3, 1fr);">
<div class="platform-card">
<div class="platform-icon">🎮</div>
<h3>PS5 DualSense Stick Drift Test</h3>
<p>The PS5 DualSense is unfortunately prone to stick drift, a problem Sony acknowledges. Our test measures drift on both the left (L3) and right (R3) sticks, shows directional drift, and gives you a pass/fail score.</p>
<ul class="info-list" style="margin-top:10px;">
<li>Connect via USB-C or Bluetooth</li>
<li>Run our 5-second drift test</li>
<li>Check for left-stick up/down drift (common DualSense issue)</li>
<li>Also test the touchpad button (button 17)</li>
</ul>
</div>
<div class="platform-card">
<div class="platform-icon">🎮</div>
<h3>PS4 DualShock 4 Stick Drift Test</h3>
<p>The DualShock 4 uses the same potentiometer-based stick tech as the DualSense. Drift is common in well-used controllers. The tester detects DS4 by its USB signature and shows PS button labels (×○□△).</p>
<ul class="info-list" style="margin-top:10px;">
<li>Works via USB cable on Windows/Mac</li>
<li>Bluetooth may require DS4Windows on PC</li>
<li>Check both sticks — right stick drift is common</li>
<li>Circularity test reveals worn stick gates</li>
</ul>
</div>
<div class="platform-card">
<div class="platform-icon">🎮</div>
<h3>Xbox Controller Stick Drift Test</h3>
<p>Xbox One, Series S, and Series X controllers connect via USB or Bluetooth on Windows. The tester detects Xbox controllers and shows A/B/X/Y labels. Both LT/RT triggers are tested with analog precision.</p>
<ul class="info-list" style="margin-top:10px;">
<li>Connect via USB or Xbox Wireless Adapter</li>
<li>Drift test works identically to PS controllers</li>
<li>Check LT/RT trigger values at rest (should be 0.000)</li>
<li>Xbox Elite controllers show all extra buttons</li>
</ul>
</div>
</div>
<div class="info-callout" style="margin-top:32px; max-width:700px;">
<p><strong>Note on Bluetooth:</strong> Some browsers have limited Gamepad API support over Bluetooth. For best results, especially for rumble testing, use a USB cable and the Chrome or Edge browser.</p>
</div>
</div>
</section>
<!-- ============================================================
CIRCULARITY EXPLAINED
============================================================ -->
<section class="content-section alt">
<div class="container">
<div class="info-grid">
<div class="info-text">
<div class="section-label">Advanced Tests</div>
<h2>What Is the <span class="gradient-text">Circularity Test</span>?</h2>
<p>The circularity test — also called the circular error test or controller circularity test — measures how evenly your analog stick moves around its full range of motion.</p>
<p>A perfect analog stick, when rotated in a circle at full extension, should trace a perfect circle. Worn sticks, damaged housing, or accumulation of debris can cause flat spots, uneven sections, or distortions in the circle.</p>
<h3 style="margin-top:16px; margin-bottom:8px;">How Our Circularity Score Works</h3>
<ul class="info-list">
<li>You trace a circle with the stick at full extension</li>
<li>We record hundreds of position samples</li>
<li>Algorithm calculates average radius and standard deviation</li>
<li>Score = 100 minus the coefficient of variation (×200)</li>
<li>100% = perfect circle, lower = more distortion</li>
</ul>
<div class="info-callout">
<p><strong>Score Guide:</strong> 90%+ Excellent | 80–90% Good | 65–80% Fair | Below 65% = significant wear, stick replacement recommended.</p>
</div>
</div>
<div class="info-text">
<div class="section-label">Calibration</div>
<h2>Controller <span class="gradient-text">Deadzone</span> Explained</h2>
<p>The deadzone is a circular zone at the center of the analog stick where input is intentionally ignored by the game or driver. Its purpose is to prevent minor imperfections in stick centering from causing unintended input.</p>
<p>Game developers set deadzones to account for the natural variation in analog stick hardware. However, as sticks age and drift increases, larger deadzones are needed — which reduces precision.</p>
<h3 style="margin-top:16px; margin-bottom:8px;">Deadzone Types</h3>
<ul class="info-list">
<li><strong>Axial deadzone:</strong> Separate deadzones on X and Y axes — can cause "cross-shaped" dead area</li>
<li><strong>Radial deadzone:</strong> Circular deadzone (what most modern games use) — feels more natural</li>
<li><strong>Scaled radial:</strong> Input is remapped to start at 0 after the deadzone — eliminates the "snap" feel</li>
</ul>
<p>Our deadzone visualizer shows a radial deadzone. Use our slider to understand how different deadzone sizes affect your stick's active input range.</p>
</div>
</div>
</div>
</section>
<!-- ============================================================
HOW TO FIX STICK DRIFT
============================================================ -->
<section class="content-section">
<div class="container">
<div class="section-label">Solutions</div>
<h2>How to <span class="gradient-text">Fix Stick Drift</span></h2>
<p class="lead">Once our controller drift test confirms you have stick drift, here are your options from easiest to most involved.</p>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">🌬️</div>
<h3>Compressed Air Cleaning</h3>
<p>Blow compressed air around the base of the stick. Dust and debris can interfere with the potentiometer. This is the first thing to try — it works in about 30% of cases and costs nothing.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🧴</div>
<h3>Contact Cleaner Spray</h3>
<p>Electronics contact cleaner (DeoxIT D5 or similar) sprayed into the stick base can clean the potentiometer tracks and eliminate drift. Works best on mild to moderate drift cases. Takes 5–10 minutes.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🎮</div>
<h3>Increase In-Game Deadzone</h3>
<p>As a temporary workaround, increase the deadzone setting in your game or on your platform. This masks the drift but reduces precision. Not a long-term solution but extends controller usability.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🔧</div>
<h3>Replace the Stick Module</h3>
<p>The stick module (potentiometer assembly) can be replaced for $5–15. For PS5/Xbox, iFixit guides make this doable for most people with basic soldering skills. Uses improved Alps or ALPS-compatible modules.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🏭</div>
<h3>Warranty / Repair Service</h3>
<p>Sony offers free drift repairs for DualSense controllers in many regions. Xbox controllers have a standard 90-day warranty. For paid repair, uBreakiFix and similar services typically charge $30–50.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🛒</div>
<h3>Hall Effect Stick Replacement</h3>
<p>Hall effect sticks use magnets instead of physical contact — they never wear out and never drift. Brands like GuliKit offer drop-in replacement kits for PS4, PS5, and Xbox controllers.</p>
</div>
</div>
</div>
</section>
<!-- ============================================================
FAQ
============================================================ -->
<section class="content-section alt" id="faq">
<div class="container">
<div class="section-label" style="text-align:center;">FAQ</div>
<h2 style="text-align:center; margin-bottom:40px;">Frequently Asked Questions</h2>
<div class="faq-list">
<div class="faq-item">
<div class="faq-question">
How do I know if my controller has stick drift?
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="faq-answer">
<div class="faq-answer-inner">
<p>The easiest way is to connect your controller to this tester and watch the stick position canvases. If the dot moves away from center without you touching the stick, you have drift.</p>
<p>You can also run our 5-second Drift Test: place the controller on a flat surface without touching it, click Start, and we'll give you a precise percentage and pass/fail verdict.</p>
<p>In-game signs include: character moving on its own, camera rotating unexpectedly, or crosshair drifting off target.</p>
</div>
</div>
</div>
<div class="faq-item">
<div class="faq-question">
Does this gamepad tester work with PS5 controllers?
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="faq-answer">
<div class="faq-answer-inner">
<p>Yes! The PS5 DualSense controller is fully supported. Connect it via USB-C on any Windows PC or Mac, open this page in Chrome or Edge, and press any button to activate it.</p>
<p>The tester automatically detects DualSense and shows correct PS5 button labels (×○□△, Create, Options, etc.). Vibration testing also works with DualSense over USB in Chrome.</p>
</div>
</div>
</div>
<div class="faq-item">
<div class="faq-question">
Why does my stick show a small value even without touching it?
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="faq-answer">
<div class="faq-answer-inner">
<p>Small values (under 2–3%) are normal and expected from all analog sticks. This is called "resting noise" — minor electrical variation from the potentiometer. Game deadzones are specifically designed to ignore this range.</p>
<p>Values consistently above 4% at rest are borderline, and values above 8% are definitively drift. Our drift test accounts for this by classifying results into three categories.</p>
</div>
</div>
</div>
<div class="faq-item">
<div class="faq-question">
What is a good circularity score?
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="faq-answer">
<div class="faq-answer-inner">
<p>Score interpretation:</p>
<ul>
<li><strong>90–100%:</strong> Excellent — stick is in near-perfect condition</li>
<li><strong>80–90%:</strong> Good — minor wear, no impact on gameplay</li>
<li><strong>65–80%:</strong> Fair — noticeable wear, may affect precision games</li>
<li><strong>Below 65%:</strong> Poor — significant wear, stick replacement recommended</li>
</ul>
<p>For best results, make 2–3 slow, deliberate full rotations at maximum stick extension during the test.</p>
</div>
</div>
</div>
<div class="faq-item">
<div class="faq-question">
Does this tester work with Xbox controllers?
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="faq-answer">
<div class="faq-answer-inner">
<p>Yes, Xbox One, Xbox Series S, and Xbox Series X controllers are fully supported via USB cable or Bluetooth on Windows. The tester auto-detects Xbox controllers and displays A/B/X/Y button labels.</p>
<p>For best Bluetooth support on Windows, use the Xbox Wireless Adapter or connect via USB. Note that vibration testing over Bluetooth may not work in all browsers.</p>
</div>
</div>
</div>
<div class="faq-item">
<div class="faq-question">
Why doesn't the rumble test work on my controller?
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="faq-answer">
<div class="faq-answer-inner">
<p>The Vibration API has limited browser support. Rumble testing works best in:</p>
<ul>
<li>Chrome or Edge on Windows with controller connected via USB</li>
<li>Chrome on Android (for mobile controllers)</li>
</ul>
<p>Firefox currently doesn't support the <code>vibrationActuator</code> API. Safari has partial support. If rumble doesn't work, try Chrome with a USB connection.</p>
</div>
</div>
</div>
<div class="faq-item">
<div class="faq-question">
Is my controller data sent to your servers?
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="faq-answer">
<div class="faq-answer-inner">
<p>No. All processing happens entirely in your browser using the Gamepad API. No controller data, button presses, or test results are ever sent to our servers. We don't store or transmit any input data.</p>
<p>The Gamepad API is a standard W3C browser API that allows websites to read controller input locally — similar to how keyboard and mouse input works.</p>
</div>
</div>
</div>
<div class="faq-item">
<div class="faq-question">
My controller is connected but not showing up. What should I do?
<svg class="faq-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
</div>
<div class="faq-answer">
<div class="faq-answer-inner">
<p>The Gamepad API requires you to press a button on the controller after connecting it — this is a browser security requirement. Try these steps:</p>
<ul>
<li>Press any button on the controller after connecting</li>
<li>Refresh the page, reconnect, then press a button</li>
<li>Try a different USB port or cable</li>
<li>Use Chrome or Edge browser (best Gamepad API support)</li>
<li>On PS4/PS5 via Bluetooth on PC: try DS4Windows software for better compatibility</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============================================================
FOOTER
============================================================ -->
<footer>
<div class="footer-inner">
<div class="footer-brand">
<a href="/" class="logo" style="margin-bottom:12px;">
<div class="logo-icon">🎮</div>
TwinStick<span>Gaming</span>
</a>
<p>Free online gamepad testing tools for gamers. Test stick drift, deadzone, circularity, and more — no download needed.</p>
</div>
<div class="footer-col">
<h4>Tools</h4>
<a href="/">Gamepad Tester</a>
<a href="/">Stick Drift Test</a>
<a href="/">Circularity Test</a>
<a href="/">Deadzone Calibrator</a>
</div>
<div class="footer-col">
<h4>Guides</h4>
<a href="#stick-drift">What Is Stick Drift?</a>
<a href="#how-it-works">How to Test Controllers</a>
<a href="#faq">FAQ</a>
</div>
<div class="footer-col">
<h4>Alternatives</h4>
<a href="https://www.hlplanet.com/gamepad-tester/" target="_blank" rel="noopener">HLPlanet Gamepad Tester</a>
<a href="https://hardwaretester.com/gamepad" target="_blank" rel="noopener">HardwareTester Gamepad</a>
</div>
</div>
<div class="footer-bottom">
<p>© 2025 TwinStickGaming.com — Free Online Gamepad Tester & Stick Drift Checker</p>
<p>Uses the <a href="https://w3c.github.io/gamepad/" target="_blank" rel="noopener">W3C Gamepad API</a> — All data processed locally in your browser.</p>
</div>
</footer>
<script src="js/gamepad.js"></script>
</body>
</html>
Sitemap
Кол-во: 0
XML-карта сайта для поисковиков
?
Sitemap.xml помогает поисковику быстрее находить и индексировать страницы. Особенно важен для крупных сайтов и новых страниц, на которые ещё нет входящих ссылок.
Robots.txt не содержит ссылку на карту сайта. Рекомендуется добавить карту сайта и указать ссылку на нее в robots.txt.
Внутренние ссылки
Кол-во: 7
Ссылки на другие страницы своего сайта
?
Внутренние ссылки распределяют ссылочный вес между страницами и помогают поисковику обходить сайт. Пустые анкоры и ссылки на запрещённые robots.txt страницы — типичные ошибки.
Внутренних ссылок на странице 7 оптимально.
Внутренние ссылки не запрещены к индексации в robots.txt.
Показать внутренние ссылки
| Url | Анкор | Состояние | Анализировать |
|---|---|---|---|
| / |
<div class="logo-icon">🎮</div>
TwinStick<span>Gaming</span>
|
|
Анализировать url |
| / |
Gamepad Tester
|
|
Анализировать url |
| / |
<div class="logo-icon">🎮</div>
TwinStick<span>Gaming</span>
|
|
Анализировать url |
| / |
Gamepad Tester
|
|
Анализировать url |
| / |
Stick Drift Test
|
|
Анализировать url |
| / |
Circularity Test
|
|
Анализировать url |
| / |
Deadzone Calibrator
|
|
Анализировать url |
Внешние ссылки
Кол-во: 3
Ссылки на сторонние сайты
?
Исходящие внешние ссылки передают часть ссылочного веса на чужие сайты. Ссылки на авторитетные ресурсы безопасны; ссылки на мусорные сайты могут навредить репутации страницы.
Внешних ссылок на странице 3 оптимально.
Показать внешние ссылки
| Url | Анкор | Анализировать |
|---|---|---|
| hlplanet.com |
HLPlanet Gamepad Tester
|
Анализировать url |
| hardwaretester.com |
HardwareTester Gamepad
|
Анализировать url |
| w3c.github.io |
W3C Gamepad API
|
Анализировать url |
Конкуренты Готовность: 0%
Конкуренты в Яндексе
Кол-во: 0
Топ сайтов-конкурентов в Яндексе
?
Сайты, чаще всего появляющиеся в ТОПе Яндекса по запросам из семантического ядра этой страницы.
Мы не нашли у вас конкурентов в Яндексе. Сайт или очень молодой или плохо продвигается.
Конкурентов в ТОП-10 Яндекса не нашлось.
Конкуренты в Google
Кол-во: 0
Топ сайтов-конкурентов в Google
?
Сайты, чаще всего появляющиеся в ТОПе Google по запросам из семантического ядра этой страницы.
Конкуренты в Google тоже не найдены. Займитесь продвижением сайта!
Конкурентов в ТОП-10 Google не нашлось.
ЗоЗПП: права потребителей Готовность: 100%
Нарушения
Не выявлены
Признаков дистанционной продажи товаров (интернет-магазина) не обнаружено — требования ЗоЗПП о раскрытии информации продавца к сайту не применяются. Нарушений нет.
ФЗ-149: рекомендательные технологии Готовность: 100%
Нарушения
Не выявлены
Рекомендательные блоки («с этим покупают», «похожие товары» и т.п.) на сайте не обнаружены — требования ст. 10.7 ФЗ-149 к сайту не применяются. Нарушений нет.
ФЗ-38: реклама Готовность: 100%
Нарушения
Не выявлены
Рекламных тематик с обязательными оговорками (медицина, БАД, кредиты и займы, новостройки) на сайте не обнаружено. Нарушений нет.
ФЗ-436: защита детей Готовность: 100%
Нарушения
Не выявлены
Признаков информационной продукции (новости, видео, книги, игры, курсы) не обнаружено — обязательная возрастная маркировка по ФЗ-436 сайту не требуется. Нарушений нет.
Вердикт
Выполнен подробный анализ сайта twinstickgaming.com: готовность на 64%. Чтобы выполнить все условия и попасть на первую страницу выдачи поисковых систем требуется:
Исправьте ошибки в мета-тегах.
Исправьте ошибки индексации.
Поделитесь с друзьями: