UNPKG

@expofp/floorplan

Version:

Interactive floor plan library for expos and events

2 lines (1 loc) 1.61 kB
import{useCallback as v,useRef as e}from"react";import A from"../../tools/logger";import{haversineDistance as O}from"../../utils/haversineDistance";import{hasMeaningfulChange as H,MOVE_THRESHOLD_M as E,normalizeHeading as L}from"./utils";const _=120,C=3e3,G=360;export function useUserLocationAndHeading(g){const o=e(null),s=e(null),f=e(0),u=e(null),d=e(!1),t=e(null),a=e(!1),l=e(null),h=n=>g(n),m=n=>{const r=Date.now();if(r-f.current<_)return;const i=u.current;if(!t.current){t.current=n,f.current=r,u.current=n,h(n);return}const w=O(t.current.lat,t.current.lng,n.lat,n.lng);let c;a.current?w<=E?(a.current=!1,t.current=n,c={...t.current,heading:n.heading}):(t.current=n,c=n):w>=E?(a.current=!0,t.current=n,l.current=null,c=n):(l.current==null&&(l.current=r),r-l.current>C&&(t.current=n),c={...t.current,heading:n.heading}),!(i&&!H(i,c))&&(f.current=r,u.current=c,h(c))},R=v(n=>{const r=n.webkitCompassHeading??(n.alpha!=null?G-n.alpha:null);if(r==null)return;const i=L(r);s.current!==i&&(s.current=i,u.current&&m({...u.current,heading:i}))},[g]);return{startGeolocation:()=>{o.current==null&&(o.current=navigator.geolocation.watchPosition(n=>{m({lat:n.coords.latitude,lng:n.coords.longitude,heading:s.current})},n=>A.warn("Geolocation watch error:",n),{enableHighAccuracy:!0,maximumAge:0}))},startOrientation:()=>{d.current||(d.current=!0,window.addEventListener("deviceorientation",R,!0))},stopGeolocation:()=>{o.current!=null&&(navigator.geolocation.clearWatch(o.current),o.current=null),t.current=null,a.current=!1},stopOrientation:()=>{d.current=!1,window.removeEventListener("deviceorientation",R,!0)}}}