2023-12-18 01:58:58 +01:00
|
|
|
import { UIEventSource, Stores } from "../Logic/UIEventSource"
|
2023-12-16 01:29:42 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Exports the device orientation as UIEventSources and detects 'shakes'
|
|
|
|
*/
|
|
|
|
export class Orientation {
|
|
|
|
public static singleton = new Orientation()
|
|
|
|
|
|
|
|
public gotMeasurement: UIEventSource<boolean> = new UIEventSource<boolean>(false)
|
|
|
|
/**
|
|
|
|
* The direction wrt to the magnetic north, with clockwise = positive.
|
|
|
|
* 0 degrees is pointing towards the north
|
|
|
|
* 90° is east,
|
|
|
|
* 180° is south
|
|
|
|
* 270° is west
|
|
|
|
*
|
|
|
|
* Note that this is the opposite of what the DeviceOrientationEvent uses!
|
|
|
|
* */
|
|
|
|
public alpha: UIEventSource<number> = new UIEventSource<number>(undefined)
|
|
|
|
public beta: UIEventSource<number> = new UIEventSource<number>(undefined)
|
|
|
|
public gamma: UIEventSource<number> = new UIEventSource<number>(undefined)
|
|
|
|
/**
|
|
|
|
* Indicates if 'alpha' is with the actual magnetic field or just mimicks that
|
|
|
|
*/
|
|
|
|
public absolute: UIEventSource<boolean> = new UIEventSource<boolean>(undefined)
|
|
|
|
/**
|
|
|
|
* A derivate of beta and gamma
|
|
|
|
* An arrow pointing up, rotated with this amount should more or less point towards the sky
|
|
|
|
* Used in the slope input
|
|
|
|
*/
|
|
|
|
public arrowDirection: UIEventSource<number> = new UIEventSource(undefined)
|
|
|
|
private _measurementsStarted = false
|
2023-12-19 22:21:34 +01:00
|
|
|
private _animateFakeMeasurements = false
|
2023-12-16 01:29:42 +01:00
|
|
|
|
2023-12-19 22:21:34 +01:00
|
|
|
constructor() {
|
2024-01-29 16:57:40 +01:00
|
|
|
// this.fakeMeasurements()
|
2023-12-19 22:21:34 +01:00
|
|
|
}
|
2023-12-16 01:29:42 +01:00
|
|
|
|
2023-12-19 22:21:34 +01:00
|
|
|
// noinspection JSUnusedGlobalSymbols
|
2023-12-18 01:30:02 +01:00
|
|
|
public fakeMeasurements(rotateAlpha: boolean = true) {
|
|
|
|
console.log("Starting fake measurements of orientation sensors", {
|
|
|
|
alpha: this.alpha,
|
|
|
|
beta: this.beta,
|
|
|
|
gamma: this.gamma,
|
|
|
|
absolute: this.absolute,
|
|
|
|
})
|
2023-12-16 01:29:42 +01:00
|
|
|
this.alpha.setData(45)
|
2023-12-19 22:21:34 +01:00
|
|
|
|
2023-12-18 01:30:02 +01:00
|
|
|
if (rotateAlpha) {
|
2023-12-19 22:21:34 +01:00
|
|
|
this._animateFakeMeasurements = true
|
|
|
|
Stores.Chronic(25).addCallback((date) => {
|
2023-12-24 05:01:10 +01:00
|
|
|
this.alpha.setData((date.getTime() / 50) % 360)
|
2023-12-19 22:21:34 +01:00
|
|
|
if (!this._animateFakeMeasurements) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
})
|
2023-12-18 01:30:02 +01:00
|
|
|
}
|
2023-12-16 01:29:42 +01:00
|
|
|
this.beta.setData(20)
|
|
|
|
this.gamma.setData(30)
|
|
|
|
this.absolute.setData(true)
|
|
|
|
this.gotMeasurement.setData(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
public startMeasurements() {
|
|
|
|
if (this._measurementsStarted) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
this._measurementsStarted = true
|
|
|
|
console.log("Starting device orientation listener")
|
|
|
|
try {
|
|
|
|
window.addEventListener("deviceorientationabsolute", (e: DeviceOrientationEvent) =>
|
|
|
|
this.update(e)
|
|
|
|
)
|
|
|
|
} catch (e) {
|
|
|
|
console.log("Could not init device orientation api due to", e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private update(event: DeviceOrientationEvent) {
|
2024-02-15 16:02:22 +01:00
|
|
|
if(event.alpha === null || event.beta === null || event.gamma === null){
|
|
|
|
return
|
|
|
|
}
|
2023-12-16 01:29:42 +01:00
|
|
|
this.gotMeasurement.setData(true)
|
|
|
|
// IF the phone is lying flat, then:
|
|
|
|
// alpha is the compass direction (but not absolute)
|
|
|
|
// beta is tilt if you would lift the phone towards you
|
|
|
|
// gamma is rotation if you rotate the phone along the long axis
|
|
|
|
|
|
|
|
// Note: the event uses _counterclockwise_ = positive for alpha
|
|
|
|
// However, we use _clockwise_ = positive throughout the application, so we use '-' here!
|
|
|
|
this.alpha.setData(Math.floor(360 - event.alpha))
|
|
|
|
this.beta.setData(Math.floor(event.beta))
|
|
|
|
this.gamma.setData(Math.floor(event.gamma))
|
|
|
|
this.absolute.setData(event.absolute)
|
|
|
|
if (this.beta.data < 0) {
|
|
|
|
this.arrowDirection.setData(this.gamma.data + 180)
|
|
|
|
} else {
|
|
|
|
this.arrowDirection.setData(-this.gamma.data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|