Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

121 строка
3.2 KiB

  1. /*
  2. * Author: Alex Gibson
  3. * https://github.com/alexgibson/shake.js
  4. * License: MIT license
  5. */
  6. (function (global, factory) {
  7. if (typeof define === 'function' && define.amd) {
  8. define(function () {
  9. return factory(global, global.document);
  10. });
  11. } else if (typeof module !== 'undefined' && module.exports)
  12. module.exports = factory(global, global.document);
  13. else
  14. global.Shake = factory(global, global.document);
  15. })(typeof window !== 'undefined' ? window : this, function (window, document) {
  16. function Shake (options) {
  17. //feature detect
  18. this.hasDeviceMotion = 'ondevicemotion' in window;
  19. this.options = {
  20. threshold: 15, //default velocity threshold for shake to register
  21. timeout: 1000 //default interval between events
  22. };
  23. if (typeof options === 'object') {
  24. for (let i in options) {
  25. if (options.hasOwnProperty(i))
  26. this.options[i] = options[i];
  27. }
  28. }
  29. //use date to prevent multiple shakes firing
  30. this.lastTime = new Date();
  31. //accelerometer values
  32. this.lastX = null;
  33. this.lastY = null;
  34. this.lastZ = null;
  35. //create custom event
  36. if (typeof document.CustomEvent === 'function') {
  37. this.event = new document.CustomEvent('shake', {
  38. bubbles: true,
  39. cancelable: true
  40. });
  41. } else if (typeof document.createEvent === 'function') {
  42. this.event = document.createEvent('Event');
  43. this.event.initEvent('shake', true, true);
  44. } else
  45. return false;
  46. }
  47. //reset timer values
  48. Shake.prototype.reset = function () {
  49. this.lastTime = new Date();
  50. this.lastX = null;
  51. this.lastY = null;
  52. this.lastZ = null;
  53. };
  54. //start listening for devicemotion
  55. Shake.prototype.start = function () {
  56. this.reset();
  57. if (this.hasDeviceMotion)
  58. window.addEventListener('devicemotion', this, false);
  59. };
  60. //stop listening for devicemotion
  61. Shake.prototype.stop = function () {
  62. if (this.hasDeviceMotion)
  63. window.removeEventListener('devicemotion', this, false);
  64. this.reset();
  65. };
  66. //calculates if shake did occur
  67. Shake.prototype.devicemotion = function (e) {
  68. let current = e.accelerationIncludingGravity;
  69. let currentTime;
  70. let timeDifference;
  71. let deltaX = 0;
  72. let deltaY = 0;
  73. let deltaZ = 0;
  74. if ((this.lastX === null) && (this.lastY === null) && (this.lastZ === null)) {
  75. this.lastX = current.x;
  76. this.lastY = current.y;
  77. this.lastZ = current.z;
  78. return;
  79. }
  80. deltaX = Math.abs(this.lastX - current.x);
  81. deltaY = Math.abs(this.lastY - current.y);
  82. deltaZ = Math.abs(this.lastZ - current.z);
  83. if (((deltaX > this.options.threshold) && (deltaY > this.options.threshold)) || ((deltaX > this.options.threshold) && (deltaZ > this.options.threshold)) || ((deltaY > this.options.threshold) && (deltaZ > this.options.threshold))) {
  84. //calculate time in milliseconds since last shake registered
  85. currentTime = new Date();
  86. timeDifference = currentTime.getTime() - this.lastTime.getTime();
  87. if (timeDifference > this.options.timeout) {
  88. window.dispatchEvent(this.event);
  89. this.lastTime = new Date();
  90. }
  91. }
  92. this.lastX = current.x;
  93. this.lastY = current.y;
  94. this.lastZ = current.z;
  95. };
  96. //event handler
  97. Shake.prototype.handleEvent = function (e) {
  98. if (typeof (this[e.type]) === 'function')
  99. return this[e.type](e);
  100. };
  101. return Shake;
  102. });