小编第一次写博客,如有哪不对 请多多包含
本编讲的是在微信公众号模仿微信摇一摇的采坑之路,供大家参考 小编只做个搬运工
源码地址:https://alexgibson.github.io/shake.js
实现原理:
- 微信摇一摇事件需要有硬件支撑,要求手机中有 陀螺仪(顾明思议它是利用手机硬件来做支撑)
- 通过陀螺仪的重力加速来判断当前用户手动摇动的重力感应,并获取到指来做函数的判断
- 最终要的一点是ios升级12.2以上系统包括12.2,需要用到https协议进行访问处理,因为ios新增了这个隐私设置
下面就来点干货吧!!!
shake.js
针对使用设备加速计的移动网络浏览器的自定义“摇动”事件JavaScript插件。
(function(global, factory) {
if (typeof define === 'function' && define.amd) {
define(function() {
return factory(global, global.document);
});
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = factory(global, global.document);
} else {
global.Shake = factory(global, global.document);
}
} (typeof window !== 'undefined' ? window : this, function (window, document) {
'use strict';
function Shake(options) {
//feature detect
this.hasDeviceMotion = 'ondevicemotion' in window;
this.options = {
threshold: 15, //default velocity threshold for shake to register
timeout: 1000 //default interval between events
};
if (typeof options === 'object') {
for (var i in options) {
if (options.hasOwnProperty(i)) {
this.options[i] = options[i];
}
}
}
//use date to prevent multiple shakes firing
this.lastTime = new Date();
//accelerometer values
this.lastX = null;
this.lastY = null;
this.lastZ = null;
//create custom event
if (typeof document.CustomEvent === 'function') {
this.event = new document.CustomEvent('shake', {
bubbles: true,
cancelable: true
});
} else if (typeof document.createEvent === 'function') {
this.event = document.createEvent('Event');
this.event.initEvent('shake', true, true);
} else {
return false;
}
}
//reset timer values
Shake.prototype.reset = function () {
this.lastTime = new Date();
this.lastX = null;
this.lastY = null;
this.lastZ = null;
};
//start listening for devicemotion
Shake.prototype.start = function () {
this.reset();
if (this.hasDeviceMotion) {
window.addEventListener('devicemotion', this, false);
}
};
//stop listening for devicemotion
Shake.prototype.stop = function () {
if (this.hasDeviceMotion) {
window.removeEventListener('devicemotion', this, false);
}
this.reset();
};
//calculates if shake did occur
Shake.prototype.devicemotion = function (e) {
var current = e.accelerationIncludingGravity;
var currentTime;
var timeDifference;
var deltaX = 0;
var deltaY = 0;
var deltaZ = 0;
if ((this.lastX === null) && (this.lastY === null) && (this.lastZ === null)) {
this.lastX = current.x;
this.lastY = current.y;
this.lastZ = current.z;
return;
}
deltaX = Math.abs(this.lastX - current.x);
deltaY = Math.abs(this.lastY - current.y);
deltaZ = Math.abs(this.lastZ - current.z);
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))) {
//calculate time in milliseconds since last shake registered
currentTime = new Date();
timeDifference = currentTime.getTime() - this.lastTime.getTime();
if (timeDifference > this.options.timeout) {
window.dispatchEvent(this.event);
this.lastTime = new Date();
}
}
this.lastX = current.x;
this.lastY = current.y;
this.lastZ = current.z;
};
//event handler
Shake.prototype.handleEvent = function (e) {
if (typeof (this[e.type]) === 'function') {
return this[e.type](e);
}
};
return Shake;
}));
引入
var Shake = require('shake.js');
创建一个新的Shake实例:
var shakeEvent = new Shake({
threshold: 15, // 可选震动强度阈值 (默认15)
timeout: 1000 // 可选的事件
});
开始听设备动作
shakeEvent .start();
使用回调注册shake事件监听器window:
window.addEventListener('shake', shakeEventDidOccur, false);
window.addEventListener('shake', shakeEventDidOccur, false);
function shakeEventDidOccur () {//成功后调用的函数
alert('摇一摇成功')
}
踩坑总结:
这个问题纠结了好几天,后来因为项目耽搁了一直没做,前天想起来研究了一下。小编这次入坑最深的还是因为https协议的问题,一开始安卓和ios12.2以下的都可以,就是12.2版本以上的不行 后来根据这个问题也翻了不少的博客,最终在微信H5 ios升级12.2后 重力感应突然没用了 在这找到了答案,所以说不得不吐槽一下ios系统。 本人就是一个新晋码农, 只做大自然的搬砖工 初次分享,多多指教
支持的Web浏览器/设备
- iOS Safari 4.2.1 (以上)
- Android 4.0.3(默认浏览器)
- FirefoxOS设备