locar 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,7 @@ import * as LocAR from 'locar';
40
40
  as long as you include `locar` as a dependency, e.g. in your `package.json`:
41
41
  ```
42
42
  "dependencies": {
43
- "locar" : "^0.0.10",
43
+ "locar" : "^0.0.11",
44
44
  "three" : "^0.175.0"
45
45
  }
46
46
  ```
package/dist/locar.es.js CHANGED
@@ -1,19 +1,19 @@
1
- var W = (i) => {
2
- throw TypeError(i);
1
+ var q = (r) => {
2
+ throw TypeError(r);
3
3
  };
4
- var S = (i, t, e) => t.has(i) || W("Cannot " + e);
5
- var s = (i, t, e) => (S(i, t, "read from private field"), e ? e.call(i) : t.get(i)), m = (i, t, e) => t.has(i) ? W("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e), u = (i, t, e, n) => (S(i, t, "write to private field"), n ? n.call(i, e) : t.set(i, e), e), f = (i, t, e) => (S(i, t, "access private method"), e);
6
- var k = (i, t, e, n) => ({
7
- set _(r) {
8
- u(i, t, r, e);
4
+ var S = (r, t, i) => t.has(r) || q("Cannot " + i);
5
+ var n = (r, t, i) => (S(r, t, "read from private field"), i ? i.call(r) : t.get(r)), m = (r, t, i) => t.has(r) ? q("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(r) : t.set(r, i), l = (r, t, i, e) => (S(r, t, "write to private field"), e ? e.call(r, i) : t.set(r, i), i), p = (r, t, i) => (S(r, t, "access private method"), i);
6
+ var k = (r, t, i, e) => ({
7
+ set _(c) {
8
+ l(r, t, c, i);
9
9
  },
10
10
  get _() {
11
- return s(i, t, n);
11
+ return n(r, t, e);
12
12
  }
13
13
  });
14
- import * as L from "three";
15
- import { Vector3 as Y, Euler as U, Quaternion as _, EventDispatcher as Z, MathUtils as C } from "three";
16
- var E, N, z, V, X;
14
+ import * as b from "three";
15
+ import { Vector3 as B, Euler as U, Quaternion as F, EventDispatcher as K, MathUtils as C } from "three";
16
+ var E, G, X, Q, V;
17
17
  class $ {
18
18
  /**
19
19
  * Create a SphMercProjection.
@@ -28,8 +28,8 @@ class $ {
28
28
  * @param {number} lat - the latitude.
29
29
  * @return {Array} Two-member array containing easting and northing.
30
30
  */
31
- project(t, e) {
32
- return [f(this, E, N).call(this, t), f(this, E, z).call(this, e)];
31
+ project(t, i) {
32
+ return [p(this, E, G).call(this, t), p(this, E, X).call(this, i)];
33
33
  }
34
34
  /**
35
35
  * Unproject a Spherical Mercator easting and northing.
@@ -37,7 +37,7 @@ class $ {
37
37
  * @return {Array} Two-member array containing longitude and latitude
38
38
  */
39
39
  unproject(t) {
40
- return [f(this, E, V).call(this, t[0]), f(this, E, X).call(this, t[1])];
40
+ return [p(this, E, Q).call(this, t[0]), p(this, E, V).call(this, t[1])];
41
41
  }
42
42
  /**
43
43
  * Return the projection's ID.
@@ -47,19 +47,19 @@ class $ {
47
47
  return "epsg:3857";
48
48
  }
49
49
  }
50
- E = new WeakSet(), N = function(t) {
50
+ E = new WeakSet(), G = function(t) {
51
51
  return t / 180 * this.HALF_EARTH;
52
- }, z = function(t) {
53
- var e = Math.log(Math.tan((90 + t) * Math.PI / 360)) / (Math.PI / 180);
54
- return e * this.HALF_EARTH / 180;
55
- }, V = function(t) {
56
- return t / this.HALF_EARTH * 180;
57
52
  }, X = function(t) {
58
- var e = t / this.HALF_EARTH * 180;
59
- return e = 180 / Math.PI * (2 * Math.atan(Math.exp(e * Math.PI / 180)) - Math.PI / 2), e;
53
+ var i = Math.log(Math.tan((90 + t) * Math.PI / 360)) / (Math.PI / 180);
54
+ return i * this.HALF_EARTH / 180;
55
+ }, Q = function(t) {
56
+ return t / this.HALF_EARTH * 180;
57
+ }, V = function(t) {
58
+ var i = t / this.HALF_EARTH * 180;
59
+ return i = 180 / Math.PI * (2 * Math.atan(Math.exp(i * Math.PI / 180)) - Math.PI / 2), i;
60
60
  };
61
- var D, A, b, H, R, P, M, T, O, w, p, j, Q, F, B;
62
- class K {
61
+ var x, O, P, H, L, A, y, D, T, M, f, j, Y, W, Z;
62
+ class ot {
63
63
  /**
64
64
  * @param {THREE.Scene} scene - The Three.js scene to use.
65
65
  * @param {THREE.Camera} camera - The Three.js camera to use. Should usually
@@ -68,19 +68,19 @@ class K {
68
68
  * setGpsOptions() below.
69
69
  * @param {Object} serverLogger - an object which can optionally log GPS position to a server for debugging. null by default, so no logging will be done. This object should implement a sendData() method to send data (2nd arg) to a given endpoint (1st arg). Please see source code for details. Ensure you comply with privacy laws (GDPR or equivalent) if implementing this.
70
70
  */
71
- constructor(t, e, n = {}, r = null) {
72
- m(this, p);
73
- m(this, D);
74
- m(this, A);
75
- m(this, b);
76
- m(this, H);
77
- m(this, R);
71
+ constructor(t, i, e = {}, c = null) {
72
+ m(this, f);
73
+ m(this, x);
74
+ m(this, O);
78
75
  m(this, P);
79
- m(this, M);
76
+ m(this, H);
77
+ m(this, L);
78
+ m(this, A);
79
+ m(this, y);
80
+ m(this, D);
80
81
  m(this, T);
81
- m(this, O);
82
- m(this, w);
83
- this.scene = t, this.camera = e, u(this, D, new $()), u(this, A, {}), u(this, b, null), u(this, H, 0), u(this, R, 100), u(this, P, null), this.setGpsOptions(n), u(this, M, null), u(this, T, 0), u(this, O, 0), u(this, w, r);
82
+ m(this, M);
83
+ this.scene = t, this.camera = i, l(this, x, new $()), l(this, O, {}), l(this, P, null), l(this, H, 0), l(this, L, 100), l(this, A, null), this.setGpsOptions(e), l(this, y, null), l(this, D, 0), l(this, T, 0), l(this, M, c);
84
84
  }
85
85
  /**
86
86
  * Set the projection to use.
@@ -89,7 +89,7 @@ class K {
89
89
  * containing easting and northing.
90
90
  */
91
91
  setProjection(t) {
92
- u(this, D, t);
92
+ l(this, x, t);
93
93
  }
94
94
  /**
95
95
  * Set the GPS options.
@@ -99,7 +99,7 @@ class K {
99
99
  * minimum accuracy, in metres, for a GPS reading to be counted.
100
100
  */
101
101
  setGpsOptions(t = {}) {
102
- t.gpsMinDistance !== void 0 && u(this, H, t.gpsMinDistance), t.gpsMinAccuracy !== void 0 && u(this, R, t.gpsMinAccuracy);
102
+ t.gpsMinDistance !== void 0 && l(this, H, t.gpsMinDistance), t.gpsMinAccuracy !== void 0 && l(this, L, t.gpsMinAccuracy);
103
103
  }
104
104
  /**
105
105
  * Start the GPS on a real device
@@ -107,19 +107,19 @@ class K {
107
107
  * GPS errors can be handled by handling the gpserror event.
108
108
  */
109
109
  async startGps() {
110
- if (s(this, w)) {
111
- const e = await (await s(this, w).sendData("/gps/start", {
112
- gpsMinDistance: s(this, H),
113
- gpsMinAccuracy: s(this, R)
110
+ if (n(this, M)) {
111
+ const i = await (await n(this, M).sendData("/gps/start", {
112
+ gpsMinDistance: n(this, H),
113
+ gpsMinAccuracy: n(this, L)
114
114
  })).json();
115
- u(this, O, e.session);
115
+ l(this, T, i.session);
116
116
  }
117
- return s(this, P) === null ? (u(this, P, navigator.geolocation.watchPosition(
117
+ return n(this, A) === null ? (l(this, A, navigator.geolocation.watchPosition(
118
118
  (t) => {
119
- f(this, p, F).call(this, t);
119
+ p(this, f, W).call(this, t);
120
120
  },
121
121
  (t) => {
122
- s(this, A).gpserror ? s(this, A).gpserror(t.code) : alert(`GPS error: code ${t.code}`);
122
+ n(this, O).gpserror ? n(this, O).gpserror(t.code) : alert(`GPS error: code ${t.code}`);
123
123
  },
124
124
  {
125
125
  enableHighAccuracy: !0
@@ -132,7 +132,7 @@ class K {
132
132
  * stopped (i.e. it was never started).
133
133
  */
134
134
  stopGps() {
135
- return s(this, P) !== null ? (navigator.geolocation.clearWatch(s(this, P)), u(this, P, null), !0) : !1;
135
+ return n(this, A) !== null ? (navigator.geolocation.clearWatch(n(this, A)), l(this, A, null), !0) : !1;
136
136
  }
137
137
  /**
138
138
  * Send a fake GPS signal. Useful for testing on a desktop or laptop.
@@ -143,12 +143,12 @@ class K {
143
143
  * @param {number} acc - The accuracy of the GPS reading in metres. May be
144
144
  * ignored if lower than the specified minimum accuracy.
145
145
  */
146
- fakeGps(t, e, n = null, r = 0) {
147
- n !== null && this.setElevation(n), f(this, p, F).call(this, {
146
+ fakeGps(t, i, e = null, c = 0) {
147
+ e !== null && this.setElevation(e), p(this, f, W).call(this, {
148
148
  coords: {
149
149
  longitude: t,
150
- latitude: e,
151
- accuracy: r
150
+ latitude: i,
151
+ accuracy: c
152
152
  }
153
153
  });
154
154
  }
@@ -162,13 +162,13 @@ class K {
162
162
  * @param {number} lat - The latitude.
163
163
  * @return {Array} a two member array containing the WebGL x and z coordinates
164
164
  */
165
- lonLatToWorldCoords(t, e) {
166
- const n = s(this, D).project(t, e);
167
- if (s(this, M))
168
- n[0] -= s(this, M)[0], n[1] -= s(this, M)[1];
165
+ lonLatToWorldCoords(t, i) {
166
+ const e = n(this, x).project(t, i);
167
+ if (n(this, y))
168
+ e[0] -= n(this, y)[0], e[1] -= n(this, y)[1];
169
169
  else
170
170
  throw "No initial position determined";
171
- return [n[0], -n[1]];
171
+ return [e[0], -e[1]];
172
172
  }
173
173
  /**
174
174
  * Add a new AR object at a given latitude, longitude and elevation.
@@ -180,13 +180,13 @@ class K {
180
180
  * @param {Object} properties - properties describing the object (for example,
181
181
  * the contents of the GeoJSON properties field).
182
182
  */
183
- add(t, e, n, r, d = {}) {
183
+ add(t, i, e, c, d = {}) {
184
184
  var g;
185
- t.properties = d, f(this, p, j).call(this, t, e, n, r), this.scene.add(t), (g = s(this, w)) == null || g.sendData("/object/new", {
185
+ t.properties = d, p(this, f, j).call(this, t, i, e, c), this.scene.add(t), (g = n(this, M)) == null || g.sendData("/object/new", {
186
186
  position: t.position,
187
187
  x: t.position.x,
188
188
  z: t.position.z,
189
- session: s(this, O),
189
+ session: n(this, T),
190
190
  properties: d
191
191
  });
192
192
  }
@@ -210,50 +210,50 @@ class K {
210
210
  * @listens LocationBased#gpsupdate
211
211
  * @listens LocationBased#gpserror
212
212
  */
213
- on(t, e) {
214
- s(this, A)[t] = e;
213
+ on(t, i) {
214
+ n(this, O)[t] = i;
215
215
  }
216
216
  }
217
- D = new WeakMap(), A = new WeakMap(), b = new WeakMap(), H = new WeakMap(), R = new WeakMap(), P = new WeakMap(), M = new WeakMap(), T = new WeakMap(), O = new WeakMap(), w = new WeakMap(), p = new WeakSet(), j = function(t, e, n, r) {
218
- const d = this.lonLatToWorldCoords(e, n);
219
- r !== void 0 && (t.position.y = r), [t.position.x, t.position.z] = d;
220
- }, Q = function(t, e) {
221
- u(this, M, s(this, D).project(t, e));
222
- }, F = function(t) {
223
- var n, r, d;
224
- let e = Number.MAX_VALUE;
225
- k(this, T)._++, (n = s(this, w)) == null || n.sendData("/gps/new", {
226
- gpsCount: s(this, T),
217
+ x = new WeakMap(), O = new WeakMap(), P = new WeakMap(), H = new WeakMap(), L = new WeakMap(), A = new WeakMap(), y = new WeakMap(), D = new WeakMap(), T = new WeakMap(), M = new WeakMap(), f = new WeakSet(), j = function(t, i, e, c) {
218
+ const d = this.lonLatToWorldCoords(i, e);
219
+ c !== void 0 && (t.position.y = c), [t.position.x, t.position.z] = d;
220
+ }, Y = function(t, i) {
221
+ l(this, y, n(this, x).project(t, i));
222
+ }, W = function(t) {
223
+ var e, c, d;
224
+ let i = Number.MAX_VALUE;
225
+ k(this, D)._++, (e = n(this, M)) == null || e.sendData("/gps/new", {
226
+ gpsCount: n(this, D),
227
227
  lat: t.coords.latitude,
228
228
  lon: t.coords.longitude,
229
229
  acc: t.coords.accuracy,
230
- session: s(this, O)
231
- }), t.coords.accuracy <= s(this, R) && (s(this, b) === null ? u(this, b, {
230
+ session: n(this, T)
231
+ }), t.coords.accuracy <= n(this, L) && (n(this, P) === null ? l(this, P, {
232
232
  latitude: t.coords.latitude,
233
233
  longitude: t.coords.longitude
234
- }) : e = f(this, p, B).call(this, s(this, b), t.coords), e >= s(this, H) && (s(this, b).longitude = t.coords.longitude, s(this, b).latitude = t.coords.latitude, s(this, M) || (f(this, p, Q).call(this, t.coords.longitude, t.coords.latitude), (r = s(this, w)) == null || r.sendData("/worldorigin/new", {
235
- gpsCount: s(this, T),
234
+ }) : i = p(this, f, Z).call(this, n(this, P), t.coords), i >= n(this, H) && (n(this, P).longitude = t.coords.longitude, n(this, P).latitude = t.coords.latitude, n(this, y) || (p(this, f, Y).call(this, t.coords.longitude, t.coords.latitude), (c = n(this, M)) == null || c.sendData("/worldorigin/new", {
235
+ gpsCount: n(this, D),
236
236
  lat: t.coords.latitude,
237
237
  lon: t.coords.longitude,
238
- session: s(this, O),
239
- initialPosition: s(this, M)
240
- })), f(this, p, j).call(this, this.camera, t.coords.longitude, t.coords.latitude), (d = s(this, w)) == null || d.sendData("/gps/accepted", {
241
- gpsCount: s(this, T),
238
+ session: n(this, T),
239
+ initialPosition: n(this, y)
240
+ })), p(this, f, j).call(this, this.camera, t.coords.longitude, t.coords.latitude), (d = n(this, M)) == null || d.sendData("/gps/accepted", {
241
+ gpsCount: n(this, D),
242
242
  cameraX: this.camera.position.x,
243
243
  cameraZ: this.camera.position.z,
244
- session: s(this, O),
245
- distMoved: e
246
- }), s(this, A).gpsupdate && s(this, A).gpsupdate(t, e)));
244
+ session: n(this, T),
245
+ distMoved: i
246
+ }), n(this, O).gpsupdate && n(this, O).gpsupdate(t, i)));
247
247
  }, /**
248
248
  * Calculate haversine distance between two lat/lon pairs.
249
249
  *
250
250
  * Taken from original A-Frame AR.js location-based components
251
251
  */
252
- B = function(t, e) {
253
- const n = L.MathUtils.degToRad(e.longitude - t.longitude), r = L.MathUtils.degToRad(e.latitude - t.latitude), d = Math.sin(r / 2) * Math.sin(r / 2) + Math.cos(L.MathUtils.degToRad(t.latitude)) * Math.cos(L.MathUtils.degToRad(e.latitude)) * (Math.sin(n / 2) * Math.sin(n / 2));
252
+ Z = function(t, i) {
253
+ const e = b.MathUtils.degToRad(i.longitude - t.longitude), c = b.MathUtils.degToRad(i.latitude - t.latitude), d = Math.sin(c / 2) * Math.sin(c / 2) + Math.cos(b.MathUtils.degToRad(t.latitude)) * Math.cos(b.MathUtils.degToRad(i.latitude)) * (Math.sin(e / 2) * Math.sin(e / 2));
254
254
  return 2 * Math.atan2(Math.sqrt(d), Math.sqrt(1 - d)) * 6371e3;
255
255
  };
256
- class J {
256
+ class at {
257
257
  /**
258
258
  * Create a Webcam.
259
259
  * @param options {Object} - options to use for initialising the camera.
@@ -266,22 +266,22 @@ class J {
266
266
  * element to render the webcam feed. If a falsy value (e.g. null or
267
267
  * undefined), a video element will be created.
268
268
  */
269
- constructor(t = {}, e) {
270
- this.sceneWebcam = new L.Scene();
271
- let n;
272
- if (e ? n = document.querySelector(e) : (n = document.createElement("video"), n.setAttribute("autoplay", !0), n.setAttribute("playsinline", !0), n.style.display = "none", document.body.appendChild(n)), this.texture = new L.VideoTexture(n), navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
273
- const r = {
269
+ constructor(t = {}, i) {
270
+ this.sceneWebcam = new b.Scene();
271
+ let e;
272
+ if (i ? e = document.querySelector(i) : (e = document.createElement("video"), e.setAttribute("autoplay", !0), e.setAttribute("playsinline", !0), e.style.display = "none", document.body.appendChild(e)), this.texture = new b.VideoTexture(e), navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
273
+ const c = {
274
274
  video: {
275
275
  width: { ideal: t.idealWidth || 1280 },
276
276
  height: { ideal: t.idealHeight || 720 },
277
277
  facingMode: "environment"
278
278
  }
279
279
  };
280
- navigator.mediaDevices.getUserMedia(r).then((d) => {
281
- n.addEventListener("loadedmetadata", () => {
280
+ navigator.mediaDevices.getUserMedia(c).then((d) => {
281
+ e.addEventListener("loadedmetadata", () => {
282
282
  var g;
283
- n.setAttribute("width", n.videoWidth), n.setAttribute("height", n.videoHeight), n.play(), (g = t.onVideoStarted) == null || g.call(this, this.texture);
284
- }), n.srcObject = d;
283
+ e.setAttribute("width", e.videoWidth), e.setAttribute("height", e.videoHeight), e.play(), (g = t.onVideoStarted) == null || g.call(this, this.texture);
284
+ }), e.srcObject = d;
285
285
  }).catch((d) => {
286
286
  setTimeout(() => {
287
287
  alert(
@@ -304,95 +304,96 @@ Message: ` + d.message
304
304
  this.texture.dispose();
305
305
  }
306
306
  }
307
- const q = navigator.userAgent.match(/iPhone|iPad|iPod/i) || /Macintosh/i.test(navigator.userAgent) && navigator.maxTouchPoints != null && navigator.maxTouchPoints > 1, tt = new Y(0, 0, 1), G = new U(), et = new _(), it = new _(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)), nt = { type: "change" };
308
- class st extends Z {
307
+ const z = navigator.userAgent.match(/iPhone|iPad|iPod/i) || /Macintosh/i.test(navigator.userAgent) && navigator.maxTouchPoints != null && navigator.maxTouchPoints > 1, J = new B(0, 0, 1), N = new U(), tt = new F(), et = new F(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)), it = { type: "change" };
308
+ class rt extends K {
309
309
  /**
310
310
  * Create an instance of DeviceOrientationControls.
311
311
  * @param {Object} object - the object to attach the controls to
312
312
  * (usually your Three.js camera)
313
+ * @param {Object} options - options for DeviceOrientationControls: currently accepts smoothingFactor
313
314
  */
314
- constructor(t) {
315
+ constructor(t, i = {}) {
315
316
  super(), window.isSecureContext === !1 && console.error(
316
317
  "THREE.DeviceOrientationControls: DeviceOrientationEvent is only available in secure contexts (https)"
317
318
  );
318
- const e = this, n = 1e-6, r = new _();
319
- this.object = t, this.object.rotation.reorder("YXZ"), this.enabled = !0, this.deviceOrientation = null, this.screenOrientation = 0, this.alphaOffset = 0, this.initialOffset = null, this.TWO_PI = 2 * Math.PI, this.HALF_PI = 0.5 * Math.PI, this.orientationChangeEventName = "ondeviceorientationabsolute" in window ? "deviceorientationabsolute" : "deviceorientation", this.smoothingFactor = 1;
320
- const d = function({
321
- alpha: o,
322
- beta: c,
323
- gamma: l,
324
- webkitCompassHeading: a
319
+ const e = this, c = 1e-6, d = new F();
320
+ this.object = t, this.object.rotation.reorder("YXZ"), this.enabled = !0, this.deviceOrientation = null, this.screenOrientation = 0, this.alphaOffset = 0, this.initialOffset = null, this.TWO_PI = 2 * Math.PI, this.HALF_PI = 0.5 * Math.PI, this.orientationChangeEventName = "ondeviceorientationabsolute" in window ? "deviceorientationabsolute" : "deviceorientation", this.smoothingFactor = i.smoothingFactor || 1;
321
+ const g = function({
322
+ alpha: s,
323
+ beta: o,
324
+ gamma: a,
325
+ webkitCompassHeading: u
325
326
  }) {
326
- if (q) {
327
- const h = 360 - a;
328
- e.alphaOffset = C.degToRad(h - o), e.deviceOrientation = { alpha: o, beta: c, gamma: l, webkitCompassHeading: a };
327
+ if (z) {
328
+ const h = 360 - u;
329
+ e.alphaOffset = C.degToRad(h - s), e.deviceOrientation = { alpha: s, beta: o, gamma: a, webkitCompassHeading: u };
329
330
  } else
330
- o < 0 && (o += 360), e.deviceOrientation = { alpha: o, beta: c, gamma: l };
331
+ s < 0 && (s += 360), e.deviceOrientation = { alpha: s, beta: o, gamma: a };
331
332
  window.dispatchEvent(
332
333
  new CustomEvent("camera-rotation-change", {
333
334
  detail: { cameraRotation: t.rotation }
334
335
  })
335
336
  );
336
- }, g = function() {
337
+ }, I = function() {
337
338
  e.screenOrientation = window.orientation || 0;
338
- }, x = function(o, c, l, a, h) {
339
- G.set(l, c, -a, "YXZ"), o.setFromEuler(G), o.multiply(it), o.multiply(et.setFromAxisAngle(tt, -h));
339
+ }, R = function(s, o, a, u, h) {
340
+ N.set(a, o, -u, "YXZ"), s.setFromEuler(N), s.multiply(et), s.multiply(tt.setFromAxisAngle(J, -h));
340
341
  };
341
342
  this.connect = function() {
342
- g(), window.DeviceOrientationEvent !== void 0 && typeof window.DeviceOrientationEvent.requestPermission == "function" ? window.DeviceOrientationEvent.requestPermission().then((o) => {
343
- o === "granted" && (window.addEventListener(
343
+ I(), window.DeviceOrientationEvent !== void 0 && typeof window.DeviceOrientationEvent.requestPermission == "function" ? window.DeviceOrientationEvent.requestPermission().then((s) => {
344
+ s === "granted" && (window.addEventListener(
344
345
  "orientationchange",
345
- g
346
+ I
346
347
  ), window.addEventListener(
347
348
  e.orientationChangeEventName,
348
- d
349
+ g
349
350
  ));
350
- }).catch(function(o) {
351
+ }).catch(function(s) {
351
352
  console.error(
352
353
  "THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:",
353
- o
354
+ s
354
355
  );
355
356
  }) : (window.addEventListener(
356
357
  "orientationchange",
357
- g
358
+ I
358
359
  ), window.addEventListener(
359
360
  e.orientationChangeEventName,
360
- d
361
+ g
361
362
  )), e.enabled = !0;
362
363
  }, this.disconnect = function() {
363
364
  window.removeEventListener(
364
365
  "orientationchange",
365
- g
366
+ I
366
367
  ), window.removeEventListener(
367
368
  e.orientationChangeEventName,
368
- d
369
+ g
369
370
  ), e.enabled = !1, e.initialOffset = !1, e.deviceOrientation = null;
370
- }, this.update = function({ theta: o = 0 } = { theta: 0 }) {
371
+ }, this.update = function({ theta: s = 0 } = { theta: 0 }) {
371
372
  if (e.enabled === !1) return;
372
- const c = e.deviceOrientation;
373
- if (c) {
374
- let l = c.alpha ? C.degToRad(c.alpha) + e.alphaOffset : 0, a = c.beta ? C.degToRad(c.beta) : 0, h = c.gamma ? C.degToRad(c.gamma) : 0;
375
- const I = e.screenOrientation ? C.degToRad(e.screenOrientation) : 0;
376
- if (q) {
377
- const v = new _();
378
- x(v, l, a, h, I);
379
- const y = new U().setFromQuaternion(
373
+ const o = e.deviceOrientation;
374
+ if (o) {
375
+ let a = o.alpha ? C.degToRad(o.alpha) + e.alphaOffset : 0, u = o.beta ? C.degToRad(o.beta) : 0, h = o.gamma ? C.degToRad(o.gamma) : 0;
376
+ const _ = e.screenOrientation ? C.degToRad(e.screenOrientation) : 0;
377
+ if (z) {
378
+ const v = new F();
379
+ R(v, a, u, h, _);
380
+ const w = new U().setFromQuaternion(
380
381
  v,
381
382
  "YXZ"
382
383
  );
383
- console.log(y.x, y.y, y.z), y.y = C.degToRad(
384
- 360 - c.webkitCompassHeading
385
- ), v.setFromEuler(y), e.object.quaternion.copy(v);
384
+ console.log(w.x, w.y, w.z), w.y = C.degToRad(
385
+ 360 - o.webkitCompassHeading
386
+ ), v.setFromEuler(w), e.object.quaternion.copy(v);
386
387
  } else {
387
388
  if (this.smoothingFactor < 1) {
388
389
  if (this.lastOrientation) {
389
390
  const v = this.smoothingFactor;
390
- l = this._getSmoothedAngle(
391
- l,
391
+ a = this._getSmoothedAngle(
392
+ a,
392
393
  this.lastOrientation.alpha,
393
394
  v
394
- ), a = this._getSmoothedAngle(
395
- a + Math.PI,
395
+ ), u = this._getSmoothedAngle(
396
+ u + Math.PI,
396
397
  this.lastOrientation.beta,
397
398
  v
398
399
  ), h = this._getSmoothedAngle(
@@ -402,47 +403,47 @@ class st extends Z {
402
403
  Math.PI
403
404
  );
404
405
  } else
405
- a += Math.PI, h += this.HALF_PI;
406
+ u += Math.PI, h += this.HALF_PI;
406
407
  this.lastOrientation = {
407
- alpha: l,
408
- beta: a,
408
+ alpha: a,
409
+ beta: u,
409
410
  gamma: h
410
411
  };
411
412
  }
412
- x(
413
+ R(
413
414
  e.object.quaternion,
414
- l + o,
415
- this.smoothingFactor < 1 ? a - Math.PI : a,
415
+ a + s,
416
+ this.smoothingFactor < 1 ? u - Math.PI : u,
416
417
  this.smoothingFactor < 1 ? h - this.HALF_PI : h,
417
- I
418
+ _
418
419
  );
419
420
  }
420
- 8 * (1 - r.dot(e.object.quaternion)) > n && (r.copy(e.object.quaternion), e.dispatchEvent(nt));
421
+ 8 * (1 - d.dot(e.object.quaternion)) > c && (d.copy(e.object.quaternion), e.dispatchEvent(it));
421
422
  }
422
- }, this._orderAngle = function(o, c, l = this.TWO_PI) {
423
- return c > o && Math.abs(c - o) < l / 2 || o > c && Math.abs(c - o) > l / 2 ? { left: o, right: c } : { left: c, right: o };
424
- }, this._getSmoothedAngle = function(o, c, l, a = this.TWO_PI) {
425
- const h = this._orderAngle(o, c, a), I = h.left, v = h.right;
426
- h.left = 0, h.right -= I, h.right < 0 && (h.right += a);
427
- let y = v == c ? (1 - l) * h.right + l * h.left : l * h.right + (1 - l) * h.left;
428
- return y += I, y >= a && (y -= a), y;
423
+ }, this._orderAngle = function(s, o, a = this.TWO_PI) {
424
+ return o > s && Math.abs(o - s) < a / 2 || s > o && Math.abs(o - s) > a / 2 ? { left: s, right: o } : { left: o, right: s };
425
+ }, this._getSmoothedAngle = function(s, o, a, u = this.TWO_PI) {
426
+ const h = this._orderAngle(s, o, u), _ = h.left, v = h.right;
427
+ h.left = 0, h.right -= _, h.right < 0 && (h.right += u);
428
+ let w = v == o ? (1 - a) * h.right + a * h.left : a * h.right + (1 - a) * h.left;
429
+ return w += _, w >= u && (w -= u), w;
429
430
  }, this.updateAlphaOffset = function() {
430
431
  e.initialOffset = !1;
431
432
  }, this.dispose = function() {
432
433
  e.disconnect();
433
434
  }, this.getAlpha = function() {
434
- const { deviceOrientation: o } = e;
435
- return o && o.alpha ? C.degToRad(o.alpha) + e.alphaOffset : 0;
435
+ const { deviceOrientation: s } = e;
436
+ return s && s.alpha ? C.degToRad(s.alpha) + e.alphaOffset : 0;
436
437
  }, this.getBeta = function() {
437
- const { deviceOrientation: o } = e;
438
- return o && o.beta ? C.degToRad(o.beta) : 0;
438
+ const { deviceOrientation: s } = e;
439
+ return s && s.beta ? C.degToRad(s.beta) : 0;
439
440
  }, window.DeviceOrientationEvent !== void 0 && typeof window.DeviceOrientationEvent.requestPermission == "function" ? this.initPermissionDialog() : this.connect();
440
441
  }
441
442
  // Provide gesture before initialising device orientation controls
442
443
  // From PR #659 on the main AR.js repo
443
444
  // Thanks to @ma2yama
444
445
  initPermissionDialog() {
445
- const t = document.createElement("div"), e = document.createElement("div"), n = document.createElement("div"), r = document.createElement("div");
446
+ const t = document.createElement("div"), i = document.createElement("div"), e = document.createElement("div"), c = document.createElement("div");
446
447
  document.body.appendChild(t);
447
448
  const d = {
448
449
  display: "flex",
@@ -461,13 +462,13 @@ class st extends Z {
461
462
  borderRadius: "3px",
462
463
  width: "36rem",
463
464
  height: "24rem"
464
- }, x = {
465
+ }, I = {
465
466
  width: "100%",
466
467
  height: "70%",
467
468
  display: "flex",
468
469
  justifyContent: "center",
469
470
  alignItems: "center"
470
- }, o = {
471
+ }, R = {
471
472
  display: "inline-flex",
472
473
  width: "100%",
473
474
  height: "30%",
@@ -477,29 +478,29 @@ class st extends Z {
477
478
  for (let a in d)
478
479
  t.style[a] = d[a];
479
480
  for (let a in g)
480
- e.style[a] = g[a];
481
- for (let a in x)
482
- n.style[a] = x[a];
483
- for (let a in o)
484
- r.style[a] = o[a];
485
- t.appendChild(e), e.appendChild(n), e.appendChild(r), n.innerHTML = '<div style="font-size: 24pt; margin: 1rem;">This immersive website requires access to your device motion sensors.</div>';
486
- const c = () => {
481
+ i.style[a] = g[a];
482
+ for (let a in I)
483
+ e.style[a] = I[a];
484
+ for (let a in R)
485
+ c.style[a] = R[a];
486
+ t.appendChild(i), i.appendChild(e), i.appendChild(c), e.innerHTML = '<div style="font-size: 24pt; margin: 1rem;">This immersive website requires access to your device motion sensors.</div>';
487
+ const s = () => {
487
488
  this.connect(), t.style.display = "none";
488
- }, l = document.createElement("button");
489
- l.addEventListener("click", c), l.style.width = "50%", l.style.height = "80%", l.style.fontSize = "20pt", l.appendChild(document.createTextNode("OK")), r.appendChild(l), document.body.appendChild(t);
489
+ }, o = document.createElement("button");
490
+ o.addEventListener("click", s), o.style.width = "50%", o.style.height = "80%", o.style.fontSize = "20pt", o.appendChild(document.createTextNode("OK")), c.appendChild(o), document.body.appendChild(t);
490
491
  }
491
492
  }
492
- class rt {
493
+ class ct {
493
494
  /**
494
495
  * Create a ClickHandler.
495
496
  * @param {THREE.WebGLRenderer} - The Three.js renderer on which the click
496
497
  * events will be handled.
497
498
  */
498
499
  constructor(t) {
499
- this.raycaster = new L.Raycaster(), this.normalisedMousePosition = new L.Vector2(null, null), t.domElement.addEventListener("click", (e) => {
500
+ this.raycaster = new b.Raycaster(), this.normalisedMousePosition = new b.Vector2(null, null), t.domElement.addEventListener("click", (i) => {
500
501
  this.normalisedMousePosition.set(
501
- e.clientX / t.domElement.clientWidth * 2 - 1,
502
- -(e.clientY / t.domElement.clientHeight * 2) + 1
502
+ i.clientX / t.domElement.clientWidth * 2 - 1,
503
+ -(i.clientY / t.domElement.clientHeight * 2) + 1
503
504
  );
504
505
  });
505
506
  }
@@ -511,149 +512,21 @@ class rt {
511
512
  * cast into.
512
513
  * @return {Array} - array of all intersected objects.
513
514
  */
514
- raycast(t, e) {
515
+ raycast(t, i) {
515
516
  if (this.normalisedMousePosition.x !== null && this.normalisedMousePosition.y !== null) {
516
517
  this.raycaster.setFromCamera(this.normalisedMousePosition, t);
517
- const n = this.raycaster.intersectObjects(e.children, !1);
518
- return this.normalisedMousePosition.set(null, null), n;
518
+ const e = this.raycaster.intersectObjects(i.children, !1);
519
+ return this.normalisedMousePosition.set(null, null), e;
519
520
  }
520
521
  return [];
521
522
  }
522
523
  }
523
- AFRAME.registerComponent("locar-webcam", {
524
- schema: {
525
- idealWidth: {
526
- type: "number",
527
- default: 1024
528
- },
529
- idealHeight: {
530
- type: "number",
531
- default: 768
532
- },
533
- videoElement: {
534
- type: "string",
535
- default: ""
536
- }
537
- },
538
- init: function() {
539
- new J({
540
- idealWidth: this.data.idealWidth,
541
- idealHeight: this.data.idealHeight,
542
- onVideoStarted: (i) => {
543
- this.el.object3D.background = i;
544
- }
545
- }, this.data.videoElement || null);
546
- }
547
- });
548
- AFRAME.registerComponent("locar-camera", {
549
- schema: {
550
- simulateLatitude: {
551
- type: "number",
552
- default: 0
553
- },
554
- simulateLongitude: {
555
- type: "number",
556
- default: 0
557
- },
558
- simulateAltitude: {
559
- type: "number",
560
- default: -Number.MAX_VALUE
561
- },
562
- positionMinAccuracy: {
563
- type: "number",
564
- default: 100
565
- }
566
- },
567
- init: function() {
568
- this.locar = new K(
569
- this.el.sceneEl.object3D,
570
- this.el.object3D
571
- ), this.locar.on("gpsupdate", (i, t) => {
572
- this.el.emit("gpsupdate", {
573
- position: i,
574
- distMoved: t
575
- });
576
- }), this.locar.on("gpserror", (i) => {
577
- const t = [
578
- "User denied access to GPS.",
579
- "GPS satellites not available.",
580
- "Timeout communicating with GPS satellites - try moving to a more open area."
581
- ];
582
- i >= 1 && i <= 3 ? alert(t[i - 1]) : alert(`Unknown geolocation error code ${i}.`);
583
- }), this._isMobile() && (this.deviceOrientationControls = new st(this.el.object3D));
584
- },
585
- update: function(i) {
586
- this.locar.setGpsOptions({
587
- gpsMinAccuracy: this.data.positionMinAccuracy,
588
- gpsMinDistance: this.data.gpsMinDistance
589
- }), (this.data.simulateLatitude !== 0 || this.data.simulateLongitude !== 0) && (this.data.simulateLatitude != (i == null ? void 0 : i.simulateLatitude) || this.data.simulateLongitude != (i == null ? void 0 : i.simulateLongitude)) && (this.locar.stopGps(), this.locar.fakeGps(
590
- this.data.simulateLongitude,
591
- this.data.simulateLatitude
592
- ), this.data.simulateLongitude = 0, this.data.simulateLatitude = 0), this.data.simulateAltitude > -Number.MAX_VALUE && this.locar.setElevation(this.data.simulateAltitude + 1.6);
593
- },
594
- play: function() {
595
- this.locar.startGps();
596
- },
597
- pause: function() {
598
- this.locar.stopGps();
599
- },
600
- /**
601
- * Convert longitude and latitude to three.js/WebGL world coordinates.
602
- * Uses the specified projection, and negates the northing (in typical
603
- * projections, northings increase northwards, but in the WebGL coordinate
604
- * system, we face negative z if the camera is at the origin with default
605
- * rotation).
606
- * @param {number} lon - The longitude.
607
- * @param {number} lat - The latitude.
608
- * @return {Array} a two member array containing the WebGL x and z coordinates
609
- */
610
- lonLatToWorldCoords: function(i, t) {
611
- return this.locar.lonLatToWorldCoords(i, t);
612
- },
613
- tick: function() {
614
- var i;
615
- (i = this.deviceOrientationControls) == null || i.update();
616
- },
617
- _isMobile: function() {
618
- return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
619
- navigator.userAgent
620
- ) || /Macintosh/i.test(navigator.userAgent) && navigator.maxTouchPoints != null && navigator.maxTouchPoints > 1;
621
- }
622
- });
623
- AFRAME.registerComponent("locar-entity-place", {
624
- schema: {
625
- latitude: {
626
- type: "number",
627
- default: 0
628
- },
629
- longitude: {
630
- type: "number",
631
- default: 0
632
- }
633
- },
634
- init: function() {
635
- const i = this.el.sceneEl.querySelector("[locar-camera]");
636
- this.locarCamera = i.components["locar-camera"];
637
- },
638
- update: function(i) {
639
- this.locarCamera || console.error("Cannot update locar-entity-place without a locar-camera component on the scene camera.");
640
- const t = this.locarCamera.lonLatToWorldCoords(
641
- this.data.longitude,
642
- this.data.latitude
643
- );
644
- this.el.object3D.position.set(
645
- t[0],
646
- this.el.object3D.position.y,
647
- t[1]
648
- );
649
- }
650
- });
651
- const ct = "0.0.10";
524
+ const ht = "0.0.10-noaframe-1";
652
525
  export {
653
- rt as ClickHandler,
654
- st as DeviceOrientationControls,
655
- K as LocationBased,
526
+ ct as ClickHandler,
527
+ rt as DeviceOrientationControls,
528
+ ot as LocationBased,
656
529
  $ as SphMercProjection,
657
- J as Webcam,
658
- ct as version
530
+ at as Webcam,
531
+ ht as version
659
532
  };
package/dist/locar.umd.js CHANGED
@@ -1,3 +1,3 @@
1
- (function(r,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],n):(r=typeof globalThis<"u"?globalThis:r||self,n(r.locar={},r.THREE))})(this,function(r,n){"use strict";var Q=r=>{throw TypeError(r)};var U=(r,n,p)=>n.has(r)||Q("Cannot "+p);var s=(r,n,p)=>(U(r,n,"read from private field"),p?p.call(r):n.get(r)),y=(r,n,p)=>n.has(r)?Q("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(r):n.set(r,p),m=(r,n,p,v)=>(U(r,n,"write to private field"),v?v.call(r,p):n.set(r,p),p),w=(r,n,p)=>(U(r,n,"access private method"),p);var V=(r,n,p,v)=>({set _(W){m(r,n,W,p)},get _(){return s(r,n,v)}});var b,X,B,Y,Z,_,L,E,j,I,D,A,S,T,O,M,k,$,q,K;function p(a){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(a){for(const e in a)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(a,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>a[e]})}}return t.default=a,Object.freeze(t)}const v=p(n);class W{constructor(){y(this,b);this.EARTH=4007501668e-2,this.HALF_EARTH=2003750834e-2}project(t,e){return[w(this,b,X).call(this,t),w(this,b,B).call(this,e)]}unproject(t){return[w(this,b,Y).call(this,t[0]),w(this,b,Z).call(this,t[1])]}getID(){return"epsg:3857"}}b=new WeakSet,X=function(t){return t/180*this.HALF_EARTH},B=function(t){var e=Math.log(Math.tan((90+t)*Math.PI/360))/(Math.PI/180);return e*this.HALF_EARTH/180},Y=function(t){return t/this.HALF_EARTH*180},Z=function(t){var e=t/this.HALF_EARTH*180;return e=180/Math.PI*(2*Math.atan(Math.exp(e*Math.PI/180))-Math.PI/2),e};class H{constructor(t,e,i={},h=null){y(this,M);y(this,_);y(this,L);y(this,E);y(this,j);y(this,I);y(this,D);y(this,A);y(this,S);y(this,T);y(this,O);this.scene=t,this.camera=e,m(this,_,new W),m(this,L,{}),m(this,E,null),m(this,j,0),m(this,I,100),m(this,D,null),this.setGpsOptions(i),m(this,A,null),m(this,S,0),m(this,T,0),m(this,O,h)}setProjection(t){m(this,_,t)}setGpsOptions(t={}){t.gpsMinDistance!==void 0&&m(this,j,t.gpsMinDistance),t.gpsMinAccuracy!==void 0&&m(this,I,t.gpsMinAccuracy)}async startGps(){if(s(this,O)){const e=await(await s(this,O).sendData("/gps/start",{gpsMinDistance:s(this,j),gpsMinAccuracy:s(this,I)})).json();m(this,T,e.session)}return s(this,D)===null?(m(this,D,navigator.geolocation.watchPosition(t=>{w(this,M,q).call(this,t)},t=>{s(this,L).gpserror?s(this,L).gpserror(t.code):alert(`GPS error: code ${t.code}`)},{enableHighAccuracy:!0})),!0):!1}stopGps(){return s(this,D)!==null?(navigator.geolocation.clearWatch(s(this,D)),m(this,D,null),!0):!1}fakeGps(t,e,i=null,h=0){i!==null&&this.setElevation(i),w(this,M,q).call(this,{coords:{longitude:t,latitude:e,accuracy:h}})}lonLatToWorldCoords(t,e){const i=s(this,_).project(t,e);if(s(this,A))i[0]-=s(this,A)[0],i[1]-=s(this,A)[1];else throw"No initial position determined";return[i[0],-i[1]]}add(t,e,i,h,u={}){var f;t.properties=u,w(this,M,k).call(this,t,e,i,h),this.scene.add(t),(f=s(this,O))==null||f.sendData("/object/new",{position:t.position,x:t.position.x,z:t.position.z,session:s(this,T),properties:u})}setElevation(t){this.camera.position.y=t}on(t,e){s(this,L)[t]=e}}_=new WeakMap,L=new WeakMap,E=new WeakMap,j=new WeakMap,I=new WeakMap,D=new WeakMap,A=new WeakMap,S=new WeakMap,T=new WeakMap,O=new WeakMap,M=new WeakSet,k=function(t,e,i,h){const u=this.lonLatToWorldCoords(e,i);h!==void 0&&(t.position.y=h),[t.position.x,t.position.z]=u},$=function(t,e){m(this,A,s(this,_).project(t,e))},q=function(t){var i,h,u;let e=Number.MAX_VALUE;V(this,S)._++,(i=s(this,O))==null||i.sendData("/gps/new",{gpsCount:s(this,S),lat:t.coords.latitude,lon:t.coords.longitude,acc:t.coords.accuracy,session:s(this,T)}),t.coords.accuracy<=s(this,I)&&(s(this,E)===null?m(this,E,{latitude:t.coords.latitude,longitude:t.coords.longitude}):e=w(this,M,K).call(this,s(this,E),t.coords),e>=s(this,j)&&(s(this,E).longitude=t.coords.longitude,s(this,E).latitude=t.coords.latitude,s(this,A)||(w(this,M,$).call(this,t.coords.longitude,t.coords.latitude),(h=s(this,O))==null||h.sendData("/worldorigin/new",{gpsCount:s(this,S),lat:t.coords.latitude,lon:t.coords.longitude,session:s(this,T),initialPosition:s(this,A)})),w(this,M,k).call(this,this.camera,t.coords.longitude,t.coords.latitude),(u=s(this,O))==null||u.sendData("/gps/accepted",{gpsCount:s(this,S),cameraX:this.camera.position.x,cameraZ:this.camera.position.z,session:s(this,T),distMoved:e}),s(this,L).gpsupdate&&s(this,L).gpsupdate(t,e)))},K=function(t,e){const i=v.MathUtils.degToRad(e.longitude-t.longitude),h=v.MathUtils.degToRad(e.latitude-t.latitude),u=Math.sin(h/2)*Math.sin(h/2)+Math.cos(v.MathUtils.degToRad(t.latitude))*Math.cos(v.MathUtils.degToRad(e.latitude))*(Math.sin(i/2)*Math.sin(i/2));return 2*Math.atan2(Math.sqrt(u),Math.sqrt(1-u))*6371e3};class G{constructor(t={},e){this.sceneWebcam=new v.Scene;let i;if(e?i=document.querySelector(e):(i=document.createElement("video"),i.setAttribute("autoplay",!0),i.setAttribute("playsinline",!0),i.style.display="none",document.body.appendChild(i)),this.texture=new v.VideoTexture(i),navigator.mediaDevices&&navigator.mediaDevices.getUserMedia){const h={video:{width:{ideal:t.idealWidth||1280},height:{ideal:t.idealHeight||720},facingMode:"environment"}};navigator.mediaDevices.getUserMedia(h).then(u=>{i.addEventListener("loadedmetadata",()=>{var f;i.setAttribute("width",i.videoWidth),i.setAttribute("height",i.videoHeight),i.play(),(f=t.onVideoStarted)==null||f.call(this,this.texture)}),i.srcObject=u}).catch(u=>{setTimeout(()=>{alert(`Webcam Error
2
- Name: `+u.name+`
3
- Message: `+u.message)},1e3)})}else setTimeout(()=>{alert("sorry - media devices API not supported")},1e3)}dispose(){this.texture.dispose()}}const R=navigator.userAgent.match(/iPhone|iPad|iPod/i)||/Macintosh/i.test(navigator.userAgent)&&navigator.maxTouchPoints!=null&&navigator.maxTouchPoints>1,J=new n.Vector3(0,0,1),N=new n.Euler,tt=new n.Quaternion,et=new n.Quaternion(-Math.sqrt(.5),0,0,Math.sqrt(.5)),it={type:"change"};class z extends n.EventDispatcher{constructor(t){super(),window.isSecureContext===!1&&console.error("THREE.DeviceOrientationControls: DeviceOrientationEvent is only available in secure contexts (https)");const e=this,i=1e-6,h=new n.Quaternion;this.object=t,this.object.rotation.reorder("YXZ"),this.enabled=!0,this.deviceOrientation=null,this.screenOrientation=0,this.alphaOffset=0,this.initialOffset=null,this.TWO_PI=2*Math.PI,this.HALF_PI=.5*Math.PI,this.orientationChangeEventName="ondeviceorientationabsolute"in window?"deviceorientationabsolute":"deviceorientation",this.smoothingFactor=1;const u=function({alpha:o,beta:l,gamma:d,webkitCompassHeading:c}){if(R){const g=360-c;e.alphaOffset=n.MathUtils.degToRad(g-o),e.deviceOrientation={alpha:o,beta:l,gamma:d,webkitCompassHeading:c}}else o<0&&(o+=360),e.deviceOrientation={alpha:o,beta:l,gamma:d};window.dispatchEvent(new CustomEvent("camera-rotation-change",{detail:{cameraRotation:t.rotation}}))},f=function(){e.screenOrientation=window.orientation||0},x=function(o,l,d,c,g){N.set(d,l,-c,"YXZ"),o.setFromEuler(N),o.multiply(et),o.multiply(tt.setFromAxisAngle(J,-g))};this.connect=function(){f(),window.DeviceOrientationEvent!==void 0&&typeof window.DeviceOrientationEvent.requestPermission=="function"?window.DeviceOrientationEvent.requestPermission().then(o=>{o==="granted"&&(window.addEventListener("orientationchange",f),window.addEventListener(e.orientationChangeEventName,u))}).catch(function(o){console.error("THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:",o)}):(window.addEventListener("orientationchange",f),window.addEventListener(e.orientationChangeEventName,u)),e.enabled=!0},this.disconnect=function(){window.removeEventListener("orientationchange",f),window.removeEventListener(e.orientationChangeEventName,u),e.enabled=!1,e.initialOffset=!1,e.deviceOrientation=null},this.update=function({theta:o=0}={theta:0}){if(e.enabled===!1)return;const l=e.deviceOrientation;if(l){let d=l.alpha?n.MathUtils.degToRad(l.alpha)+e.alphaOffset:0,c=l.beta?n.MathUtils.degToRad(l.beta):0,g=l.gamma?n.MathUtils.degToRad(l.gamma):0;const F=e.screenOrientation?n.MathUtils.degToRad(e.screenOrientation):0;if(R){const P=new n.Quaternion;x(P,d,c,g,F);const C=new n.Euler().setFromQuaternion(P,"YXZ");console.log(C.x,C.y,C.z),C.y=n.MathUtils.degToRad(360-l.webkitCompassHeading),P.setFromEuler(C),e.object.quaternion.copy(P)}else{if(this.smoothingFactor<1){if(this.lastOrientation){const P=this.smoothingFactor;d=this._getSmoothedAngle(d,this.lastOrientation.alpha,P),c=this._getSmoothedAngle(c+Math.PI,this.lastOrientation.beta,P),g=this._getSmoothedAngle(g+this.HALF_PI,this.lastOrientation.gamma,P,Math.PI)}else c+=Math.PI,g+=this.HALF_PI;this.lastOrientation={alpha:d,beta:c,gamma:g}}x(e.object.quaternion,d+o,this.smoothingFactor<1?c-Math.PI:c,this.smoothingFactor<1?g-this.HALF_PI:g,F)}8*(1-h.dot(e.object.quaternion))>i&&(h.copy(e.object.quaternion),e.dispatchEvent(it))}},this._orderAngle=function(o,l,d=this.TWO_PI){return l>o&&Math.abs(l-o)<d/2||o>l&&Math.abs(l-o)>d/2?{left:o,right:l}:{left:l,right:o}},this._getSmoothedAngle=function(o,l,d,c=this.TWO_PI){const g=this._orderAngle(o,l,c),F=g.left,P=g.right;g.left=0,g.right-=F,g.right<0&&(g.right+=c);let C=P==l?(1-d)*g.right+d*g.left:d*g.right+(1-d)*g.left;return C+=F,C>=c&&(C-=c),C},this.updateAlphaOffset=function(){e.initialOffset=!1},this.dispose=function(){e.disconnect()},this.getAlpha=function(){const{deviceOrientation:o}=e;return o&&o.alpha?n.MathUtils.degToRad(o.alpha)+e.alphaOffset:0},this.getBeta=function(){const{deviceOrientation:o}=e;return o&&o.beta?n.MathUtils.degToRad(o.beta):0},window.DeviceOrientationEvent!==void 0&&typeof window.DeviceOrientationEvent.requestPermission=="function"?this.initPermissionDialog():this.connect()}initPermissionDialog(){const t=document.createElement("div"),e=document.createElement("div"),i=document.createElement("div"),h=document.createElement("div");document.body.appendChild(t);const u={display:"flex",position:"fixed",top:0,left:0,width:"100%",height:"100%",zIndex:1,backgroundColor:"rgba(0,0,0,0.6)",justifyContent:"center",alignItems:"center"},f={backgroundColor:"white",padding:"6px",borderRadius:"3px",width:"36rem",height:"24rem"},x={width:"100%",height:"70%",display:"flex",justifyContent:"center",alignItems:"center"},o={display:"inline-flex",width:"100%",height:"30%",justifyContent:"center",alignItems:"center"};for(let c in u)t.style[c]=u[c];for(let c in f)e.style[c]=f[c];for(let c in x)i.style[c]=x[c];for(let c in o)h.style[c]=o[c];t.appendChild(e),e.appendChild(i),e.appendChild(h),i.innerHTML='<div style="font-size: 24pt; margin: 1rem;">This immersive website requires access to your device motion sensors.</div>';const l=()=>{this.connect(),t.style.display="none"},d=document.createElement("button");d.addEventListener("click",l),d.style.width="50%",d.style.height="80%",d.style.fontSize="20pt",d.appendChild(document.createTextNode("OK")),h.appendChild(d),document.body.appendChild(t)}}class nt{constructor(t){this.raycaster=new v.Raycaster,this.normalisedMousePosition=new v.Vector2(null,null),t.domElement.addEventListener("click",e=>{this.normalisedMousePosition.set(e.clientX/t.domElement.clientWidth*2-1,-(e.clientY/t.domElement.clientHeight*2)+1)})}raycast(t,e){if(this.normalisedMousePosition.x!==null&&this.normalisedMousePosition.y!==null){this.raycaster.setFromCamera(this.normalisedMousePosition,t);const i=this.raycaster.intersectObjects(e.children,!1);return this.normalisedMousePosition.set(null,null),i}return[]}}AFRAME.registerComponent("locar-webcam",{schema:{idealWidth:{type:"number",default:1024},idealHeight:{type:"number",default:768},videoElement:{type:"string",default:""}},init:function(){new G({idealWidth:this.data.idealWidth,idealHeight:this.data.idealHeight,onVideoStarted:a=>{this.el.object3D.background=a}},this.data.videoElement||null)}}),AFRAME.registerComponent("locar-camera",{schema:{simulateLatitude:{type:"number",default:0},simulateLongitude:{type:"number",default:0},simulateAltitude:{type:"number",default:-Number.MAX_VALUE},positionMinAccuracy:{type:"number",default:100}},init:function(){this.locar=new H(this.el.sceneEl.object3D,this.el.object3D),this.locar.on("gpsupdate",(a,t)=>{this.el.emit("gpsupdate",{position:a,distMoved:t})}),this.locar.on("gpserror",a=>{const t=["User denied access to GPS.","GPS satellites not available.","Timeout communicating with GPS satellites - try moving to a more open area."];a>=1&&a<=3?alert(t[a-1]):alert(`Unknown geolocation error code ${a}.`)}),this._isMobile()&&(this.deviceOrientationControls=new z(this.el.object3D))},update:function(a){this.locar.setGpsOptions({gpsMinAccuracy:this.data.positionMinAccuracy,gpsMinDistance:this.data.gpsMinDistance}),(this.data.simulateLatitude!==0||this.data.simulateLongitude!==0)&&(this.data.simulateLatitude!=(a==null?void 0:a.simulateLatitude)||this.data.simulateLongitude!=(a==null?void 0:a.simulateLongitude))&&(this.locar.stopGps(),this.locar.fakeGps(this.data.simulateLongitude,this.data.simulateLatitude),this.data.simulateLongitude=0,this.data.simulateLatitude=0),this.data.simulateAltitude>-Number.MAX_VALUE&&this.locar.setElevation(this.data.simulateAltitude+1.6)},play:function(){this.locar.startGps()},pause:function(){this.locar.stopGps()},lonLatToWorldCoords:function(a,t){return this.locar.lonLatToWorldCoords(a,t)},tick:function(){var a;(a=this.deviceOrientationControls)==null||a.update()},_isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)||/Macintosh/i.test(navigator.userAgent)&&navigator.maxTouchPoints!=null&&navigator.maxTouchPoints>1}}),AFRAME.registerComponent("locar-entity-place",{schema:{latitude:{type:"number",default:0},longitude:{type:"number",default:0}},init:function(){const a=this.el.sceneEl.querySelector("[locar-camera]");this.locarCamera=a.components["locar-camera"]},update:function(a){this.locarCamera||console.error("Cannot update locar-entity-place without a locar-camera component on the scene camera.");const t=this.locarCamera.lonLatToWorldCoords(this.data.longitude,this.data.latitude);this.el.object3D.position.set(t[0],this.el.object3D.position.y,t[1])}});const st="0.0.10";r.ClickHandler=nt,r.DeviceOrientationControls=z,r.LocationBased=H,r.SphMercProjection=W,r.Webcam=G,r.version=st,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
1
+ (function(a,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],n):(a=typeof globalThis<"u"?globalThis:a||self,n(a.locar={},a.THREE))})(this,function(a,n){"use strict";var N=a=>{throw TypeError(a)};var q=(a,n,f)=>n.has(a)||N("Cannot "+f);var s=(a,n,f)=>(q(a,n,"read from private field"),f?f.call(a):n.get(a)),v=(a,n,f)=>n.has(a)?N("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(a):n.set(a,f),u=(a,n,f,m)=>(q(a,n,"write to private field"),m?m.call(a,f):n.set(a,f),f),y=(a,n,f)=>(q(a,n,"access private method"),f);var Q=(a,n,f,m)=>({set _(W){u(a,n,W,f)},get _(){return s(a,n,m)}});var w,G,X,V,Y,E,D,I,S,j,L,O,_,T,P,M,H,Z,k,B;function f(b){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(b){for(const i in b)if(i!=="default"){const e=Object.getOwnPropertyDescriptor(b,i);Object.defineProperty(t,i,e.get?e:{enumerable:!0,get:()=>b[i]})}}return t.default=b,Object.freeze(t)}const m=f(n);class W{constructor(){v(this,w);this.EARTH=4007501668e-2,this.HALF_EARTH=2003750834e-2}project(t,i){return[y(this,w,G).call(this,t),y(this,w,X).call(this,i)]}unproject(t){return[y(this,w,V).call(this,t[0]),y(this,w,Y).call(this,t[1])]}getID(){return"epsg:3857"}}w=new WeakSet,G=function(t){return t/180*this.HALF_EARTH},X=function(t){var i=Math.log(Math.tan((90+t)*Math.PI/360))/(Math.PI/180);return i*this.HALF_EARTH/180},V=function(t){return t/this.HALF_EARTH*180},Y=function(t){var i=t/this.HALF_EARTH*180;return i=180/Math.PI*(2*Math.atan(Math.exp(i*Math.PI/180))-Math.PI/2),i};class K{constructor(t,i,e={},l=null){v(this,M);v(this,E);v(this,D);v(this,I);v(this,S);v(this,j);v(this,L);v(this,O);v(this,_);v(this,T);v(this,P);this.scene=t,this.camera=i,u(this,E,new W),u(this,D,{}),u(this,I,null),u(this,S,0),u(this,j,100),u(this,L,null),this.setGpsOptions(e),u(this,O,null),u(this,_,0),u(this,T,0),u(this,P,l)}setProjection(t){u(this,E,t)}setGpsOptions(t={}){t.gpsMinDistance!==void 0&&u(this,S,t.gpsMinDistance),t.gpsMinAccuracy!==void 0&&u(this,j,t.gpsMinAccuracy)}async startGps(){if(s(this,P)){const i=await(await s(this,P).sendData("/gps/start",{gpsMinDistance:s(this,S),gpsMinAccuracy:s(this,j)})).json();u(this,T,i.session)}return s(this,L)===null?(u(this,L,navigator.geolocation.watchPosition(t=>{y(this,M,k).call(this,t)},t=>{s(this,D).gpserror?s(this,D).gpserror(t.code):alert(`GPS error: code ${t.code}`)},{enableHighAccuracy:!0})),!0):!1}stopGps(){return s(this,L)!==null?(navigator.geolocation.clearWatch(s(this,L)),u(this,L,null),!0):!1}fakeGps(t,i,e=null,l=0){e!==null&&this.setElevation(e),y(this,M,k).call(this,{coords:{longitude:t,latitude:i,accuracy:l}})}lonLatToWorldCoords(t,i){const e=s(this,E).project(t,i);if(s(this,O))e[0]-=s(this,O)[0],e[1]-=s(this,O)[1];else throw"No initial position determined";return[e[0],-e[1]]}add(t,i,e,l,h={}){var p;t.properties=h,y(this,M,H).call(this,t,i,e,l),this.scene.add(t),(p=s(this,P))==null||p.sendData("/object/new",{position:t.position,x:t.position.x,z:t.position.z,session:s(this,T),properties:h})}setElevation(t){this.camera.position.y=t}on(t,i){s(this,D)[t]=i}}E=new WeakMap,D=new WeakMap,I=new WeakMap,S=new WeakMap,j=new WeakMap,L=new WeakMap,O=new WeakMap,_=new WeakMap,T=new WeakMap,P=new WeakMap,M=new WeakSet,H=function(t,i,e,l){const h=this.lonLatToWorldCoords(i,e);l!==void 0&&(t.position.y=l),[t.position.x,t.position.z]=h},Z=function(t,i){u(this,O,s(this,E).project(t,i))},k=function(t){var e,l,h;let i=Number.MAX_VALUE;Q(this,_)._++,(e=s(this,P))==null||e.sendData("/gps/new",{gpsCount:s(this,_),lat:t.coords.latitude,lon:t.coords.longitude,acc:t.coords.accuracy,session:s(this,T)}),t.coords.accuracy<=s(this,j)&&(s(this,I)===null?u(this,I,{latitude:t.coords.latitude,longitude:t.coords.longitude}):i=y(this,M,B).call(this,s(this,I),t.coords),i>=s(this,S)&&(s(this,I).longitude=t.coords.longitude,s(this,I).latitude=t.coords.latitude,s(this,O)||(y(this,M,Z).call(this,t.coords.longitude,t.coords.latitude),(l=s(this,P))==null||l.sendData("/worldorigin/new",{gpsCount:s(this,_),lat:t.coords.latitude,lon:t.coords.longitude,session:s(this,T),initialPosition:s(this,O)})),y(this,M,H).call(this,this.camera,t.coords.longitude,t.coords.latitude),(h=s(this,P))==null||h.sendData("/gps/accepted",{gpsCount:s(this,_),cameraX:this.camera.position.x,cameraZ:this.camera.position.z,session:s(this,T),distMoved:i}),s(this,D).gpsupdate&&s(this,D).gpsupdate(t,i)))},B=function(t,i){const e=m.MathUtils.degToRad(i.longitude-t.longitude),l=m.MathUtils.degToRad(i.latitude-t.latitude),h=Math.sin(l/2)*Math.sin(l/2)+Math.cos(m.MathUtils.degToRad(t.latitude))*Math.cos(m.MathUtils.degToRad(i.latitude))*(Math.sin(e/2)*Math.sin(e/2));return 2*Math.atan2(Math.sqrt(h),Math.sqrt(1-h))*6371e3};class ${constructor(t={},i){this.sceneWebcam=new m.Scene;let e;if(i?e=document.querySelector(i):(e=document.createElement("video"),e.setAttribute("autoplay",!0),e.setAttribute("playsinline",!0),e.style.display="none",document.body.appendChild(e)),this.texture=new m.VideoTexture(e),navigator.mediaDevices&&navigator.mediaDevices.getUserMedia){const l={video:{width:{ideal:t.idealWidth||1280},height:{ideal:t.idealHeight||720},facingMode:"environment"}};navigator.mediaDevices.getUserMedia(l).then(h=>{e.addEventListener("loadedmetadata",()=>{var p;e.setAttribute("width",e.videoWidth),e.setAttribute("height",e.videoHeight),e.play(),(p=t.onVideoStarted)==null||p.call(this,this.texture)}),e.srcObject=h}).catch(h=>{setTimeout(()=>{alert(`Webcam Error
2
+ Name: `+h.name+`
3
+ Message: `+h.message)},1e3)})}else setTimeout(()=>{alert("sorry - media devices API not supported")},1e3)}dispose(){this.texture.dispose()}}const R=navigator.userAgent.match(/iPhone|iPad|iPod/i)||/Macintosh/i.test(navigator.userAgent)&&navigator.maxTouchPoints!=null&&navigator.maxTouchPoints>1,J=new n.Vector3(0,0,1),z=new n.Euler,tt=new n.Quaternion,et=new n.Quaternion(-Math.sqrt(.5),0,0,Math.sqrt(.5)),it={type:"change"};class nt extends n.EventDispatcher{constructor(t,i={}){super(),window.isSecureContext===!1&&console.error("THREE.DeviceOrientationControls: DeviceOrientationEvent is only available in secure contexts (https)");const e=this,l=1e-6,h=new n.Quaternion;this.object=t,this.object.rotation.reorder("YXZ"),this.enabled=!0,this.deviceOrientation=null,this.screenOrientation=0,this.alphaOffset=0,this.initialOffset=null,this.TWO_PI=2*Math.PI,this.HALF_PI=.5*Math.PI,this.orientationChangeEventName="ondeviceorientationabsolute"in window?"deviceorientationabsolute":"deviceorientation",this.smoothingFactor=i.smoothingFactor||1;const p=function({alpha:o,beta:r,gamma:c,webkitCompassHeading:g}){if(R){const d=360-g;e.alphaOffset=n.MathUtils.degToRad(d-o),e.deviceOrientation={alpha:o,beta:r,gamma:c,webkitCompassHeading:g}}else o<0&&(o+=360),e.deviceOrientation={alpha:o,beta:r,gamma:c};window.dispatchEvent(new CustomEvent("camera-rotation-change",{detail:{cameraRotation:t.rotation}}))},x=function(){e.screenOrientation=window.orientation||0},F=function(o,r,c,g,d){z.set(c,r,-g,"YXZ"),o.setFromEuler(z),o.multiply(et),o.multiply(tt.setFromAxisAngle(J,-d))};this.connect=function(){x(),window.DeviceOrientationEvent!==void 0&&typeof window.DeviceOrientationEvent.requestPermission=="function"?window.DeviceOrientationEvent.requestPermission().then(o=>{o==="granted"&&(window.addEventListener("orientationchange",x),window.addEventListener(e.orientationChangeEventName,p))}).catch(function(o){console.error("THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:",o)}):(window.addEventListener("orientationchange",x),window.addEventListener(e.orientationChangeEventName,p)),e.enabled=!0},this.disconnect=function(){window.removeEventListener("orientationchange",x),window.removeEventListener(e.orientationChangeEventName,p),e.enabled=!1,e.initialOffset=!1,e.deviceOrientation=null},this.update=function({theta:o=0}={theta:0}){if(e.enabled===!1)return;const r=e.deviceOrientation;if(r){let c=r.alpha?n.MathUtils.degToRad(r.alpha)+e.alphaOffset:0,g=r.beta?n.MathUtils.degToRad(r.beta):0,d=r.gamma?n.MathUtils.degToRad(r.gamma):0;const U=e.screenOrientation?n.MathUtils.degToRad(e.screenOrientation):0;if(R){const A=new n.Quaternion;F(A,c,g,d,U);const C=new n.Euler().setFromQuaternion(A,"YXZ");console.log(C.x,C.y,C.z),C.y=n.MathUtils.degToRad(360-r.webkitCompassHeading),A.setFromEuler(C),e.object.quaternion.copy(A)}else{if(this.smoothingFactor<1){if(this.lastOrientation){const A=this.smoothingFactor;c=this._getSmoothedAngle(c,this.lastOrientation.alpha,A),g=this._getSmoothedAngle(g+Math.PI,this.lastOrientation.beta,A),d=this._getSmoothedAngle(d+this.HALF_PI,this.lastOrientation.gamma,A,Math.PI)}else g+=Math.PI,d+=this.HALF_PI;this.lastOrientation={alpha:c,beta:g,gamma:d}}F(e.object.quaternion,c+o,this.smoothingFactor<1?g-Math.PI:g,this.smoothingFactor<1?d-this.HALF_PI:d,U)}8*(1-h.dot(e.object.quaternion))>l&&(h.copy(e.object.quaternion),e.dispatchEvent(it))}},this._orderAngle=function(o,r,c=this.TWO_PI){return r>o&&Math.abs(r-o)<c/2||o>r&&Math.abs(r-o)>c/2?{left:o,right:r}:{left:r,right:o}},this._getSmoothedAngle=function(o,r,c,g=this.TWO_PI){const d=this._orderAngle(o,r,g),U=d.left,A=d.right;d.left=0,d.right-=U,d.right<0&&(d.right+=g);let C=A==r?(1-c)*d.right+c*d.left:c*d.right+(1-c)*d.left;return C+=U,C>=g&&(C-=g),C},this.updateAlphaOffset=function(){e.initialOffset=!1},this.dispose=function(){e.disconnect()},this.getAlpha=function(){const{deviceOrientation:o}=e;return o&&o.alpha?n.MathUtils.degToRad(o.alpha)+e.alphaOffset:0},this.getBeta=function(){const{deviceOrientation:o}=e;return o&&o.beta?n.MathUtils.degToRad(o.beta):0},window.DeviceOrientationEvent!==void 0&&typeof window.DeviceOrientationEvent.requestPermission=="function"?this.initPermissionDialog():this.connect()}initPermissionDialog(){const t=document.createElement("div"),i=document.createElement("div"),e=document.createElement("div"),l=document.createElement("div");document.body.appendChild(t);const h={display:"flex",position:"fixed",top:0,left:0,width:"100%",height:"100%",zIndex:1,backgroundColor:"rgba(0,0,0,0.6)",justifyContent:"center",alignItems:"center"},p={backgroundColor:"white",padding:"6px",borderRadius:"3px",width:"36rem",height:"24rem"},x={width:"100%",height:"70%",display:"flex",justifyContent:"center",alignItems:"center"},F={display:"inline-flex",width:"100%",height:"30%",justifyContent:"center",alignItems:"center"};for(let c in h)t.style[c]=h[c];for(let c in p)i.style[c]=p[c];for(let c in x)e.style[c]=x[c];for(let c in F)l.style[c]=F[c];t.appendChild(i),i.appendChild(e),i.appendChild(l),e.innerHTML='<div style="font-size: 24pt; margin: 1rem;">This immersive website requires access to your device motion sensors.</div>';const o=()=>{this.connect(),t.style.display="none"},r=document.createElement("button");r.addEventListener("click",o),r.style.width="50%",r.style.height="80%",r.style.fontSize="20pt",r.appendChild(document.createTextNode("OK")),l.appendChild(r),document.body.appendChild(t)}}class st{constructor(t){this.raycaster=new m.Raycaster,this.normalisedMousePosition=new m.Vector2(null,null),t.domElement.addEventListener("click",i=>{this.normalisedMousePosition.set(i.clientX/t.domElement.clientWidth*2-1,-(i.clientY/t.domElement.clientHeight*2)+1)})}raycast(t,i){if(this.normalisedMousePosition.x!==null&&this.normalisedMousePosition.y!==null){this.raycaster.setFromCamera(this.normalisedMousePosition,t);const e=this.raycaster.intersectObjects(i.children,!1);return this.normalisedMousePosition.set(null,null),e}return[]}}const ot="0.0.10-noaframe-1";a.ClickHandler=st,a.DeviceOrientationControls=nt,a.LocationBased=K,a.SphMercProjection=W,a.Webcam=$,a.version=ot,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "locar",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "Location-based AR from AR.js.",
5
5
  "files": [
6
6
  "dist"