小程序的wx.onAccelerometerChange

https://www.2cto.com/kf/201802/724174.html(copy)

也许有人会问,小程序中都是竖直app形态,要横竖屏判断有什么用?即使判断出了横屏状态,你能把小程序横过来?答案是不能的,但是判断当前设备处于横屏或者竖屏状态来实现一些友好的用户体验交互方式的需求确实存在。例如手机横屏,让视频播放自动全屏,手机竖屏,让视频切换回来小屏。

然而,截止至目前,小程序官方的API中并没有提供这样的横竖屏判断的方法。那么我们只能自己想办法实现这样的判断。小程序的设备API中提供了加速度计的监听方法,使用方法如下:

wx.onAccelerometerChange(function(res) {

console.log(res.x)

console.log(res.y)

console.log(res.z)

})

加速度计的三轴

以下是一般移动设备的加速度计三轴坐标系示例图:

以手机竖直面向用户为例,加速计的三轴坐标系统的X、Y、Z轴定义如下:

沿着手机屏幕顶部向上是Y轴正方向,向下是Y轴负方向;

当手机顶部朝上时,沿着手机屏幕向右是X轴正方向,向左是X轴负方向;

正对手机时,垂直屏幕向外是Z轴正方向,垂直屏幕向里是Z轴负方向;

当手机处于静止状态时,手机此时只受一个重力加速度(1g=9.8m/s2)的作用,加速度计返回的res.x、res.y、res.z的值就是设备的三轴受到的加速度的值,取值范围从[-1g,1g]。设备以不同方式放置时,x/y/z的值如下:

计算姿态角

在stackoverflow上找到了根据加速度计三轴的值计算姿态角公式,经过结合设备的三轴坐标方向对公式进行调整,最终得出了公式:

Pitch = atan2(Y, Z) * 180/M_PI;Roll = atan2(-X, sqrt(Y*Y+ Z*Z)) * 180/M_PI;

Roll = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI;

Roll(绕Y轴旋转的角度)

当设备绕着自身Y轴旋转时(表示手机左侧或右侧翘起的角度),该角度值将会发生变化,取值范围是-90到90度。

Pitch(绕X轴旋转的角度)

当手机绕着自身的Y轴旋转(表示手机顶部或尾部翘起的角度),该角度会发生变化,值的范围是-180到180度。

接下来就是根据自己对横竖屏角度的观测,再结合微信小程序中,视频全屏只能以手机向左旋转方式全屏的特性,只对用户左侧横屏判断为横屏状态,实现代码片段如下:

// 0为竖屏,1为横屏

let lastState = 0;

let lastTime = Date.now();

wx.startAccelerometer();

wx.onAccelerometerChange((res) => {

const now = Date.now();

// 500ms检测一次

if (now - lastTime < 500) {

return;

}

lastTime = now;

let nowState;

// 57.3 = 180 / Math.PI

const Roll = Math.atan2(-res.x, Math.sqrt(res.y * res.y + res.z * res.z)) * 57.3;

const Pitch = Math.atan2(res.y, res.z) * 57.3;

// console.log(‘Roll: ‘ + Roll, ‘Pitch: ‘ + Pitch)

// 横屏状态

if (Roll > 50) {

if ((Pitch > -180 && Pitch < -60) || (Pitch > 130)) {

nowState = 1;

} else {

nowState = lastState;

}

} else if ((Roll > 0 && Roll < 30) || (Roll < 0 && Roll > -30)) {

let absPitch = Math.abs(Pitch);

// 如果手机平躺,保持原状态不变,40容错率

if ((absPitch > 140 || absPitch < 40)) {

nowState = lastState;

} else if (Pitch < 0) { /*收集竖向正立的情况*/

nowState = 0;

} else {

nowState = lastState;

}

}

else {

nowState = lastState;

}

// 状态变化时,触发

if (nowState !== lastState) {

lastState = nowState;

if (nowState === 1) {

console.log(‘change:横屏‘);

} else {

console.log(‘change:竖屏‘);

}

}

});

然后就可以在横竖屏切换的状态下,去切换视频的横竖屏了

if (state === 1) {

video.requestFullScreen();

} else {

video.exitFullScreen();

}

其他

另外,在这里发现小程序的一个小bug,就是当进入一个页面,马上就调用requestFullScreen()方法去拉起视频全屏时,会破坏整个页面的布局,并且再调用全屏方法时,视频就无法再全屏了,像这样:

所以为了防止用户直接以横屏的状态进入一个视频播放页,而我们的横屏判断检测生效立即触发全屏引发bug,我将监听横竖屏的事件通过setTimeout(listener, 3000)延迟3s监听,这样横屏才不会触发bug。

原文地址:https://www.cnblogs.com/dianzan/p/9668488.html

时间: 2024-11-12 20:31:43

小程序的wx.onAccelerometerChange的相关文章

微信应用号小程序下载wx.downloadFile(OBJECT)

微信应用号小程序下载wx.downloadFile(OBJECT) wx.downloadFile(OBJECT) ? 下载文件资源到本地.客户端直接发起一个HTTP GET请求,把下载到的资源根据 type 进行处理,并返回文件的本地临时路径. OBJECT参数说明: 参数 类型 必填 必填 url String 是 下载资源的 url type String 否 下载资源的类型,用于客户端识别处理,有效值:image/audio/video header Object 否 HTTP 请求 H

微信 小程序 drawImage wx.canvasToTempFilePath wx.saveFile 获取设备宽高 尺寸问题

以下问题测试环境为微信开发者0.10.102800,手机端iphone6,如有不对敬谢指出. 根据我的测试,context.drawImage,在开发者工具中并不能画出来,只有预览到手机中显示. wx.canvasToTempFilePath wx.saveFile 官方文档中只有一行,真是坑爹啊,原来 wx.canvasToTempFilePath参数为一个对象包括canvasID,success,fail,complete,和wx.saveFile差不多: wx.canvasToTempFi

小程序,wx.request;动态向服务器端请求数据。

wx.request 通过微信封装的ajax,动态向服务器端请求数据.以下是在练习微信小程序时写的测试代码. 其中index.js文件如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //测试: wx.request({      url:'http://hd.jz-lm.com/mobile/Ceshi/index',      method: 'GET',      data: {},      header: {          'Ac

小程序开发wx.scanCode扫一扫接口,可以代替部分扫码枪的工作了

小程序扫码接口wx.scanCode挺有意思, 以后会代替部分扫码枪的工作, 而且小程序扫一扫还有自己特色的功能, 是扫码枪不具备的. 线下店面, 或许将来不需要电脑收银系统, 直接可以使用大屏手机, 就可以进行收付款, 商品管理. 在开发过程中, 使用小wx.scanCode()接口, 扫描了一些常见的应用场景, 得到的结果如下: 1. 扫描小程序码 返回结果 {"errMsg":"scanCode:ok","result":"*&q

微信小程序之 wx.getUserInfo引导用户授权问题

首先,在page外定义一个函数用户判断是否为空对象 var isEmptyObject = function (e) { var temp; for (temp in e) return !1; return !0 } 然后,在page中的onload里面调用授权 onLoad: function () { var that = this; if (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInf

微信小程序之wx.navigateback往回携带参数

在微信小程序开发的过程当中  经常碰到一些带逻辑的一些事情 就比如 新增地址 修改地址  筛选用户条件等页面的时候  我们也可以用wx.navigateTo来跳转实现 但其中有很多问题 1.微信的十层跳转  当你用navigateTo跳转的时候跳转十次的时候就跳不动了 2.参数的传递 我们在用navigateTo跳转的时候通常带着参数来跳  试想一下 如果我们一种这么跳 那么携带的参数越来越多 这不是开发的一个好事情 所以在以上的问题上我们可以用navigateback来实现  既仅携带本次跳转

微信小程序之wx.requestPayment 发起微信支付

wx.requestPayment 发起微信支付 timeStamp 时间戳 nonceStr 随机字符串 package 统一下单接口返回的 prepay_id 参数值 signType 签名算法 paySign 支付签名 success 接口成功回调 fail 接口失败回调 complete 接口完成回调(成功,失败都执行) 1.先调用后台接口,生产基本数据 // 获取店铺信息 Api.BalancePay({ openid: openid, amount: amount, bid: bid

【微信小程序】 wx:if 与 hidden(隐藏元素)区别

wx:if 与 hidden 都可以控制微信小程序中元素的显示与否. 区别: wx:if 是遇 true 显示,hidden 是遇 false 显示. wx:if 在隐藏的时候不渲染,而 hidden 在隐藏时仍然渲染,只是不呈现. 所以如果频繁切换的话,用 wx:if 将会消耗更多资源,因为每次呈现的时候他都会渲染,每次隐藏的时候,他都会销毁. 如果切换并不频繁的话,用 wx:if 相对来说较好些,因为它会避免初始就一下渲染那么多. wxml: <view> <text>page

小程序,wx.request请求数据服务器配置

微信小程序服务器配置时有个坑,中间遇到过一次. 在进行服务器域名配置的时,一定要按照文档的规范: 填写的域名是https://x.b5h.com 不能写成https://www.x.b5h.com 用https://www.x.b5h.com进行数据请求时,会出错,文件请求失败,在服务器端找不到文件,控制台报错为404错误.