locar 0.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 AR.js organisation, unless stated otherwise in individual source files
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # LocAR.js
2
+
3
+ Location-based AR from AR.js.
4
+
5
+ ## What is this?
6
+
7
+ LocAR.js is an AR.js project to develop a library focused specifically on location-based augmented reality in the browser. Currently it consists of the location-based three.js code from [the main AR.js repository](https://github.com/AR-js-org/AR.js), with some minor changes to make it compatible with latest versions (0.169.0 at time of writing) of three.js.
8
+
9
+ ## Why?
10
+
11
+ Location-based AR has been part of AR.js for a while now, however the location-based component is essentially entirely independent of the marker-based and NFT components. Thus it makes sense to separate it out into its own project so that, for example, its dependencies (primarily three.js) can be updated without breaking the rest of AR.js and likewise, the code can be altered to ensure compatibility with the latest three.js without similarly breaking the remainder of AR.js. It also means that developers can work on the location-based aspect without having to understand the marker-based and NFT side, and also means that there is no need to include jsartoolkit.
12
+
13
+ ## Using the modern build tool Vite
14
+
15
+ The opportunity has also been taken to move to the modern and user-friendly build tool [Vite](https://vitejs.dev), with the hope that this will improve the development and maintenance experience.
16
+
17
+ ## Roadmap - investigating long standing bugs and issues
18
+
19
+ For a while there have been some bugs and issues with location-based AR.js which are thus far unresolved (e.g [#278](https://github.com/AR-js-org/AR.js/issues/278) or [#590](https://github.com/AR-js-org/AR.js/issues/590) ), which we hope can be investigated more easily with a standalone project (subject to our time availability of course - which is why we need developers and maintainers!). It's also hoped that the move to the more friendly Vite build system will help resolve some of the occasional issues that occur with importing ES6 modules (e.g. [issue 607](https://github.com/AR-js-org/AR.js/issues/607) ).
20
+
21
+ Some of these issues, such as incorrect North on some devices, may well be to do with incorrect or mis-calibrated sensors but the hope is that the standalone library will help to verify this and, if certain devices have North wrong by a consistent bearing, to develop a calibration tool.
22
+
23
+ For this reason, the focus at present will be on developing a **pure three.js version only**. When we believe that the key bugs and issues have been resolved, the plan is to then provide an A-Frame wrapper.
24
+
25
+ ## Using the library
26
+
27
+ The library will eventually be published to `npm`. For now, you should build a library tarball locally with
28
+ ```
29
+ npm run build
30
+ ```
31
+
32
+ Then you can use the library in your projects with:
33
+
34
+ ```javascript
35
+ import * as LocAR from 'locar';
36
+ ```
37
+
38
+ as long as you install the tarball locally into your projects, e.g. in your `package.json`:
39
+ ```
40
+ "dependencies": {
41
+ "locar" : "file:location-of-the-tarball.tgz",
42
+ "three" : "^0.169.0"
43
+ }
44
+ ```
45
+
46
+ Including the library bundle directly as an import has issues with duplicate three.js imports which we have not resolved, so we recommend the approach above.
47
+
48
+ ## Disclaimer
49
+
50
+ This is an open-source project licensed under the [MIT License](LICENSE) and thus comes with no warranty. Also it is a volunteer-led project; work on the project by AR.js maintainers or any other contributor will be undertaken *time-permitting* only. For this reason we welcome contributors! The more people working on the project, the more likely it is that it will become full-featured and issues will be resolved.
@@ -0,0 +1,233 @@
1
+ import * as n from "three";
2
+ class p {
3
+ constructor() {
4
+ this.EARTH = 4007501668e-2, this.HALF_EARTH = 2003750834e-2;
5
+ }
6
+ project(e, t) {
7
+ return [this.lonToSphMerc(e), this.latToSphMerc(t)];
8
+ }
9
+ unproject(e) {
10
+ return [this.sphMercToLon(e[0]), this.sphMercToLat(e[1])];
11
+ }
12
+ lonToSphMerc(e) {
13
+ return e / 180 * this.HALF_EARTH;
14
+ }
15
+ latToSphMerc(e) {
16
+ var t = Math.log(Math.tan((90 + e) * Math.PI / 360)) / (Math.PI / 180);
17
+ return t * this.HALF_EARTH / 180;
18
+ }
19
+ sphMercToLon(e) {
20
+ return e / this.HALF_EARTH * 180;
21
+ }
22
+ sphMercToLat(e) {
23
+ var t = e / this.HALF_EARTH * 180;
24
+ return t = 180 / Math.PI * (2 * Math.atan(Math.exp(t * Math.PI / 180)) - Math.PI / 2), t;
25
+ }
26
+ getID() {
27
+ return "epsg:3857";
28
+ }
29
+ }
30
+ class E {
31
+ constructor(e, t, i = {}) {
32
+ this._scene = e, this._camera = t, this._proj = new p(), this._eventHandlers = {}, this._lastCoords = null, this._gpsMinDistance = 0, this._gpsMinAccuracy = 100, this._watchPositionId = null, this.setGpsOptions(i), this.initialPosition = null;
33
+ }
34
+ setProjection(e) {
35
+ this._proj = e;
36
+ }
37
+ setGpsOptions(e = {}) {
38
+ e.gpsMinDistance !== void 0 && (this._gpsMinDistance = e.gpsMinDistance), e.gpsMinAccuracy !== void 0 && (this._gpsMinAccuracy = e.gpsMinAccuracy);
39
+ }
40
+ startGps() {
41
+ return this._watchPositionId === null ? (this._watchPositionId = navigator.geolocation.watchPosition(
42
+ (e) => {
43
+ this._gpsReceived(e);
44
+ },
45
+ (e) => {
46
+ this._eventHandlers.gpserror ? this._eventHandlers.gpserror(e.code) : alert(`GPS error: code ${e.code}`);
47
+ },
48
+ {
49
+ enableHighAccuracy: !0
50
+ }
51
+ ), !0) : !1;
52
+ }
53
+ stopGps() {
54
+ return this._watchPositionId !== null ? (navigator.geolocation.clearWatch(this._watchPositionId), this._watchPositionId = null, !0) : !1;
55
+ }
56
+ fakeGps(e, t, i = null, s = 0) {
57
+ i !== null && this.setElevation(i), this._gpsReceived({
58
+ coords: {
59
+ longitude: e,
60
+ latitude: t,
61
+ accuracy: s
62
+ }
63
+ });
64
+ }
65
+ lonLatToWorldCoords(e, t) {
66
+ const i = this._proj.project(e, t);
67
+ if (this.initialPosition)
68
+ i[0] -= this.initialPosition[0], i[1] -= this.initialPosition[1];
69
+ else
70
+ throw "No initial position determined";
71
+ return [i[0], -i[1]];
72
+ }
73
+ add(e, t, i, s, a = {}) {
74
+ e.properties = a, this.setWorldPosition(e, t, i, s), this._scene.add(e);
75
+ }
76
+ setWorldPosition(e, t, i, s) {
77
+ const a = this.lonLatToWorldCoords(t, i);
78
+ s !== void 0 && (e.position.y = s), [e.position.x, e.position.z] = a;
79
+ }
80
+ setElevation(e) {
81
+ this._camera.position.y = e;
82
+ }
83
+ on(e, t) {
84
+ this._eventHandlers[e] = t;
85
+ }
86
+ setWorldOrigin(e, t) {
87
+ this.initialPosition = this._proj.project(e, t);
88
+ }
89
+ _gpsReceived(e) {
90
+ let t = Number.MAX_VALUE;
91
+ e.coords.accuracy <= this._gpsMinAccuracy && (this._lastCoords === null ? this._lastCoords = {
92
+ latitude: e.coords.latitude,
93
+ longitude: e.coords.longitude
94
+ } : t = this._haversineDist(this._lastCoords, e.coords), t >= this._gpsMinDistance && (this._lastCoords.longitude = e.coords.longitude, this._lastCoords.latitude = e.coords.latitude, this.initialPosition || this.setWorldOrigin(
95
+ e.coords.longitude,
96
+ e.coords.latitude
97
+ ), this.setWorldPosition(
98
+ this._camera,
99
+ e.coords.longitude,
100
+ e.coords.latitude
101
+ ), this._eventHandlers.gpsupdate && this._eventHandlers.gpsupdate(e, t)));
102
+ }
103
+ /**
104
+ * Calculate haversine distance between two lat/lon pairs.
105
+ *
106
+ * Taken from original A-Frame AR.js location-based components
107
+ */
108
+ _haversineDist(e, t) {
109
+ const i = n.MathUtils.degToRad(t.longitude - e.longitude), s = n.MathUtils.degToRad(t.latitude - e.latitude), a = Math.sin(s / 2) * Math.sin(s / 2) + Math.cos(n.MathUtils.degToRad(e.latitude)) * Math.cos(n.MathUtils.degToRad(t.latitude)) * (Math.sin(i / 2) * Math.sin(i / 2));
110
+ return 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) * 6371e3;
111
+ }
112
+ }
113
+ class _ {
114
+ constructor(e, t, i) {
115
+ this.renderer = e, this.renderer.autoClear = !1, this.sceneWebcam = new n.Scene();
116
+ let s;
117
+ t === void 0 ? (s = document.createElement("video"), s.setAttribute("autoplay", !0), s.setAttribute("playsinline", !0), s.style.display = "none", document.body.appendChild(s)) : s = document.querySelector(t), this.geom = new n.PlaneGeometry(), this.texture = new n.VideoTexture(s), this.material = new n.MeshBasicMaterial({ map: this.texture });
118
+ const a = new n.Mesh(this.geom, this.material);
119
+ if (this.sceneWebcam.add(a), this.cameraWebcam = new n.OrthographicCamera(
120
+ -0.5,
121
+ 0.5,
122
+ 0.5,
123
+ -0.5,
124
+ 0,
125
+ 10
126
+ ), navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
127
+ const c = {
128
+ video: {
129
+ width: (i == null ? void 0 : i.width) || 1280,
130
+ height: (i == null ? void 0 : i.height) || 720,
131
+ facingMode: "environment"
132
+ }
133
+ };
134
+ navigator.mediaDevices.getUserMedia(c).then((d) => {
135
+ console.log("using the webcam successfully..."), s.srcObject = d, s.play();
136
+ }).catch((d) => {
137
+ setTimeout(() => {
138
+ this.createErrorPopup(
139
+ `Webcam Error
140
+ Name: ` + d.name + `
141
+ Message: ` + d.message
142
+ );
143
+ }, 1e3);
144
+ });
145
+ } else
146
+ setTimeout(() => {
147
+ this.createErrorPopup("sorry - media devices API not supported");
148
+ }, 1e3);
149
+ }
150
+ update() {
151
+ this.renderer.clear(), this.renderer.render(this.sceneWebcam, this.cameraWebcam), this.renderer.clearDepth();
152
+ }
153
+ dispose() {
154
+ this.material.dispose(), this.texture.dispose(), this.geom.dispose();
155
+ }
156
+ createErrorPopup(e) {
157
+ if (!document.getElementById("error-popup")) {
158
+ var t = document.createElement("div");
159
+ t.innerHTML = e, t.setAttribute("id", "error-popup"), document.body.appendChild(t);
160
+ }
161
+ }
162
+ }
163
+ const v = new n.Vector3(0, 0, 1), g = new n.Euler(), w = new n.Quaternion(), M = new n.Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)), f = { type: "change" };
164
+ class P extends n.EventDispatcher {
165
+ constructor(e) {
166
+ super(), window.isSecureContext === !1 && console.error("THREE.DeviceOrientationControls: DeviceOrientationEvent is only available in secure contexts (https)");
167
+ const t = this, i = 1e-6, s = new n.Quaternion();
168
+ this.object = e, this.object.rotation.reorder("YXZ"), this.enabled = !0, this.deviceOrientation = {}, this.screenOrientation = 0, this.alphaOffset = 0, this.deviceOrientationEventName = "ondeviceorientationabsolute" in window ? "deviceorientationabsolute" : "deviceorientation";
169
+ const a = function(o) {
170
+ t.deviceOrientation = o;
171
+ }, c = function() {
172
+ t.screenOrientation = window.orientation || 0;
173
+ }, d = function(o, h, l, u, m) {
174
+ g.set(l, h, -u, "YXZ"), o.setFromEuler(g), o.multiply(M), o.multiply(w.setFromAxisAngle(v, -m));
175
+ };
176
+ this.connect = function() {
177
+ c(), window.DeviceOrientationEvent !== void 0 && typeof window.DeviceOrientationEvent.requestPermission == "function" ? window.DeviceOrientationEvent.requestPermission().then(function(o) {
178
+ o == "granted" && (window.addEventListener("orientationchange", c), window.addEventListener(t.deviceOrientationEventName, a));
179
+ }).catch(function(o) {
180
+ console.error("THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:", o);
181
+ }) : (window.addEventListener("orientationchange", c), window.addEventListener(t.deviceOrientationEventName, a)), t.enabled = !0;
182
+ }, this.disconnect = function() {
183
+ window.removeEventListener("orientationchange", c), window.removeEventListener(t.deviceOrientationEventName, a), t.enabled = !1;
184
+ }, this.update = function() {
185
+ if (t.enabled === !1) return;
186
+ const o = t.deviceOrientation;
187
+ if (o) {
188
+ const h = o.alpha ? n.MathUtils.degToRad(o.alpha) + t.alphaOffset : 0, l = o.beta ? n.MathUtils.degToRad(o.beta) : 0, u = o.gamma ? n.MathUtils.degToRad(o.gamma) : 0, m = t.screenOrientation ? n.MathUtils.degToRad(t.screenOrientation) : 0;
189
+ d(t.object.quaternion, h, l, u, m), 8 * (1 - s.dot(t.object.quaternion)) > i && (s.copy(t.object.quaternion), t.dispatchEvent(f));
190
+ }
191
+ }, this.dispose = function() {
192
+ t.disconnect();
193
+ }, this.connect();
194
+ }
195
+ }
196
+ class y {
197
+ constructor(e) {
198
+ this.raycaster = new n.Raycaster(), this.normalisedMousePosition = new n.Vector2(null, null), e.domElement.addEventListener("click", (t) => {
199
+ this.normalisedMousePosition.set(
200
+ t.clientX / e.domElement.clientWidth * 2 - 1,
201
+ -(t.clientY / e.domElement.clientHeight * 2) + 1
202
+ );
203
+ });
204
+ }
205
+ raycast(e, t) {
206
+ if (this.normalisedMousePosition.x !== null && this.normalisedMousePosition.y !== null) {
207
+ this.raycaster.setFromCamera(this.normalisedMousePosition, e);
208
+ const i = this.raycaster.intersectObjects(t.children, !1);
209
+ return this.normalisedMousePosition.set(null, null), i;
210
+ }
211
+ return [];
212
+ }
213
+ }
214
+ function b(r = {}) {
215
+ const e = new n.Scene(), t = new n.PerspectiveCamera(
216
+ r.fov || 60,
217
+ window.innerWidth / window.innerHeight,
218
+ r.near || 1e-3,
219
+ r.far || 100
220
+ ), i = new n.WebGLRenderer();
221
+ return i.setSize(window.innerWidth, window.innerHeight), document.body.appendChild(i.domElement), window.addEventListener("resize", (s) => {
222
+ i.setSize(window.innerWidth, window.innerHeight), t.aspect = window.innerWidth / window.innerHeight, t.updateProjectionMatrix();
223
+ }), i.setAnimationLoop(r.animate || function() {
224
+ i.render(e, t);
225
+ }), { scene: e, camera: t, renderer: i };
226
+ }
227
+ export {
228
+ y as ClickHandler,
229
+ P as DeviceOrientationControls,
230
+ E as LocationBased,
231
+ _ as WebcamRenderer,
232
+ b as init3d
233
+ };
@@ -0,0 +1,3 @@
1
+ (function(c,h){typeof exports=="object"&&typeof module<"u"?h(exports,require("three")):typeof define=="function"&&define.amd?define(["exports","three"],h):(c=typeof globalThis<"u"?globalThis:c||self,h(c.locar={},c.THREE))})(this,function(c,h){"use strict";function v(r){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const t in r)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(r,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>r[t]})}}return e.default=r,Object.freeze(e)}const n=v(h);class w{constructor(){this.EARTH=4007501668e-2,this.HALF_EARTH=2003750834e-2}project(e,t){return[this.lonToSphMerc(e),this.latToSphMerc(t)]}unproject(e){return[this.sphMercToLon(e[0]),this.sphMercToLat(e[1])]}lonToSphMerc(e){return e/180*this.HALF_EARTH}latToSphMerc(e){var t=Math.log(Math.tan((90+e)*Math.PI/360))/(Math.PI/180);return t*this.HALF_EARTH/180}sphMercToLon(e){return e/this.HALF_EARTH*180}sphMercToLat(e){var t=e/this.HALF_EARTH*180;return t=180/Math.PI*(2*Math.atan(Math.exp(t*Math.PI/180))-Math.PI/2),t}getID(){return"epsg:3857"}}class M{constructor(e,t,i={}){this._scene=e,this._camera=t,this._proj=new w,this._eventHandlers={},this._lastCoords=null,this._gpsMinDistance=0,this._gpsMinAccuracy=100,this._watchPositionId=null,this.setGpsOptions(i),this.initialPosition=null}setProjection(e){this._proj=e}setGpsOptions(e={}){e.gpsMinDistance!==void 0&&(this._gpsMinDistance=e.gpsMinDistance),e.gpsMinAccuracy!==void 0&&(this._gpsMinAccuracy=e.gpsMinAccuracy)}startGps(){return this._watchPositionId===null?(this._watchPositionId=navigator.geolocation.watchPosition(e=>{this._gpsReceived(e)},e=>{this._eventHandlers.gpserror?this._eventHandlers.gpserror(e.code):alert(`GPS error: code ${e.code}`)},{enableHighAccuracy:!0}),!0):!1}stopGps(){return this._watchPositionId!==null?(navigator.geolocation.clearWatch(this._watchPositionId),this._watchPositionId=null,!0):!1}fakeGps(e,t,i=null,s=0){i!==null&&this.setElevation(i),this._gpsReceived({coords:{longitude:e,latitude:t,accuracy:s}})}lonLatToWorldCoords(e,t){const i=this._proj.project(e,t);if(this.initialPosition)i[0]-=this.initialPosition[0],i[1]-=this.initialPosition[1];else throw"No initial position determined";return[i[0],-i[1]]}add(e,t,i,s,a={}){e.properties=a,this.setWorldPosition(e,t,i,s),this._scene.add(e)}setWorldPosition(e,t,i,s){const a=this.lonLatToWorldCoords(t,i);s!==void 0&&(e.position.y=s),[e.position.x,e.position.z]=a}setElevation(e){this._camera.position.y=e}on(e,t){this._eventHandlers[e]=t}setWorldOrigin(e,t){this.initialPosition=this._proj.project(e,t)}_gpsReceived(e){let t=Number.MAX_VALUE;e.coords.accuracy<=this._gpsMinAccuracy&&(this._lastCoords===null?this._lastCoords={latitude:e.coords.latitude,longitude:e.coords.longitude}:t=this._haversineDist(this._lastCoords,e.coords),t>=this._gpsMinDistance&&(this._lastCoords.longitude=e.coords.longitude,this._lastCoords.latitude=e.coords.latitude,this.initialPosition||this.setWorldOrigin(e.coords.longitude,e.coords.latitude),this.setWorldPosition(this._camera,e.coords.longitude,e.coords.latitude),this._eventHandlers.gpsupdate&&this._eventHandlers.gpsupdate(e,t)))}_haversineDist(e,t){const i=n.MathUtils.degToRad(t.longitude-e.longitude),s=n.MathUtils.degToRad(t.latitude-e.latitude),a=Math.sin(s/2)*Math.sin(s/2)+Math.cos(n.MathUtils.degToRad(e.latitude))*Math.cos(n.MathUtils.degToRad(t.latitude))*(Math.sin(i/2)*Math.sin(i/2));return 2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a))*6371e3}}class _{constructor(e,t,i){this.renderer=e,this.renderer.autoClear=!1,this.sceneWebcam=new n.Scene;let s;t===void 0?(s=document.createElement("video"),s.setAttribute("autoplay",!0),s.setAttribute("playsinline",!0),s.style.display="none",document.body.appendChild(s)):s=document.querySelector(t),this.geom=new n.PlaneGeometry,this.texture=new n.VideoTexture(s),this.material=new n.MeshBasicMaterial({map:this.texture});const a=new n.Mesh(this.geom,this.material);if(this.sceneWebcam.add(a),this.cameraWebcam=new n.OrthographicCamera(-.5,.5,.5,-.5,0,10),navigator.mediaDevices&&navigator.mediaDevices.getUserMedia){const d={video:{width:(i==null?void 0:i.width)||1280,height:(i==null?void 0:i.height)||720,facingMode:"environment"}};navigator.mediaDevices.getUserMedia(d).then(l=>{console.log("using the webcam successfully..."),s.srcObject=l,s.play()}).catch(l=>{setTimeout(()=>{this.createErrorPopup(`Webcam Error
2
+ Name: `+l.name+`
3
+ Message: `+l.message)},1e3)})}else setTimeout(()=>{this.createErrorPopup("sorry - media devices API not supported")},1e3)}update(){this.renderer.clear(),this.renderer.render(this.sceneWebcam,this.cameraWebcam),this.renderer.clearDepth()}dispose(){this.material.dispose(),this.texture.dispose(),this.geom.dispose()}createErrorPopup(e){if(!document.getElementById("error-popup")){var t=document.createElement("div");t.innerHTML=e,t.setAttribute("id","error-popup"),document.body.appendChild(t)}}}const E=new n.Vector3(0,0,1),f=new n.Euler,y=new n.Quaternion,P=new n.Quaternion(-Math.sqrt(.5),0,0,Math.sqrt(.5)),b={type:"change"};class O extends n.EventDispatcher{constructor(e){super(),window.isSecureContext===!1&&console.error("THREE.DeviceOrientationControls: DeviceOrientationEvent is only available in secure contexts (https)");const t=this,i=1e-6,s=new n.Quaternion;this.object=e,this.object.rotation.reorder("YXZ"),this.enabled=!0,this.deviceOrientation={},this.screenOrientation=0,this.alphaOffset=0,this.deviceOrientationEventName="ondeviceorientationabsolute"in window?"deviceorientationabsolute":"deviceorientation";const a=function(o){t.deviceOrientation=o},d=function(){t.screenOrientation=window.orientation||0},l=function(o,u,m,g,p){f.set(m,u,-g,"YXZ"),o.setFromEuler(f),o.multiply(P),o.multiply(y.setFromAxisAngle(E,-p))};this.connect=function(){d(),window.DeviceOrientationEvent!==void 0&&typeof window.DeviceOrientationEvent.requestPermission=="function"?window.DeviceOrientationEvent.requestPermission().then(function(o){o=="granted"&&(window.addEventListener("orientationchange",d),window.addEventListener(t.deviceOrientationEventName,a))}).catch(function(o){console.error("THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:",o)}):(window.addEventListener("orientationchange",d),window.addEventListener(t.deviceOrientationEventName,a)),t.enabled=!0},this.disconnect=function(){window.removeEventListener("orientationchange",d),window.removeEventListener(t.deviceOrientationEventName,a),t.enabled=!1},this.update=function(){if(t.enabled===!1)return;const o=t.deviceOrientation;if(o){const u=o.alpha?n.MathUtils.degToRad(o.alpha)+t.alphaOffset:0,m=o.beta?n.MathUtils.degToRad(o.beta):0,g=o.gamma?n.MathUtils.degToRad(o.gamma):0,p=t.screenOrientation?n.MathUtils.degToRad(t.screenOrientation):0;l(t.object.quaternion,u,m,g,p),8*(1-s.dot(t.object.quaternion))>i&&(s.copy(t.object.quaternion),t.dispatchEvent(b))}},this.dispose=function(){t.disconnect()},this.connect()}}class T{constructor(e){this.raycaster=new n.Raycaster,this.normalisedMousePosition=new n.Vector2(null,null),e.domElement.addEventListener("click",t=>{this.normalisedMousePosition.set(t.clientX/e.domElement.clientWidth*2-1,-(t.clientY/e.domElement.clientHeight*2)+1)})}raycast(e,t){if(this.normalisedMousePosition.x!==null&&this.normalisedMousePosition.y!==null){this.raycaster.setFromCamera(this.normalisedMousePosition,e);const i=this.raycaster.intersectObjects(t.children,!1);return this.normalisedMousePosition.set(null,null),i}return[]}}function H(r={}){const e=new n.Scene,t=new n.PerspectiveCamera(r.fov||60,window.innerWidth/window.innerHeight,r.near||.001,r.far||100),i=new n.WebGLRenderer;return i.setSize(window.innerWidth,window.innerHeight),document.body.appendChild(i.domElement),window.addEventListener("resize",s=>{i.setSize(window.innerWidth,window.innerHeight),t.aspect=window.innerWidth/window.innerHeight,t.updateProjectionMatrix()}),i.setAnimationLoop(r.animate||function(){i.render(e,t)}),{scene:e,camera:t,renderer:i}}c.ClickHandler=T,c.DeviceOrientationControls=O,c.LocationBased=M,c.WebcamRenderer=_,c.init3d=H,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "locar",
3
+ "version": "0.0.2",
4
+ "description": "Location-based AR from AR.js.",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "main": "./dist/locar.umd.js",
9
+ "module": "./dist/locar.es.js",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/locar.es.js",
13
+ "require": "./dist/locar.umd.js"
14
+ }
15
+ },
16
+ "scripts": {
17
+ "build": "vite build && npm pack"
18
+ },
19
+ "devDependencies": {
20
+ "vite": "^5.4.8"
21
+ }
22
+ }