前言
微信小程序提供了丰富的设备能力 API,让应用可以获取手机硬件传感器数据,实现触摸之外的更多交互方式。其中wx.onAccelerometerChange加速计监听接口,可以实时获取手机三轴加速度信息,基于该能力可以开发摇一摇、体感交互类场景。
本文将实现一款变脸交互小程序,支持点击图片切换脸谱、摇晃手机触发变脸两种交互模式,同时统计并展示累计变脸次数,完整演示加速计 API 的使用流程、事件绑定、数据渲染与业务逻辑封装。
开发环境:微信开发者工具,Skyline 渲染模式,原生小程序,不使用云服务。
实现效果
- 页面展示脸谱图像,点击图像,随机切换一张脸谱,累计变脸数字自增;
- 摇晃手机,触发加速计事件,弹出 Toast 提示 “摇一摇成功”,同时随机更换脸谱,累计变脸次数同步更新;
- 页面底部实时展示累计变脸总次数,两种交互行为都会进行计数统计。
核心 API 介绍
wx.onAccelerometerChange(function listener)
监听加速度数据事件。回调函数返回 res 对象,包含
x、y、z三个轴的加速度值。手机晃动时三轴数值会发生明显波动,我们可以设定阈值来识别摇晃动作。
- res.x:x 轴加速度
- res.y:y 轴加速度
- res.z:z 轴加速度
注意:小程序模拟器无法模拟传感器数据,摇晃交互必须在真机调试下才可以看到完整效果。
项目结构设计
face‑game ├─images # 脸谱资源,1.png ~14.png共14张脸谱图片 ├─pages │ └─index │ ├─index.wxml 页面结构 │ ├─index.wxss 页面局部样式 │ └─index.js 业务逻辑、传感器监听、数据处理 ├─app.json # 全局配置、渲染模式配置 └─app.wxss # 全局公共样式完整代码实现
1. app.json 全局配置
配置页面路由、导航栏样式以及 Skyline 渲染相关参数。
{ "pages": [ "pages/index/index" ], "window": { "navigationBarTextStyle": "black", "navigationStyle": "custom" }, "style": "v2", "renderer": "skyline", "rendererOptions": { "skyline": { "defaultDisplayBlock": true, "defaultContentBox": true, "tagNameStyleIsolation": "legacy", "disableABTest": true, "sdkVersionBegin": "3.0.0", "sdkVersionEnd": "15.255.255" } }, "componentFramework": "glass‑easel", "sitemapLocation": "sitemap.json", "lazyCodeLoading": "requiredComponents" }2. index.wxml 页面结构
使用image组件展示脸谱,绑定点击 tap 事件;增加视图展示累计变脸次数。
<navigation-bar title="变脸游戏" back="{{false}}" color="black" background="#FFF"></navigation-bar> <scroll-view class="scrollarea" scroll-y type="list"> <view class="box"> <view class="title">wx.onAccelerometerChange示例</view> <image src="{{faces[index]}}" mode="widthFix" bind:tap="changeFace" /> <view class="count-text">累计变脸总次数:{{totalCount}}</view> </view> </scroll-view>3. index.wxss 页面样式
/**index.wxss**/ page { height: 100vh; display: flex; flex-direction: column; } .scrollarea { flex: 1; overflow-y: hidden; } image { margin: 20rpx; } .count-text { font-size:40rpx; color:rebeccapurple; text-align:center; margin-top:30rpx; font-weight:bold; }4. app.wxss 全局公共样式
.title { padding: 20rpx; border: 2rpx solid purple; font-size: 40rpx; font-weight: bolder; text-align: center; margin-bottom: 30rpx; color: rebeccapurple; }5. index.js 业务逻辑核心
- data 中定义脸谱图片数组、当前图片索引、变脸计数字段;
- 封装工具函数生成随机索引,用于随机切换脸谱;
- changeFace 方法:切换脸谱同时完成计数累加;
- onShow 生命周期中注册加速计监听,判断三轴加速度阈值识别摇晃动作。
Page({ data: { index: 0, totalCount: 0, faces: [ '/images/1.png', '/images/2.png', '/images/3.png', '/images/4.png', '/images/5.png', '/images/6.png', '/images/7.png', '/images/8.png', '/images/9.png', '/images/10.png', '/images/11.png', '/images/12.png', '/images/13.png', '/images/14.png' ] }, // 生成 [0,n) 的随机索引 createRandomIndex(n) { return Math.floor(Math.random() * n) }, // 切换脸谱,同时累加变脸次数 changeFace() { this.setData({ index: this.createRandomIndex(this.data.faces.length), totalCount: this.data.totalCount + 1 }) }, onShow() { // 注册加速计变化监听 wx.onAccelerometerChange((res) => { // 判断三轴加速度阈值,识别摇晃动作 if (res.x > 0.5 || res.y > 0.5 || res.z > 0.5) { this.changeFace() wx.showToast({ title: '摇一摇成功', icon: 'success', duration: 5000 }) } }) } })关键技术点解析
1、随机索引生成
Math.random()生成[0,1)浮点数,乘以数组长度 n,再通过Math.floor()向下取整,得到 0 到 n‑1 之间的合法数组下标,实现随机选取脸谱。
2、加速计摇晃判断逻辑
wx.onAccelerometerChange会高频持续回调传感器数据,当手机产生摇晃动作,x/y/z 轴加速度会超过设定阈值 0.5,此时判定为摇晃,执行变脸逻辑。
实际项目中可以增加防抖处理,避免短时间内多次摇晃重复触发变脸。
3、数据驱动视图
小程序采用 MVVM 模式,通过this.setData()修改index控制图片渲染,修改totalCount更新页面计数,视图自动响应数据变化。点击图片、摇晃手机两套入口共用同一个changeFace函数,保证计数逻辑统一。
踩坑与优化建议
- 传感器仅真机有效:微信开发者工具模拟器无法模拟加速计,摇一摇效果必须使用真机调试预览。
- 监听事件释放:当前示例中
onShow注册监听,多次打开页面会重复绑定监听事件。正式项目建议在onHide中调用wx.offAccelerometerChange()取消监听,防止事件多次触发。 - 防抖优化:加速计回调频率很高,快速摇晃会连续触发变脸,可以增加时间戳防抖,限制最短触发间隔。
- 图片资源:图片较多时建议压缩图片体积,减少小程序包体积。
拓展方向
基于加速计 API 还可以拓展更多玩法:
- 增加分数逻辑,记录最高变脸分数;
- 增加动画效果,变脸时添加过渡动画;
- 结合本地存储,把累计次数持久化,退出小程序再次打开不会清零。
总结
wx.onAccelerometerChange是小程序设备能力中非常典型的传感器 API,它把手机硬件能力开放给前端,打破了单纯点击交互的局限。本案例把传感器事件、页面点击事件封装到同一个业务方法,实现了两套交互入口,同时利用小程序的数据绑定完成状态展示。对于体感小游戏、摇一摇营销类场景,这套开发思路具备很好的参考价值。