Vibration.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow
  9. * @jsdoc
  10. */
  11. 'use strict';
  12. import NativeVibration from './NativeVibration';
  13. const Platform = require('../Utilities/Platform');
  14. /**
  15. * Vibration API
  16. *
  17. * See https://reactnative.dev/docs/vibration.html
  18. */
  19. let _vibrating: boolean = false;
  20. let _id: number = 0; // _id is necessary to prevent race condition.
  21. const _default_vibration_length = 400;
  22. function vibrateByPattern(pattern: Array<number>, repeat: boolean = false) {
  23. if (_vibrating) {
  24. return;
  25. }
  26. _vibrating = true;
  27. if (pattern[0] === 0) {
  28. NativeVibration.vibrate(_default_vibration_length);
  29. pattern = pattern.slice(1);
  30. }
  31. if (pattern.length === 0) {
  32. _vibrating = false;
  33. return;
  34. }
  35. setTimeout(() => vibrateScheduler(++_id, pattern, repeat, 1), pattern[0]);
  36. }
  37. function vibrateScheduler(
  38. id,
  39. pattern: Array<number>,
  40. repeat: boolean,
  41. nextIndex: number,
  42. ) {
  43. if (!_vibrating || id !== _id) {
  44. return;
  45. }
  46. NativeVibration.vibrate(_default_vibration_length);
  47. if (nextIndex >= pattern.length) {
  48. if (repeat) {
  49. nextIndex = 0;
  50. } else {
  51. _vibrating = false;
  52. return;
  53. }
  54. }
  55. setTimeout(
  56. () => vibrateScheduler(id, pattern, repeat, nextIndex + 1),
  57. pattern[nextIndex],
  58. );
  59. }
  60. const Vibration = {
  61. /**
  62. * Trigger a vibration with specified `pattern`.
  63. *
  64. * See https://reactnative.dev/docs/vibration.html#vibrate
  65. */
  66. vibrate: function(
  67. pattern: number | Array<number> = _default_vibration_length,
  68. repeat: boolean = false,
  69. ) {
  70. if (Platform.OS === 'android') {
  71. if (typeof pattern === 'number') {
  72. NativeVibration.vibrate(pattern);
  73. } else if (Array.isArray(pattern)) {
  74. NativeVibration.vibrateByPattern(pattern, repeat ? 0 : -1);
  75. } else {
  76. throw new Error('Vibration pattern should be a number or array');
  77. }
  78. } else {
  79. if (_vibrating) {
  80. return;
  81. }
  82. if (typeof pattern === 'number') {
  83. NativeVibration.vibrate(pattern);
  84. } else if (Array.isArray(pattern)) {
  85. vibrateByPattern(pattern, repeat);
  86. } else {
  87. throw new Error('Vibration pattern should be a number or array');
  88. }
  89. }
  90. },
  91. /**
  92. * Stop vibration
  93. *
  94. * See https://reactnative.dev/docs/vibration.html#cancel
  95. */
  96. cancel: function() {
  97. if (Platform.OS === 'ios') {
  98. _vibrating = false;
  99. } else {
  100. NativeVibration.cancel();
  101. }
  102. },
  103. };
  104. module.exports = Vibration;