Skip to content

Commit 1df495a

Browse files
committed
feature(types): add TS types
1 parent 0514a8f commit 1df495a

File tree

1 file changed

+311
-0
lines changed

1 file changed

+311
-0
lines changed

lib/types/locar.d.ts

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
declare module "locar" {
2+
import * as THREE from "three";
3+
4+
/**
5+
* Generic, small event emitter that only stores a single handler per event name.
6+
*/
7+
export class EventEmitter {
8+
protected eventHandlers: Record<string, (...args: any[]) => void>;
9+
on(eventName: string, handler: (...args: any[]) => void): void;
10+
emit(eventName: string, ...params: any[]): void;
11+
}
12+
13+
/**
14+
* Spherical Mercator (EPSG:3857) projection used by `LocationBased`.
15+
*/
16+
export class SphMercProjection {
17+
constructor();
18+
/**
19+
* @returns [easting, northing]
20+
*/
21+
project(lon: number, lat: number): [number, number];
22+
/**
23+
* @returns [lon, lat]
24+
*/
25+
unproject(projected: [number, number]): [number, number];
26+
getID(): "epsg:3857";
27+
}
28+
29+
/**
30+
* Options for GPS in `LocationBased`.
31+
* Mirrored from `setGpsOptions(...)`
32+
*/
33+
export interface GpsOptions {
34+
/**
35+
* Meters the device must move to accept the next GPS reading.
36+
*/
37+
gpsMinDistance?: number;
38+
/**
39+
* Minimum accuracy in meters to accept a GPS reading.
40+
*/
41+
gpsMinAccuracy?: number;
42+
}
43+
44+
/**
45+
* Optional logger object passed to `LocationBased` for debug.
46+
*/
47+
export interface ServerLogger {
48+
/**
49+
* Should send data to server. Implementation-specific in userland.
50+
*/
51+
sendData(endpoint: string, data: any): Promise<Response> | Response;
52+
}
53+
54+
/**
55+
* Main location AR class.
56+
*/
57+
export class LocationBased extends EventEmitter {
58+
readonly scene: THREE.Scene;
59+
readonly camera: THREE.Camera;
60+
61+
constructor(
62+
scene: THREE.Scene,
63+
camera: THREE.Camera,
64+
options?: GpsOptions,
65+
serverLogger?: ServerLogger | null,
66+
);
67+
68+
/**
69+
* Set the projection (must have `project(lon,lat): [x,y]`).
70+
*/
71+
setProjection(proj: {
72+
project(lon: number, lat: number): [number, number];
73+
}): void;
74+
75+
/**
76+
* Update GPS options at runtime.
77+
*/
78+
setGpsOptions(options?: GpsOptions): void;
79+
80+
/**
81+
* Start real GPS (`navigator.geolocation.watchPosition`).
82+
*/
83+
startGps(): Promise<boolean> | boolean;
84+
85+
/**
86+
* Stop real GPS.
87+
*/
88+
stopGps(): boolean;
89+
90+
/**
91+
* Send a fake GPS position.
92+
*/
93+
fakeGps(lon: number, lat: number, elev?: number | null, acc?: number): void;
94+
95+
/**
96+
* Convert lon/lat to world coordinates (needs initial position).
97+
*/
98+
lonLatToWorldCoords(lon: number, lat: number): [number, number];
99+
100+
/**
101+
* Add a THREE object at lon/lat/(elev) and put in the scene.
102+
*/
103+
add(
104+
object: THREE.Object3D,
105+
lon: number,
106+
lat: number,
107+
elev?: number,
108+
properties?: Record<string, any>,
109+
): void;
110+
111+
/**
112+
* Set camera elevation (y).
113+
*/
114+
setElevation(elev: number): void;
115+
116+
/**
117+
* Events:
118+
* - "gpsupdate": `{ position: GeolocationPosition, distMoved: number }``
119+
* - "gpserror": `GeolocationPositionError`
120+
*/
121+
on(
122+
eventName: "gpsupdate",
123+
handler: (data: {
124+
position: GeolocationPosition;
125+
distMoved: number;
126+
}) => void,
127+
): void;
128+
on(
129+
eventName: "gpserror",
130+
handler: (error: GeolocationPositionError) => void,
131+
): void;
132+
on(eventName: string, handler: (...args: any[]) => void): void;
133+
}
134+
135+
/**
136+
* Small webcam wrapper that creates a hidden `<video>` and a `THREE.VideoTexture`.
137+
*/
138+
export interface WebcamStartedEvent {
139+
texture: THREE.VideoTexture;
140+
}
141+
export interface WebcamErrorEvent {
142+
code: string;
143+
message: string;
144+
}
145+
146+
export class Webcam extends EventEmitter {
147+
/**
148+
* @param constraints `MediaDevices.getUserMedia` constraints
149+
* @param videoElementSelector selector for an existing `<video>`; if falsy, it creates one
150+
*/
151+
constructor(
152+
constraints?: MediaStreamConstraints,
153+
videoElementSelector?: string | null,
154+
);
155+
156+
/**
157+
* Texture that streams the camera feed.
158+
*/
159+
readonly texture: THREE.VideoTexture;
160+
161+
/**
162+
* Free GPU resources.
163+
*/
164+
dispose(): void;
165+
166+
// events
167+
on(
168+
eventName: "webcamstarted",
169+
handler: (e: WebcamStartedEvent) => void,
170+
): void;
171+
on(eventName: "webcamerror", handler: (e: WebcamErrorEvent) => void): void;
172+
on(eventName: string, handler: (...args: any[]) => void): void;
173+
}
174+
175+
/**
176+
* Click handler/raycaster wrapper.
177+
*/
178+
export class ClickHandler {
179+
constructor(renderer: THREE.WebGLRenderer);
180+
181+
/**
182+
* Cast a ray and return intersects with scene children.
183+
*/
184+
raycast(camera: THREE.Camera, scene: THREE.Scene): THREE.Intersection[];
185+
}
186+
187+
export interface DeviceOrientationControlsOptions {
188+
/**
189+
* 0 < k <= 1. Lower = more smoothing.
190+
*/
191+
smoothingFactor?: number;
192+
/**
193+
* Show iOS permission dialog.
194+
*/
195+
enablePermissionDialog?: boolean;
196+
/**
197+
* Apply inline styles on the created dialog.
198+
*/
199+
enableStyling?: boolean;
200+
/**
201+
* Use `window.confirm(...)` instead of building DOM.
202+
*/
203+
preferConfirmDialog?: boolean;
204+
}
205+
206+
export interface DeviceOrientationGrantedEvent {
207+
target: DeviceOrientationControls;
208+
}
209+
210+
export interface DeviceOrientationErrorEvent {
211+
code: string;
212+
message: string;
213+
error?: string;
214+
}
215+
216+
export class DeviceOrientationControls extends THREE.EventDispatcher {
217+
/**
218+
* @param object usually a `THREE.Camera`
219+
*/
220+
constructor(
221+
object: THREE.Object3D,
222+
options?: DeviceOrientationControlsOptions,
223+
);
224+
225+
/**
226+
* Begin listening to orientation + screenorientation (must be called after permission is granted on iOS).
227+
*/
228+
connect(): void;
229+
230+
/**
231+
* Stop listening.
232+
*/
233+
disconnect(): void;
234+
235+
/**
236+
* iOS: must be called in a user gesture to ask for perms.
237+
*/
238+
requestOrientationPermissions(): void;
239+
240+
/**
241+
* Create the DOM dialog (iOS-style) and wire it to requestOrientationPermissions.
242+
*/
243+
createObtainPermissionGestureDialog(): void;
244+
245+
/**
246+
* Choose `confirm()` vs DOM dialog.
247+
*/
248+
obtainPermissionGesture(): void;
249+
250+
/**
251+
* Call each frame.
252+
*/
253+
update(args?: { theta?: number }): void;
254+
255+
/**
256+
* iOS heading correction.
257+
*/
258+
getCorrectedHeading(): number;
259+
260+
/**
261+
* Provided in AR.js fix — forces re-evaluation of alpha offset.
262+
*/
263+
updateAlphaOffset(): void;
264+
265+
/**
266+
* Getters (radians).
267+
*/
268+
getAlpha(): number;
269+
getBeta(): number;
270+
getGamma(): number;
271+
272+
dispose(): void;
273+
274+
on(
275+
eventName: "deviceorientationgranted",
276+
handler: (ev: DeviceOrientationGrantedEvent) => void,
277+
): void;
278+
on(
279+
eventName: "deviceorientationerror",
280+
handler: (ev: DeviceOrientationErrorEvent) => void,
281+
): void;
282+
on(eventName: string, handler: (...args: any[]) => void): void;
283+
284+
enabled: boolean;
285+
}
286+
287+
/**
288+
* Version string.
289+
*/
290+
export const version: string;
291+
292+
/**
293+
* Default export from build (UMD/ES) is the namespace with all the above.
294+
* Modeled so that:
295+
* `import * as LocAR from "locar"`
296+
* and
297+
* `import LocAR from "locar"``
298+
* both typecheck.
299+
*/
300+
const LocAR: {
301+
EventEmitter: typeof EventEmitter;
302+
SphMercProjection: typeof SphMercProjection;
303+
LocationBased: typeof LocationBased;
304+
Webcam: typeof Webcam;
305+
ClickHandler: typeof ClickHandler;
306+
DeviceOrientationControls: typeof DeviceOrientationControls;
307+
version: string;
308+
};
309+
310+
export default LocAR;
311+
}

0 commit comments

Comments
 (0)