更新记录
1.1.0(2026-06-25) 下载此版本
- 重构插件目录结构,拆分 core、services、entities、utils、game 模块。
- 新增权限服务、实时监听服务、单次获取服务、生命周期服务、能力检测服务。
- 修复浏览器切换后台再返回后监听状态和数据缓存异常的问题。
- 新增统一陀螺仪数据实体,补充 timestamp、source、alpha、beta、gamma、radianX、radianY、radianZ、isValid、isStale、raw 字段。
- 新增
getGyroscope单次获取 API。 - 新增
requestGyroscopePermission独立权限申请 API。 - 修复
startGyroscope({ interval })未真实限制业务回调频率的问题。 - 新增游戏重力控制器、虚拟摇杆、倾斜方向识别和归一化工具 API。
1.0.0(2025-07-08) 下载此版本
H5 陀螺仪插件 - 为 uni-app 提供 H5 平台的陀螺仪功能支持
平台兼容性
uni-app(4.44)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | - | - | - | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
jz-h5-gyroscope
H5 陀螺仪插件 - 为 uni-app 提供 H5 平台陀螺仪能力。
当前版本已从单文件实现升级为模块化实现,除了兼容原来的实时监听 API,还新增了权限申请、单次获取、状态检测、后台恢复、游戏重力控制、虚拟摇杆、倾斜方向识别等能力。
功能概览
兼容原有能力
startGyroscope(options):开始实时监听陀螺仪。stopGyroscope(options):停止实时监听。onGyroscopeChange(callback):监听陀螺仪变化。offGyroscopeChange(callback):取消监听陀螺仪变化。getGyroscopeStatus():获取当前监听状态。
新增能力
getGyroscope(options):单次获取一次陀螺仪数据。requestGyroscopePermission(options):单独申请 iOS 陀螺仪权限。getGyroscopeSupportInfo():获取当前浏览器传感器支持情况。normalizeGyroscope(data, options):把角度数据转换成-1 ~ 1的游戏输入值。toGravityVector(data, options):把陀螺仪数据转换成重力移动向量。createGameController(options):创建游戏重力控制器,适合重力球、体感移动等场景。createVirtualJoystick(options):创建陀螺仪虚拟摇杆。getTiltDirection(data, options):获取当前倾斜方向。
适用场景
- H5 页面获取手机陀螺仪数据。
- iOS Safari / Android 浏览器中实现体感控制。
- 重力球、倾斜移动、飞行控制、方向识别。
- 把手机倾斜转换成游戏摇杆输入。
- 需要兼容 uni-app 风格 API 的 H5 项目。
平台支持
| 平台 | 支持情况 | 说明 |
|---|---|---|
| H5 Safari iOS | 支持 | iOS 13+ 需要用户点击触发权限申请 |
| H5 Chrome Android | 支持 | 通常无需额外权限 |
| H5 微信浏览器 Android | 支持 | 依赖设备和浏览器传感器能力 |
| H5 微信浏览器 iOS | 可能支持 | 受 iOS WebView 和权限策略影响 |
| H5 PC 浏览器 | 部分支持 | 大多数 PC 没有陀螺仪传感器 |
| App | 不支持 | 请使用 uni-app 官方 API |
| 小程序 | 不支持 | 请使用小程序官方 API |
安装和导入
import jzH5Gyroscope from '@/uni_modules/jz-h5-gyroscope/index.js'
快速开始
基础实时监听
export default {
data() {
return {
gyroscopeData: null
}
},
onLoad() {
jzH5Gyroscope.onGyroscopeChange(data => {
this.gyroscopeData = data
console.log('陀螺仪数据', data)
})
},
methods: {
startGyroscope() {
jzH5Gyroscope.startGyroscope({
interval: 200,
success: res => {
console.log('启动成功', res)
},
fail: err => {
console.log('启动失败', err)
},
complete: res => {
console.log('调用结束', res)
}
})
},
stopGyroscope() {
jzH5Gyroscope.stopGyroscope({
success: res => {
console.log('停止成功', res)
}
})
}
},
onUnload() {
jzH5Gyroscope.stopGyroscope()
jzH5Gyroscope.offGyroscopeChange()
}
}
iOS 端请把
startGyroscope绑定到按钮点击事件,不要在onLoad、mounted中自动启动。
iOS 使用方式
iOS 13+ 的 Safari 要求陀螺仪权限必须由用户手势触发,例如按钮点击。
推荐写法:
methods: {
startByUserTap() {
jzH5Gyroscope.requestGyroscopePermission({
success: () => {
jzH5Gyroscope.onGyroscopeChange(data => {
console.log('陀螺仪数据', data)
})
jzH5Gyroscope.startGyroscope({
interval: 200,
success: res => {
console.log('监听已启动', res)
},
fail: err => {
console.log('启动失败', err)
}
})
},
fail: err => {
console.log('权限申请失败', err)
}
})
}
}
模板示例:
<button @click="startByUserTap">开启陀螺仪</button>
iOS 注意事项
- 必须使用 HTTPS 页面。
- 权限申请必须由点击、触摸等用户动作触发。
- 如果 Safari 设置中关闭了“动作与方向访问”,浏览器可能不会返回数据。
- iOS 微信浏览器、部分 App 内置 WebView 可能受到系统限制,不能保证所有版本都可用。
API 文档
startGyroscope(options)
开始实时监听陀螺仪数据。
jzH5Gyroscope.startGyroscope({
interval: 200,
success(res) {},
fail(err) {},
complete(res) {}
})
参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| interval | Number/String | 200 | 回调触发间隔,单位 ms |
| success | Function | - | 启动成功回调 |
| fail | Function | - | 启动失败回调 |
| complete | Function | - | 调用完成回调 |
interval 支持:
| 值 | 实际间隔 |
|---|---|
20 |
20ms |
60 |
60ms |
200 |
200ms |
'game' |
20ms |
'ui' |
60ms |
'normal' |
200ms |
说明:
- 插件会先更新内部最新数据,再根据
interval节流业务回调。 - 页面切后台后不会清空最近数据。
- 页面恢复后,如果用户没有主动停止,会自动重新绑定传感器监听。
stopGyroscope(options)
停止实时监听。
jzH5Gyroscope.stopGyroscope({
success(res) {},
fail(err) {},
complete(res) {}
})
说明:
- 这是用户主动停止。
- 停止后页面恢复不会自动重新监听。
- 最近一次有效数据会保留,可用于状态查看或短时间缓存读取。
onGyroscopeChange(callback)
注册实时数据回调。
const callback = data => {
console.log(data.x, data.y, data.z)
}
jzH5Gyroscope.onGyroscopeChange(callback)
说明:
- 相同
callback不会重复注册。 - 回调频率受
startGyroscope({ interval })控制。
offGyroscopeChange(callback)
取消监听。
// 取消指定回调
jzH5Gyroscope.offGyroscopeChange(callback)
// 取消全部回调
jzH5Gyroscope.offGyroscopeChange()
getGyroscope(options)
单次获取一次陀螺仪数据。
适合只需要获取一次当前手机姿态的场景。
jzH5Gyroscope.getGyroscope({
maxAge: 300,
timeout: 1000,
success(data) {
console.log('单次数据', data)
},
fail(err) {
console.log('获取失败', err)
},
complete(res) {}
})
参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| maxAge | Number | 300 | 可接受缓存数据的最大时长,单位 ms |
| timeout | Number | 1000 | 没有缓存时等待新数据的超时时间,单位 ms |
| success | Function | - | 获取成功回调 |
| fail | Function | - | 获取失败回调 |
| complete | Function | - | 完成回调 |
规则:
- 有未过期缓存时,立即返回缓存数据。
- 没有缓存时,临时监听下一次真实传感器事件。
- 如果原本没有启动实时监听,单次获取完成后会自动停止临时监听。
- 超时仍无数据时返回失败。
requestGyroscopePermission(options)
单独申请陀螺仪权限。
jzH5Gyroscope.requestGyroscopePermission({
success(res) {
console.log('权限结果', res)
},
fail(err) {
console.log('权限失败', err)
},
complete(res) {}
})
返回示例:
{
granted: true,
state: 'granted',
required: true,
errMsg: 'requestGyroscopePermission:ok'
}
字段说明:
| 字段 | 说明 |
|---|---|
| granted | 是否已授权 |
| state | 权限状态,常见值为 granted、denied、prompt |
| required | 当前浏览器是否需要主动权限申请 |
| errMsg | 调用结果信息 |
getGyroscopeStatus()
获取当前插件状态。
const status = jzH5Gyroscope.getGyroscopeStatus()
console.log(status)
返回示例:
{
isListening: true,
isPageHidden: false,
isSupported: true,
interval: 200,
callbackCount: 1,
lastData: null,
lastEventAt: 0,
errMsg: 'getGyroscopeStatus:ok'
}
字段说明:
| 字段 | 说明 |
|---|---|
| isListening | 是否处于监听状态 |
| isPageHidden | 页面是否处于后台或隐藏状态 |
| isSupported | 当前浏览器是否支持传感器事件 |
| interval | 当前业务回调间隔 |
| callbackCount | 当前注册的回调数量 |
| lastData | 最近一次有效陀螺仪数据 |
| lastEventAt | 最近一次传感器事件时间戳 |
| errMsg | 状态信息 |
getGyroscopeSupportInfo()
获取浏览器传感器支持信息。
const support = jzH5Gyroscope.getGyroscopeSupportInfo()
console.log(support)
返回示例:
{
hasDeviceOrientation: true,
hasDeviceMotion: true,
isSecureContext: true,
needsPermission: true,
isSupported: true
}
字段说明:
| 字段 | 说明 |
|---|---|
| hasDeviceOrientation | 是否支持 DeviceOrientationEvent |
| hasDeviceMotion | 是否支持 DeviceMotionEvent |
| isSecureContext | 当前页面是否为安全上下文 |
| needsPermission | 是否需要主动调用权限申请 |
| isSupported | 是否至少支持一种传感器事件 |
数据结构
实时监听、单次获取返回的 data 结构:
{
x: 0,
y: 0,
z: 0,
alpha: 0,
beta: 0,
gamma: 0,
radianX: 0,
radianY: 0,
radianZ: 0,
timestamp: 0,
source: 'deviceorientation',
isValid: true,
isStale: false,
raw: null
}
字段说明:
| 字段 | 说明 |
|---|---|
| x | 兼容字段,对应 beta |
| y | 兼容字段,对应 gamma |
| z | 兼容字段,对应 alpha |
| alpha | 浏览器原始 Z 轴方向角 |
| beta | 浏览器原始 X 轴方向角 |
| gamma | 浏览器原始 Y 轴方向角 |
| radianX | x 对应弧度值 |
| radianY | y 对应弧度值 |
| radianZ | z 对应弧度值 |
| timestamp | 数据产生时间戳 |
| source | 数据来源,deviceorientation 或 devicemotion |
| isValid | 数据是否有效 |
| isStale | 是否为过期缓存数据 |
| raw | 浏览器原始事件对象 |
游戏能力
normalizeGyroscope(data, options)
把陀螺仪角度转换成 -1 ~ 1 的归一化输入。
适合自己实现游戏控制逻辑。
const normalized = jzH5Gyroscope.normalizeGyroscope(data, {
maxAngle: 45,
sensitivity: 1,
deadZone: 0.05,
adjustScreen: true
})
console.log(normalized.x, normalized.y)
返回示例:
{
x: 0.25,
y: -0.4,
source: 'deviceorientation',
raw: data
}
参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
| maxAngle | 45 | 最大倾斜角,超过后按最大值计算 |
| sensitivity | 1 | 灵敏度 |
| deadZone | 0 | 死区,小于该值按 0 处理 |
| adjustScreen | true | 是否根据横竖屏修正方向 |
toGravityVector(data, options)
把陀螺仪数据转换成游戏移动向量。
const vector = jzH5Gyroscope.toGravityVector(data, {
sensitivity: 1.2,
deadZone: 0.05,
maxStrength: 1,
smoothFactor: 0.2,
invertX: false,
invertY: false,
maxAngle: 45,
adjustScreen: true
})
console.log(vector)
返回示例:
{
x: 0.25,
y: -0.4,
length: 0.47,
angle: -57.99,
direction: 'right-up',
strength: 0.47
}
createGameController(options)
创建一个可持续使用的重力控制器。
相比 toGravityVector,它会保留上一次数据,用于平滑滤波,适合游戏循环中持续调用。
const controller = jzH5Gyroscope.createGameController({
sensitivity: 1.2,
deadZone: 0.05,
smoothFactor: 0.2
})
jzH5Gyroscope.onGyroscopeChange(data => {
const vector = controller.update(data)
player.x += vector.x * 5
player.y += vector.y * 5
})
控制器方法:
| 方法 | 说明 |
|---|---|
| update(data, options) | 输入陀螺仪数据,返回游戏向量 |
| reset() | 清空平滑滤波历史 |
配置参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
| sensitivity | 1 | 灵敏度 |
| deadZone | 0.05 | 死区 |
| maxStrength | 1 | 最大强度 |
| smoothFactor | 0.2 | 平滑系数,越小越平滑 |
| invertX | false | 是否反转 X 方向 |
| invertY | false | 是否反转 Y 方向 |
| maxAngle | 45 | 最大倾斜角 |
| adjustScreen | true | 是否根据横竖屏修正方向 |
createVirtualJoystick(options)
把陀螺仪转换成类似虚拟摇杆的数据。
const joystick = jzH5Gyroscope.createVirtualJoystick({
deadZone: 0.08,
sensitivity: 1
})
jzH5Gyroscope.onGyroscopeChange(data => {
const joy = joystick.update(data)
if (joy.pressed) {
console.log('摇杆方向', joy.direction)
console.log('轴值', joy.axisX, joy.axisY)
}
})
返回示例:
{
axisX: 0.25,
axisY: -0.4,
pressed: true,
strength: 0.47,
direction: 'right-up'
}
getTiltDirection(data, options)
获取倾斜方向。
const direction = jzH5Gyroscope.getTiltDirection(data, {
deadZone: 0.05,
mode: 'eight'
})
console.log(direction)
方向值:
center
left
right
up
down
left-up
left-down
right-up
right-down
参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
| deadZone | 0.05 | 死区 |
| mode | eight | four 四方向,eight 八方向 |
完整游戏示例
import jzH5Gyroscope from '@/uni_modules/jz-h5-gyroscope/index.js'
export default {
data() {
return {
player: {
x: 100,
y: 100
},
controller: null
}
},
onLoad() {
this.controller = jzH5Gyroscope.createGameController({
sensitivity: 1.5,
deadZone: 0.05,
smoothFactor: 0.15
})
jzH5Gyroscope.onGyroscopeChange(this.handleGyroscope)
},
methods: {
startGameControl() {
jzH5Gyroscope.startGyroscope({
interval: 'game',
success: () => {
console.log('体感控制已开启')
}
})
},
handleGyroscope(data) {
const vector = this.controller.update(data)
this.player.x += vector.x * 5
this.player.y += vector.y * 5
}
},
onUnload() {
jzH5Gyroscope.offGyroscopeChange(this.handleGyroscope)
jzH5Gyroscope.stopGyroscope()
}
}
错误对象
失败时通常返回:
{
errMsg: 'startGyroscope:fail 当前浏览器不支持陀螺仪功能',
code: 'NOT_SUPPORTED',
method: 'startGyroscope',
detail: null
}
常见错误码:
| 错误码 | 说明 |
|---|---|
| NOT_SUPPORTED | 当前浏览器不支持传感器事件 |
| PERMISSION_DENIED | 用户拒绝权限 |
| PERMISSION_ERROR | 权限申请异常 |
| TIMEOUT | 单次获取超时 |
| NO_VALID_DATA | 没有获取到有效数据 |
兼容性和注意事项
HTTPS 要求
现代浏览器通常要求 HTTPS 页面才能访问传感器。
iOS 权限要求
iOS 13+ 必须在用户点击中调用权限申请或启动监听:
<button @click="startGyroscope">开启</button>
不要这样做:
onLoad() {
jzH5Gyroscope.startGyroscope()
}
后台恢复
插件会监听页面生命周期:
- 页面隐藏时移除传感器监听,但保留最近数据。
- 页面恢复时,如果不是用户主动停止,会重新绑定监听。
getGyroscopeStatus().lastData.isStale可判断最近数据是否过期。
数据方向
基础数据中:
x = betay = gammaz = alpha
游戏 API 会默认根据横竖屏修正方向。如果不需要修正,可以传入:
{
adjustScreen: false
}
与旧版本差异
| 能力 | 旧版本 | 新版本 |
|---|---|---|
| 目录结构 | 单文件 | 多模块拆分 |
| 权限申请 | 启动时内部处理 | 支持单独调用 requestGyroscopePermission |
| 实时监听 | 支持 | 支持,且 interval 真实生效 |
| 回调管理 | 数组,可能重复 | Set 去重 |
| 单次获取 | 不支持 | 支持 getGyroscope |
| 状态查询 | 简单状态 | 增加页面隐藏、支持情况、最近事件时间 |
| 后台恢复 | 不完善 | 页面恢复后自动续接监听 |
| 数据结构 | { x, y, z } |
扩展 timestamp/source/raw/isStale 等字段 |
| 游戏能力 | 不支持 | 支持重力向量、虚拟摇杆、方向识别 |
更新日志
v1.1.0
- 模块化重构插件代码。
- 新增权限服务、实时监听服务、单次获取服务、生命周期服务、能力检测服务。
- 新增
getGyroscope单次获取。 - 新增
requestGyroscopePermission独立权限申请。 - 新增
getGyroscopeSupportInfo能力检测。 - 修复
interval未真实限制业务回调频率的问题。 - 修复页面后台切换后数据异常和监听恢复问题。
- 新增游戏重力控制器、虚拟摇杆、倾斜方向识别。
v1.0.0
- 初始版本发布。
- 支持 H5 陀螺仪实时监听。
- 支持 iOS 权限请求。
许可证
MIT License
本插件仅面向 H5 环境。App、小程序等平台请优先使用对应平台官方陀螺仪 API。

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 2526
赞赏 0
下载 12424209
赞赏 1934
赞赏
京公网安备:11010802035340号