У статьи есть интерактивная версия. Вы можете открыть его и поиграть с ориентацией устройства прямо с мобильного устройства.
Доступ к ориентации устройства в чистом JavaScript
В Javascript вы можете получить доступ к данным об ориентации вашего устройства, прослушивая событие deviceorientation. Это так просто:
window.addEventListener('deviceorientation', handleOrientation);
function handleOrientation(event) {
const alpha = event.alpha;
const beta = event.beta;
const gamma = event.gamma;
// Do stuff...
}
Вот значение углов alpha
, beta
и gama
:
Источник изображения: newnow.co
Но! Не каждый браузер позволяет получить доступ к данным ориентации без разрешения пользователя. Например, в iOS 13 Apple ввела метод requestPermission. Он должен срабатывать при действии пользователя (щелчок, касание или аналогичный).
Пример доступа к ориентации устройства становится немного сложнее:
function onClick() {
if (typeof DeviceMotionEvent.requestPermission === 'function') {
// Handle iOS 13+ devices.
DeviceMotionEvent.requestPermission()
.then((state) => {
if (state === 'granted') {
window.addEventListener('devicemotion', handleOrientation);
} else {
console.error('Request to access the orientation was rejected');
}
})
.catch(console.error);
} else {
// Handle regular non iOS 13+ devices.
window.addEventListener('devicemotion', handleOrientation);
}
}
Если вы включите переключатель ориентации устройства в интерактивной версии этого поста, вы должны увидеть, под какими углами сообщает ваше устройство.
Отладка доступа к ориентации в браузере
В случае, если вы используете настольное устройство, вы можете имитировать вращение устройства на вкладке «Датчики» в dev-tools:
Прохладный! Итак, теперь у нас есть доступ к ориентации устройства, и мы даже можем протестировать это в браузере!
Хук React для доступа к ориентации устройства
Последний шаг, который я хотел бы сделать, - это придумать крючок React, который инкапсулирует для меня выборку ориентации и упростит его использование в компонентах React (например, тот, который показывает вам углы выше). ).
Вот пример ловушки useDeviceOrientation.ts
, написанной на TypeScript:
import { useCallback, useEffect, useState } from 'react';
type DeviceOrientation = {
alpha: number | null,
beta: number | null,
gamma: number | null,
}
type UseDeviceOrientationData = {
orientation: DeviceOrientation | null,
error: Error | null,
requestAccess: () => Promise<boolean>,
revokeAccess: () => Promise<void>,
};
export const useDeviceOrientation = (): UseDeviceOrientationData => {
const [error, setError] = useState<Error | null>(null);
const [orientation, setOrientation] = useState<DeviceOrientation | null>(null);
const onDeviceOrientation = (event: DeviceOrientationEvent): void => {
setOrientation({
alpha: event.alpha,
beta: event.beta,
gamma: event.gamma,
});
};
const revokeAccessAsync = async (): Promise<void> => {
window.removeEventListener('deviceorientation', onDeviceOrientation);
setOrientation(null);
};
const requestAccessAsync = async (): Promise<boolean> => {
if (!DeviceOrientationEvent) {
setError(new Error('Device orientation event is not supported by your browser'));
return false;
}
if (
DeviceOrientationEvent.requestPermission
&& typeof DeviceMotionEvent.requestPermission === 'function'
) {
let permission: PermissionState;
try {
permission = await DeviceOrientationEvent.requestPermission();
} catch (err) {
setError(err);
return false;
}
if (permission !== 'granted') {
setError(new Error('Request to access the device orientation was rejected'));
return false;
}
}
window.addEventListener('deviceorientation', onDeviceOrientation);
return true;
};
const requestAccess = useCallback(requestAccessAsync, []);
const revokeAccess = useCallback(revokeAccessAsync, []);
useEffect(() => {
return (): void => {
revokeAccess();
};
}, [revokeAccess]);
return {
orientation,
error,
requestAccess,
revokeAccess,
};
};
Крючок можно использовать следующим образом:
import React from 'react';
import Toggle from './Toggle';
import { useDeviceOrientation } from './useDeviceOrientation';
const OrientationInfo = (): React.ReactElement => {
const { orientation, requestAccess, revokeAccess, error } = useDeviceOrientation();
const onToggle = (toggleState: boolean): void => {
const result = toggleState ? requestAccess() : revokeAccess();
};
const orientationInfo = orientation && (
<ul>
<li>ɑ: <code>{orientation.alpha}</code></li>
<li>β: <code>{orientation.beta}</code></li>
<li>γ: <code>{orientation.gamma}</code></li>
</ul>
);
const errorElement = error ? (
<div className="error">{error.message}</div>
) : null;
return (
<>
<Toggle onToggle={onToggle} />
{orientationInfo}
{errorElement}
</>
);
};
export default OrientationInfo;
Демо
Наконец, имея доступ к ориентации устройства, давайте имитируем трехмерное пространство и возможность смотреть на объект с трехмерной перспективы, вращая мобильное устройство. Представьте, что у вас есть виртуальный товар, и вы хотите увидеть его под разными углами и с разных сторон, прежде чем положить его в корзину.
Мы будем использовать простой трехмерный куб, созданный с использованием чистого CSS с использованием свойств перспектива, перспектива-происхождение и преобразование (вы можете найти полный пример со стилями на css-tricks.com).
Вот и наш гиро-куб, который вы должны видеть под разными углами в зависимости от ориентации вашего устройства!
Если вы читаете статью с ноутбука, вот как демоверсия должна работать на мобильных устройствах, если вы запустите интерактивную версию этого поста:
Вы можете найти все примеры кода из этой статьи (включая стили Gyro-cube) в репозитории trekhleb.github.io.
Надеюсь, этот пример был вам полезен! Я также надеюсь, что вы придумаете гораздо более интересный и реалистичный вариант использования для ориентации устройства, чем Gyro-Cube, описанный выше 😄 Удачного кодирования!