js 实现指南针
使用浏览器API获取设备朝向
浏览器提供了DeviceOrientationEvent API来检测设备方向变化。需要先检查API兼容性:
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', handleOrientation);
} else {
console.log('DeviceOrientation API not supported');
}
处理方向数据
方向事件会返回alpha(绕Z轴旋转)、beta(绕X轴旋转)和gamma(绕Y轴旋转)三个参数:

function handleOrientation(event) {
const compass = document.getElementById('compass');
const degree = event.alpha; // 0-360范围
compass.style.transform = `rotate(${-degree}deg)`;
}
创建可视化指南针
HTML结构需要包含指南针元素:
<div class="compass-container">
<div id="compass" class="compass-arrow"></div>
</div>
添加CSS样式实现指针效果:

.compass-container {
width: 200px;
height: 200px;
border-radius: 50%;
position: relative;
background: #f5f5f5;
}
.compass-arrow {
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 100px solid red;
position: absolute;
top: 50%;
left: 50%;
transform-origin: 50% 0%;
}
校准和误差处理
真实环境中需要考虑磁偏角修正:
const magneticDeclination = 5.8; // 示例值,需根据实际位置获取
function getTrueNorth(degree) {
return (degree + magneticDeclination) % 360;
}
权限请求
现代浏览器需要明确权限才能访问传感器:
async function requestPermission() {
try {
const permission = await navigator.permissions.query({
name: 'accelerometer'
});
if (permission.state === 'granted') {
initCompass();
}
} catch (err) {
console.error('Permission API error:', err);
}
}
完整实现示例
class Compass {
constructor(elementId) {
this.element = document.getElementById(elementId);
this.magneticDeclination = 0;
this.calibrationOffset = 0;
}
start() {
if (window.DeviceOrientationAbsoluteEvent) {
window.addEventListener('deviceorientationabsolute', this.update.bind(this));
} else if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', this.update.bind(this));
}
}
update(event) {
if (event.alpha !== null) {
const trueNorth = (event.alpha + this.magneticDeclination + this.calibrationOffset) % 360;
this.element.style.transform = `rotate(${-trueNorth}deg)`;
}
}
setDeclination(degrees) {
this.magneticDeclination = degrees;
}
calibrate(offset) {
this.calibrationOffset = offset;
}
}
注意事项
- 仅在HTTPS环境下或localhost可用
- iOS设备需要用户手势触发后才能获取数据
- 部分安卓设备可能不支持绝对方向检测
- 金属环境会影响传感器精度






