199 行
4.5 KiB
Plaintext
199 行
4.5 KiB
Plaintext
<template>
|
|
<!-- #ifdef APP -->
|
|
<scroll-view style="flex:1;padding: 6px;">
|
|
<!-- #endif -->
|
|
<text class="uni-h3">摇一摇</text>
|
|
<text>握住手机并快速摇晃,会调用加速计传感器,依据加速度变化检测动作,并弹出提示。</text>
|
|
|
|
<text class="log-text margin-v">{{ statusText }}</text>
|
|
<view class="uni-row margin-v">
|
|
<view class="metric-box">
|
|
<text>瞬时变化</text>
|
|
<text class="metric-value">{{ deltaText }}</text>
|
|
</view>
|
|
<view class="metric-box metric-box-space">
|
|
<text>触发次数</text>
|
|
<text class="metric-value">{{ shakeCountText }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="sensitivity-header">
|
|
<text>灵敏度</text>
|
|
<text class="sensitivity-value">{{ sensitivityLabel }}</text>
|
|
</view>
|
|
<slider class="sensitivity-slider" :value="sensitivityValue" :min="1" :max="5" :step="1"
|
|
@changing="onSensitivityChanging" @change="onSensitivityChange" />
|
|
<text class="sensitivity-tip">当前触发阈值:{{ thresholdText }},数值越低灵敏度越高,越容易触发。</text>
|
|
|
|
<!-- #ifdef APP -->
|
|
</scroll-view>
|
|
<!-- #endif -->
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
const statusText = ref('正在初始化传感器...')
|
|
const deltaText = ref('0.00')
|
|
const shakeCountText = ref('0')
|
|
const thresholdText = ref('1.35')
|
|
const sensitivityLabel = ref('中')
|
|
const sensitivityValue = ref(3)
|
|
|
|
const shakeCooldown = 1200
|
|
let lastMagnitude : number | null = null
|
|
let lastShakeTime = 0
|
|
let shakeCount = 0
|
|
let shakeThreshold = 1.35
|
|
|
|
function formatNumber(value : number) : string {
|
|
return value.toFixed(2)
|
|
}
|
|
|
|
function createMagnitude(x : number, y : number, z : number) : number {
|
|
return Math.sqrt(x * x + y * y + z * z)
|
|
}
|
|
|
|
function getSensitivityLabel(value : number) : string {
|
|
if (value <= 1) {
|
|
return '很低'
|
|
}
|
|
if (value == 2) {
|
|
return '较低'
|
|
}
|
|
if (value == 3) {
|
|
return '中'
|
|
}
|
|
if (value == 4) {
|
|
return '较高'
|
|
}
|
|
return '很高'
|
|
}
|
|
|
|
function syncSensitivity(value : number) : void {
|
|
sensitivityValue.value = value
|
|
shakeThreshold = 2.1 - value * 0.25
|
|
thresholdText.value = formatNumber(shakeThreshold)
|
|
sensitivityLabel.value = getSensitivityLabel(value)
|
|
}
|
|
|
|
function triggerShake(now : number) : void {
|
|
lastShakeTime = now
|
|
shakeCount = shakeCount + 1
|
|
shakeCountText.value = `${shakeCount}`
|
|
statusText.value = '检测成功,继续摇晃可再次触发'
|
|
uni.showToast({
|
|
title: '检测到摇一摇',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
|
|
const accelerometerListener : OnAccelerometerChangeCallback = (result : OnAccelerometerChangeCallbackResult) => {
|
|
const magnitude = createMagnitude(result.x, result.y, result.z)
|
|
if (lastMagnitude == null) {
|
|
lastMagnitude = magnitude
|
|
statusText.value = '请开始摇晃手机'
|
|
return
|
|
}
|
|
|
|
const delta = Math.abs(magnitude - (lastMagnitude as number))
|
|
deltaText.value = formatNumber(delta)
|
|
lastMagnitude = magnitude
|
|
|
|
const now = Date.now()
|
|
const passed = now - lastShakeTime
|
|
if (delta > shakeThreshold && passed > shakeCooldown) {
|
|
triggerShake(now)
|
|
}
|
|
}
|
|
|
|
function onSensitivityChanging(event : UniSliderChangeEvent) : void {
|
|
syncSensitivity(event.detail.value)
|
|
}
|
|
|
|
function onSensitivityChange(event : UniSliderChangeEvent) : void {
|
|
syncSensitivity(event.detail.value)
|
|
statusText.value = `当前灵敏度:${sensitivityLabel.value},请继续摇晃手机`
|
|
}
|
|
|
|
function startListen() : void {
|
|
uni.startAccelerometer({
|
|
interval: 'game',
|
|
success: () => {
|
|
statusText.value = '请开始摇晃手机'
|
|
},
|
|
fail: (error) => {
|
|
statusText.value = error.errMsg != null ? error.errMsg : '传感器启动失败'
|
|
}
|
|
})
|
|
}
|
|
|
|
function stopListen() : void {
|
|
uni.stopAccelerometer({
|
|
success: () => {
|
|
statusText.value = '已停止监听'
|
|
}
|
|
})
|
|
}
|
|
|
|
onReady(() => {
|
|
syncSensitivity(sensitivityValue.value)
|
|
uni.onAccelerometerChange(accelerometerListener)
|
|
startListen()
|
|
})
|
|
|
|
onShow(() => {
|
|
startListen()
|
|
})
|
|
|
|
onHide(() => {
|
|
stopListen()
|
|
})
|
|
|
|
onUnload(() => {
|
|
uni.offAccelerometerChange(accelerometerListener)
|
|
uni.stopAccelerometer()
|
|
})
|
|
</script>
|
|
|
|
<style>
|
|
.card-space {
|
|
margin: 5px;
|
|
}
|
|
|
|
.margin-v {
|
|
margin: 5px 0;
|
|
}
|
|
.log-text {
|
|
padding: 10px;
|
|
font-size: 14px;
|
|
border: 1px solid #ccc;
|
|
}
|
|
|
|
.metric-box {
|
|
flex: 1;
|
|
padding: 14px;
|
|
}
|
|
|
|
.metric-box-space {
|
|
margin-left: 10px;
|
|
}
|
|
|
|
.metric-value {
|
|
margin-top: 4px;
|
|
font-size: 30px;
|
|
}
|
|
|
|
.sensitivity-header {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.sensitivity-slider {
|
|
margin: 15px;
|
|
}
|
|
|
|
|
|
|
|
</style>
|