deviceMotionController.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. export interface DeviceMotionControllerCallbacks {
  2. onSample: (alpha: number | null, beta: number | null, gamma: number | null) => void
  3. onError: (message: string) => void
  4. }
  5. export class DeviceMotionController {
  6. callbacks: DeviceMotionControllerCallbacks
  7. listening: boolean
  8. starting: boolean
  9. motionCallback: ((result: WechatMiniprogram.OnDeviceMotionChangeCallbackResult) => void) | null
  10. constructor(callbacks: DeviceMotionControllerCallbacks) {
  11. this.callbacks = callbacks
  12. this.listening = false
  13. this.starting = false
  14. this.motionCallback = null
  15. }
  16. start(): void {
  17. if (this.listening || this.starting) {
  18. return
  19. }
  20. if (typeof wx.startDeviceMotionListening !== 'function' || typeof wx.onDeviceMotionChange !== 'function') {
  21. this.callbacks.onError('当前环境不支持设备方向监听')
  22. return
  23. }
  24. const callback = (result: WechatMiniprogram.OnDeviceMotionChangeCallbackResult) => {
  25. const alpha = typeof result.alpha === 'number' && !Number.isNaN(result.alpha) ? result.alpha : null
  26. const beta = typeof result.beta === 'number' && !Number.isNaN(result.beta) ? result.beta : null
  27. const gamma = typeof result.gamma === 'number' && !Number.isNaN(result.gamma) ? result.gamma : null
  28. this.callbacks.onSample(alpha, beta, gamma)
  29. }
  30. this.motionCallback = callback
  31. wx.onDeviceMotionChange(callback)
  32. this.starting = true
  33. wx.startDeviceMotionListening({
  34. interval: 'game',
  35. success: () => {
  36. this.starting = false
  37. this.listening = true
  38. },
  39. fail: (res) => {
  40. this.starting = false
  41. this.detachCallback()
  42. this.callbacks.onError(res && res.errMsg ? res.errMsg : 'startDeviceMotionListening failed')
  43. },
  44. })
  45. }
  46. stop(): void {
  47. this.detachCallback()
  48. wx.stopDeviceMotionListening({
  49. complete: () => {},
  50. })
  51. this.starting = false
  52. this.listening = false
  53. }
  54. destroy(): void {
  55. this.stop()
  56. }
  57. private detachCallback(): void {
  58. if (!this.motionCallback) {
  59. return
  60. }
  61. if (typeof wx.offDeviceMotionChange === 'function') {
  62. wx.offDeviceMotionChange(this.motionCallback)
  63. }
  64. this.motionCallback = null
  65. }
  66. }