export interface DeviceMotionControllerCallbacks { onSample: (alpha: number | null, beta: number | null, gamma: number | null) => void onError: (message: string) => void } export class DeviceMotionController { callbacks: DeviceMotionControllerCallbacks listening: boolean starting: boolean motionCallback: ((result: WechatMiniprogram.OnDeviceMotionChangeCallbackResult) => void) | null constructor(callbacks: DeviceMotionControllerCallbacks) { this.callbacks = callbacks this.listening = false this.starting = false this.motionCallback = null } start(): void { if (this.listening || this.starting) { return } if (typeof wx.startDeviceMotionListening !== 'function' || typeof wx.onDeviceMotionChange !== 'function') { this.callbacks.onError('当前环境不支持设备方向监听') return } const callback = (result: WechatMiniprogram.OnDeviceMotionChangeCallbackResult) => { const alpha = typeof result.alpha === 'number' && !Number.isNaN(result.alpha) ? result.alpha : null const beta = typeof result.beta === 'number' && !Number.isNaN(result.beta) ? result.beta : null const gamma = typeof result.gamma === 'number' && !Number.isNaN(result.gamma) ? result.gamma : null this.callbacks.onSample(alpha, beta, gamma) } this.motionCallback = callback wx.onDeviceMotionChange(callback) this.starting = true wx.startDeviceMotionListening({ interval: 'game', success: () => { this.starting = false this.listening = true }, fail: (res) => { this.starting = false this.detachCallback() this.callbacks.onError(res && res.errMsg ? res.errMsg : 'startDeviceMotionListening failed') }, }) } stop(): void { this.detachCallback() wx.stopDeviceMotionListening({ complete: () => {}, }) this.starting = false this.listening = false } destroy(): void { this.stop() } private detachCallback(): void { if (!this.motionCallback) { return } if (typeof wx.offDeviceMotionChange === 'function') { wx.offDeviceMotionChange(this.motionCallback) } this.motionCallback = null } }