步骤一 思路
根据 deviceorientation alpha 属性, 找出角度
根据不同角度,旋转表盘.
绘制表盘.用canvas?
canvas 旋转.全部都重新画一遍.可以.
表盘样式,
一个圆圈,
有八个 刻度
以及 八个文字.
圆圈可以画,
我计算出角度,
按照 2 Math.PI / 8 也可以画出刻度.
问题, 能不能根据圆心坐标和角度,和半径
计算出坐标位置?
理论上可以.
r * sin
r * cos
即可.
那我们直接求 坐标.
半径相同,的位置, 我们画 刻度
半径稍微大的位置, 我们 写文字.
文字需要旋转.
文字需要旋转的角度是,与 传入的角度相同.
然后需要一个 指向屏幕上方的,固定指针.
问题,alpha 什么值时指北部?
我们假设 0 时,他是指向北方的.
步骤 2 画出静态图
// 先画图.
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
ctx.beginPath();
// 先画一个圈.
// 半径
var r = 80;
ctx.arc(250,250,r,0,2 * Math.PI,0);
ctx.strokeStyle = "firebrick";
ctx.lineWidth = 10;
ctx.stroke();
// 计算八个坐标.
// 先生成八个 角度.
var center = {
x : 250,
y : 250
}
var arr = getZuobiao(center,r);
// 根据坐标, 我们画出几个圆圈 当做刻度
arr.forEach((item) => {
ctx.beginPath();
ctx.arc(item.x,item.y,8,0,2 * Math.PI,0);
ctx.fillStyle = "#333333";
ctx.fill();
});
//
var textArr = getZuobiao(center,r + 40);
// 根据坐标, 我们画出 字.
textArr.forEach((item,index) => {
// 我们需要判断 哪个是哪个, 所以我们先把关键字,弄成一个数组.
var str = ["东南","正南","西南","正西","西北","正北","东北","正东"];
ctx.beginPath();
// 文字居中
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = "20px Arial";
ctx.fillText(str[index],item.x,item.y);
})
// 中间画一条直线
ctx.beginPath();
ctx.moveTo(center.x,center.y);
ctx.lineTo(center.x,center.y - r + 30);
ctx.strokeStyle = "#333333";
ctx.lineCap = "round";
ctx.lineWidth = 8;
ctx.stroke();
// 封装成函数, 因为我们还要起第二组 坐标
function getZuobiao (center,r) {
var step = Math.PI / 4;
var arr = [];
var reg = 0;
// 临时角度
var reg1 = reg;
for(var i = 0; i < 8;i++) {
var item = arr[i] = {};
reg1 += step;
item.x = center.x + r * Math.cos(reg1);
item.y = center.y + r * Math.sin(reg1);
// 改变角度
}
return arr;
}
// 静态图已经画出来.
步骤3 动起来.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewprot" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>指南针 + canvas</title>
<style type="text/css">
:root,body{
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
font-size: 20px;
}
#myCanvas{
display: block;
width: 100vw;
height: 100vw;
margin: auto;
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="500" height="500"></canvas>
<div id="show"></div>
<script type="text/javascript">
// 先画图.
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
function move (reg) {
// 每次作画时,我们清空画布
ctx.clearRect(0,0,500,500);
// 半径
var r = 80;
//圆心
var center = {
x : 250,
y : 250
}
// 角度
var reg = reg * (Math.PI / 180);
// 基本圈
ctx.beginPath();
ctx.arc(250,250,r,0,2 * Math.PI,0);
ctx.strokeStyle = "firebrick";
ctx.lineWidth = 10;
ctx.stroke();
// 根据坐标, 我们画出几个圆圈 当做刻度
// 画刻度.
var arr = getZuobiao(center,r,reg);
arr.forEach((item) => {
ctx.beginPath();
ctx.arc(item.x,item.y,8,0,2 * Math.PI,0);
ctx.fillStyle = "#333333";
ctx.fill();
});
// 画字.
var textArr = getZuobiao(center,r + 40,reg);
// 根据坐标, 我们画出 字.
textArr.forEach((item,index) => {
// 我们需要判断 哪个是哪个, 所以我们先把关键字,弄成一个数组.
var str = ["东南","正南","西南","正西","西北","正北","东北","正东"];
ctx.beginPath();
// 文字居中
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = "20px Arial";
ctx.fillText(str[index],item.x,item.y);
})
// 中间画一条直线
ctx.beginPath();
ctx.moveTo(center.x,center.y);
ctx.lineTo(center.x,center.y - r + 30);
ctx.strokeStyle = "#333333";
ctx.lineCap = "round";
ctx.lineWidth = 8;
ctx.stroke();
}
function getZuobiao (center,r,reg) {
var step = Math.PI / 4;
var arr = [];
// 临时角度
var reg1 = reg;
for(var i = 0; i < 8;i++) {
var item = arr[i] = {};
reg1 += step;
item.x = center.x + r * Math.cos(reg1);
item.y = center.y + r * Math.sin(reg1);
// 改变角度
}
return arr;
}
move(0);
// 传不同角度即可.
var lasttime = 0;
window.addEventListener("deviceorientation",function (e) {
if(new Date().getTime() - lasttime > 50){
var reg = e.alpha;
show.innerText = reg;
// 360 要转换成弧度.
move(reg);
lasttime = new Date().getTime();
}
})
</script>
</body>
</html>
问题 每次我重新进来的时候, 都指向正北? 什么鬼?
每次重新进来的时候, alpha值都是0 左右.
安卓苹果皆如此, 问题出在哪里?
很奇怪,我怀疑, alpha 值是否能指北, alpha值本身跟地球方向无关吧?
只是旋转角度吧?
先这样吧 回头再想.
网友评论