Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | import LocationButton from '../LocationButton';
import LocationMarker from '../LocationMarker';
import { ButtonStyle, MarkerStyle } from './type';
type WatchPositionFnType = (
successCallback: PositionCallback,
errorCallback?: PositionErrorCallback | null,
options?: PositionOptions
) => number | Promise<number | string>;
export type Options = {
buttonStyle?: ButtonStyle;
markerStyle?: MarkerStyle;
showAccuracyRadius?: boolean;
watchPositionFn?: WatchPositionFnType;
};
/**
* Adds a button to the toolbar for user to click and see their current position
* on the map with a marker.
*/
class CurrentLocation {
controlUI: LocationButton;
locationMarker: LocationMarker;
map: google.maps.Map;
positionCount: number;
positionOptions: PositionOptions;
watchId?: number | string;
watchPositionFn: WatchPositionFnType;
constructor(map: google.maps.Map, options: Options = {}) {
this.map = map;
this.positionOptions = {
enableHighAccuracy: true
};
this.locationMarker = new LocationMarker(map, options);
this.controlUI = new LocationButton(map, options);
this.positionCount = 0;
this.watchId = 0;
const defaultWatchPositionFn = (
successCallback: PositionCallback,
errorCallback?: PositionErrorCallback | null,
options?: PositionOptions
): number => {
return navigator.geolocation.watchPosition(successCallback, errorCallback, options);
};
this.watchPositionFn = options.watchPositionFn || defaultWatchPositionFn;
this.controlUI.setOnClickListener(() => {
if (!this.watchId) {
this.controlUI.setEnabled(false);
this.controlUI.animate(true);
this.startWatchPosition();
} else {
this.locationMarker.center();
}
});
}
/**
* Starts watching for the user position.
* This will be called automatically each time the position changes.
* */
startWatchPosition(): void {
const id = this.watchPositionFn(
(pos) => {
this.updatePosition(pos);
},
(err: GeolocationPositionError) => {
this.setError(err);
},
this.positionOptions
);
if (id instanceof Promise) {
// eslint-disable-next-line no-return-assign
id.then((id) => (this.watchId = id));
} else {
this.watchId = id;
}
}
/**
* Everytime the position changes, the location of the marker also changes
* as well as some ControlUI settings
* */
updatePosition(pos: GeolocationPosition): void {
// eslint-disable-next-line no-plusplus
this.locationMarker.update(pos);
this.controlUI.setEnabled(true);
this.controlUI.animate(false);
}
/**
* When an error occurs during the watchPosition (e.g. PERMISSION_DENIED) an alert is showed,
* the watchId is set to undefined (to allow a re-watching) and the ControlUI settings are set to default
* */
setError(err: GeolocationPositionError): void {
this.watchId = undefined;
this.controlUI.setEnabled(true);
this.controlUI.animate(false);
alert(err.message);
}
}
export default function addMapCurrentMarker(
map: google.maps.Map,
options: Options = {}
): CurrentLocation {
return new CurrentLocation(map, options);
}
|