Дізнайтеся з цієї статті, як ми просто використовували гіроскоп і акселерометр у браузері для заголовка сайту JS Республіка (звісно з мобільного) завдяки Gyro.js.
Маленьке нагадування
Перш ніж розпочати пояснення щодо їх використання в браузері, давайте швидко розглянемо, що це за датчики.
Ваш мобільний телефон використовує гіроскоп щоб знати його орієнтацію в просторі, цю орієнтацію виражають відповідно до альфа, бета і гамма, трьома кутами повороту в градусах навколо осей Z, X і Y.акселерометр використовується для вимірювання рухів вашого телефону в метрах/секунду² (вимірювання прискорення). У поєднанні ці два датчики можуть вимірювати прискорення обертання пристрою.
Випадок (не такий) простий
У HTML5 є два API для отримання вимірювань із цих датчиків: API орієнтації пристрою та API devicemotion , перший для відновлення орієнтації телефону (альфа, бета, гамма), а другий для відновлення прискорення рухів. Спочатку ми можемо отримати всю необхідну інформацію за допомогою кількох рядків JavaScript:
window.addEventListener('devicemotion', (eventData) => { console.log(` Angle Alpha : ${eventData.rotationRate.alpha} Angle Beta : ${eventData.rotationRate.beta} Angle Gamma : ${eventData.rotationRate.gamma} Accélération en X : ${eventData.accelerationIncludingGravity.x} Accélération en Y : ${eventData.accelerationIncludingGravity.Y} Accélération en Z : ${eventData.accelerationIncludingGravity.Z} `); }, false);
З огляду на простоту API, не видається необхідним використовувати будь-яку бібліотеку! Ну, це не так просто, тому що його використання вимагає деяких тонкощів, які не очевидні на перший погляд.
Перше і, мабуть, найважливіше - це калібрування. Справді, «нейтральний» стан ваших датчиків має місце, коли телефон нерухомий і розміщений на горизонтальній поверхні. Однак більшість часу ви використовуєте свій телефон у портретному режимі, більш-менш обличчям. Тому необхідно провести калібрування, врахувати, що «нейтральне» положення – це те, яке має телефон під час завантаження сторінки, і наївним підходом було б просто зробити віднімання таким чином:
let initialOrientation = null; window.addEventListener('devicemotion', (eventData) => { const r = eventData.rotationRate; initialOrientation = initialOrientation || Object.assign({}, r); // first time console.log(` Angle calibré Alpha : ${r.alpha - initialOrientation.alpha } Angle calibré Beta : ${r.beta - initialOrientation.beta} Angle calibré Gamma : ${r.gamma -initialOrientation.gamma} `); }, false);
Але як зазначено @yvt в її питання у проекті Gyro.js цей підхід неправильний!
Він пояснює, що Кути Ейлера Використовувані для визначення орієнтації телефону не можна об’єднати, якщо вони діють на дві різні осі простим додаванням або відніманням. І якщо ми хочемо виконати цю маніпуляцію, елегантний спосіб зробити це – використовувати Кватерніони. Я дозволю вам насолоджуватися виконанням калібрування для менш математичних: Об’єднайте запит на витяг
Gyro.js також керує за вас виявленням присутності API HTML5 і додає над ними API «витягування», який дозволяє отримувати останні відомі вимірювання з датчиків за запитом. Дуже практична річ, коли ви використовуєте requestAnimationFrame як ми в продовженні.
Використання Gyro.js
Gyro.js — це більше сценарій, ніж бібліотека, створена Том Галлачер, утиліта включає лише кілька методів і властивостей:
- gyro.frequency = 500 // періодичність, з якою скрипт викликає зворотний виклик події
- gyro.getOrientation() // повертає поточні вимірювання
- gyro.calibrate() // калібрувати отримані вимірювання
- gyro.startTracking(function(o){…}) // почати періодичний виклик зворотного виклику події
- gyro.stopTracking() // зупиняємо періодичний виклик зворотного виклику події
- gyro.hasFeature('devicemotion') // перевіряє, чи підтримує браузер MozOrientation, devicemotion або deviceorientation
- gyro.getFeatures() // повертає API цих підтримуваних датчиків
Після різних тестів ми отримали найкращий рендеринг, не використовуючи періодичний зворотний виклик, запропонований API Gyro.js, а проходячи через requestAnimationFrame. Це дає можливість плавно асоціювати рух з орієнтацією телефону. Спрощена реалізація цієї концепції виглядає так:
gyro.stopTracking(); // Stop periodic calls gyro.calibrate(); // Calibrate measurement during the page loading const speed = 0.01; // A arbitrary speed ... let lastTimestamp = null; const refresh = function(timestamp) { if (lastTimestamp !== null) { // execute only if timestamp is valued const delay = timestamp - lastTimestamp; // duration since the last call const o = gyro.getOrientation(); // retrieves the last measures const step = speed * delay; // Apply step on the background-position in our example, but // you can use directly the angles for a CSS rotation property // for instance. } lastTimestamp = timestamp; // save current timestamp for the next call window.requestAnimationFrame(refresh); // call for the next refresh (max 60 times per seconde) }; window.requestAnimationFrame(refresh); // first callЯ настійно рекомендую округлити отримані вимірювання, оскільки вони постійно змінюються,
навіть коли телефон нерухомий. Це дозволить уникнути небажаних ефектів тремтіння або руху.
Кінцевий результат виглядає так: