Hyperapp — это легковесный JavaScript-фреймворк, ориентированный на управление состоянием и виртуальный DOM. Несмотря на минимализм, он позволяет интегрировать внешние браузерные API, включая Geolocation API для работы с GPS.
Для начала создаётся минимальная структура приложения:
import { h, app } from "https://unpkg.com/hyperapp@2.0.15?module";
const state = {
coords: null,
error: null
};
const actions = {
setCoords: (coords) => ({ coords }),
setError: (error) => ({ error }),
};
const view = (state, actions) => h("div", {}, [
state.coords
? h("p", {}, `Широта: ${state.coords.latitude}, Долгота: ${state.coords.longitude}`)
: h("p", {}, "Координаты не определены"),
state.error && h("p", { style: { color: "red" } }, `Ошибка: ${state.error}`),
h("button", { onclick: () => actions.getLocation() }, "Определить местоположение")
]);
Geolocation API встроен в большинство современных браузеров. Для
запроса текущей позиции используется метод
navigator.geolocation.getCurrentPosition. В Hyperapp этот
процесс удобно оборачивать в action:
actions.getLocation = () => (state, actions) => {
if (!navigator.geolocation) {
actions.setError("Geolocation API не поддерживается этим браузером");
return;
}
navigator.geolocation.getCurrentPosition(
(position) => {
actions.setCoords(position.coords);
},
(error) => {
switch(error.code) {
case error.PERMISSION_DENIED:
actions.setError("Доступ к местоположению запрещен пользователем");
break;
case error.POSITION_UNAVAILABLE:
actions.setError("Информация о местоположении недоступна");
break;
case error.TIMEOUT:
actions.setError("Время запроса местоположения истекло");
break;
default:
actions.setError("Неизвестная ошибка при определении местоположения");
}
},
{ enableHighAccuracy: true, timeout: 5000, maximumAge: 0 }
);
};
Ключевые моменты:
enableHighAccuracy: true — повышает точность GPS, но
увеличивает потребление энергии.timeout — максимальное время ожидания ответа.maximumAge — максимальный возраст кэшированных
координат.Для постоянного отслеживания позиции используется
navigator.geolocation.watchPosition, который возвращает
идентификатор наблюдателя:
let watchId = null;
actions.startTracking = () => (state, actions) => {
if (!navigator.geolocation) {
actions.setError("Geolocation API не поддерживается");
return;
}
watchId = navigator.geolocation.watchPosition(
(position) => actions.setCoords(position.coords),
(error) => actions.setError(error.message),
{ enableHighAccuracy: true }
);
};
actions.stopTracking = () => () => {
if (watchId !== null) {
navigator.geolocation.clearWatch(watchId);
watchId = null;
}
};
Использование этих методов позволяет реализовать динамическое отображение местоположения на карте или создание приложений для навигации.
Полученные координаты можно передавать в сторонние сервисы, например,
Google Maps или OpenStreetMap. Для Hyperapp создаются отдельные
компоненты или view-фрагменты, которые обновляются при изменении
состояния coords:
const mapView = (coords) =>
coords
? h("iframe", {
src: `https://www.openstreetmap.org/export/embed.html?bbox=${coords.longitude-0.01}%2C${coords.latitude-0.01}%2C${coords.longitude+0.01}%2C${coords.latitude+0.01}&layer=mapnik`,
width: "100%",
height: "400"
})
: h("p", {}, "Карта недоступна");
При работе с GPS необходимо учитывать:
watchPosition с разумными интервалами.Hyperapp позволяет эффективно управлять состоянием, и сочетание его реактивной модели с Geolocation API делает возможным создание легких, динамичных и отзывчивых приложений с GPS-навигацией.