```<!DOCTYPE html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta content="always" name="referrer">
<meta name="theme-color" content="#2932e1">
<title>RCP For A320NG</title>
</head>
<body>
<style>
.shu {
width: 2px;
font-size: 15px;
word-wrap: break-word;
}
@font-face{
font-family: digital-display;
src: url('digital-display.ttf'),
url('digital-display.eot'); /* IE9+ */
}
.Digits{
position:absolute;
top:120px;left:10px;
height:60px;width:230px;
line-height:60px;
color:white;
font-size:70px;font-family:digital-display;
display:block; float:left;
text-align:right;
}
.to_top {
width: 0;
height: 0;
border-bottom: 30px solid white;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
.top{
width: 0;
height: 0;
border-bottom: 30px solid white;
border-left: 20px solid transparent ;
border-right: 20px solid transparent ;
}
</style>
<div id="DME1" class = "Digits" style="">1.300</div>
<div id="DME2" class = "Digits" style="left:260px;">----</div>
<div id="asd"style="position: absolute; top:600px;left:200px;font-family: Microsoft YaHei;letter-spacing:5px;color:white;">ADF</div>
<div id="asd1"style="position: absolute; top:600px;left:350px;font-family: Microsoft YaHei;letter-spacing:5px;color:white;">ADF</div>
<div id="asd2"class="shu" style="position: absolute; left:80px;top:470px;font-family: Microsoft YaHei;color:white;">VOR</div>
<div id="asd3"class="shu" style="position: absolute; left:480px;top:470px;font-family: Microsoft YaHei;color:white;">VOR</div>
<div id="mat"class="to_top" style="position: absolute; left:60px;top:570px;color:white;"></div>
<div id="mat2"style="position: absolute; width:10px;height:10px;border:1px solid white;left:75px;top:600px;background:white;"></div>
<div id="mat3"style="position: absolute; width:10px;height:10px;border:1px solid white;left:75px;top:615px;background:white;"></div>
<div id="mat4"style="position: absolute; width:10px;height:10px;border:1px solid white;left:75px;top:630px;background:white;"></div>
<div id="ExchangeBtn" class="button" style="position:absolute; left:470px;top:600px;font-size:90px;font-weight:bold;font-family: Microsoft YaHei;line-height:15px;color:white;">⇧</div>
<canvas id="solar" style="border:0px solid;left:10px;top:10px;position:absolute;z-index:-1;width:560px;height:670px;scale:0.5;"></canvas>
<div id="Message" ></div>
<div id="Message2" ></div>
</body>
<script>
init();
let pi = Math.PI;
let DialCenterX = 275;
let DialCenterY = 400;
let DialRadius = 180;
let CompassHeading = 0;
let Latitude=0;
let Longitude=0;
let DME1_lat= 39.10960;
let DME1_long= 117.35343;
let DME1Distance = 0;
let hand1=30; //VOR方位角
let hand2=0;
let gap_dial_hand = 60;
let hand_length = DialRadius - gap_dial_hand;
window.addEventListener("deviceorientation", findNorth);
var Message =document.getElementById("Message");
var browser={
versions:function(){
var u = navigator.userAgent, app = navigator.appVersion;
return {
trident: u.indexOf('Trident') > -1, //IE内核
presto: u.indexOf('Presto') > -1, //opera内核
webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1,//火狐内核
mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, //android终端
iPhone: u.indexOf('iPhone') > -1 , //是否为iPhone或者QQHD浏览器
iPad: u.indexOf('iPad') > -1, //是否iPad
webApp: u.indexOf('Safari') == -1, //是否web应该程序,没有头部与底部
weixin: u.indexOf('MicroMessenger') > -1, //是否微信 (2015-01-22新增)
qq: u.match(/\sQQ/i) == " qq" //是否QQ
};
}(),
language:(navigator.browserLanguage || navigator.language).toLowerCase()
}
function draw(ctx,DialDeg,HandDeg1,HandDeg2){
//drawDial(ctx,DialDeg); //绘制表盘
//drawAllHands(ctx,HandDeg1,HandDeg2); //绘制时分秒针
requestAnimationFrame(function step(){
getLocation();
DME1Distance = getDisance(Latitude, Longitude, DME1_lat, DME1_long);
if(DME1Distance>722094) DME1Distance="----";
document.getElementById("DME1").innerHTML = DME1Distance;
drawDial(ctx,CompassHeading); //绘制表盘
drawAllHands(ctx,hand1,hand2); //绘制时分秒针
requestAnimationFrame(step);
});
}
function toRad(d) { return d * Math.PI / 180; }
function getDisance(lat1, lng1, lat2, lng2) { //lat为纬度, lng为经度, 一定不要弄错
var dis = 0;
var radLat1 = toRad(lat1);
var radLat2 = toRad(lat2);
var deltaLat = radLat1 - radLat2;
var deltaLng = toRad(lng1) - toRad(lng2);
var dis = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(deltaLat / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(deltaLng / 2), 2)));
dis = dis * 6378137;
dis = dis ;///1852 ;//转为海里
return dis.toFixed(1);
}
function getLocation()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(showPosition);
}
else{
Message.innerHTML="Geolocation is not supported by this browser.";
}
}
function showPosition(position)
{
Message.innerHTML="Latitude: " + position.coords.latitude + "<br />Longitude: " + position.coords.longitude +"<br/>accuracy:"+ position.coords.accuracy;
Latitude = position.coords.latitude; Longitude = position.coords.longitude;
}
function findNorth(evt) {
if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
CompassHeading = 360-evt.webkitCompassHeading.toFixed(0);
//window.location.href ="iPhone.html";
} else if (/(Android)/i.test(navigator.userAgent)) {
//alert(navigator.userAgent);
CompassHeading = evt.alpha -90;
document.getElementById("Message2").innerHTML = "您的手机需要校准指南针,请将手机指向正北后刷新页面。";
} else {
}
}
function init(){
let canvas = document.querySelector("#solar");
canvas.width = 560;
canvas.height = 670;
let ctx = canvas.getContext("2d");
drawOutline(ctx);
//strokeRoundRect(ctx, 10, 10, 100, 50, 10);
fillRoundRect(ctx, 40, 95, 216, 124, 30, 'rgba(99,116,122,1)');
fillRoundRect(ctx, 50, 105, 192, 68, 15, 'rgba(0,0,0,1)');
fillRoundRect(ctx, 295, 95, 216, 124, 30, 'rgba(99,116,122,1)');
fillRoundRect(ctx, 305, 105, 192, 68, 15, 'rgba(0,0,0,1)');
//fillRoundRect(ctx, 50, 50, 450, 600, 20, 'rgba(0,0,0,1)');
draw(ctx,30,30,60);
ctx.font = '20px "微软雅黑"';
ctx.fillStyle = "white";
ctx.fillText("DME-1", 110, 200);
ctx.font = '20px "微软雅黑"';
ctx.fillStyle = "white";
ctx.fillText("DME-2", 370, 200);
}
/*绘制时分秒针*/
function drawAllHands(ctx,HandDeg1,HandDeg2){
let time = new Date();
let s = time.getSeconds();
let m = time.getMinutes();
let h = time.getHours();
let pi = Math.PI;
let secondAngle = HandDeg1;//pi / 180 * 6 * s; //计算出来s针的弧度
let minuteAngle = pi / 180 * HandDeg1; //计算出来分针的弧度
let hourAngle = pi / 180 *HandDeg2;//pi / 180 * 30 * h + minuteAngle / 12; //计算出来时针的弧度
//
drawHand2(hand2 + CompassHeading, hand_length, 2, "white", ctx); //绘制时针,(角度,针长,粗细,颜色,canvas)
drawHand(hand1 + CompassHeading, hand_length, 2, "white", ctx); //绘制分针
//drawHand(secondAngle, 150, 2, "blue", ctx); //绘制秒针
}
/*绘制时针、或分针、或秒针
* 参数1:要绘制的针的角度
* 参数2:要绘制的针的长度
* 参数3:要绘制的针的宽度
* 参数4:要绘制的针的颜色
* 参数4:ctx
* */
function drawHand(angle, len, width, color, ctx){
ctx.save();
ctx.translate(DialCenterX, DialCenterY); //把坐标轴的远点平移到原来的中心
ctx.rotate(angle*pi/180 + pi/2); //旋转坐标轴。 x轴就是针的角度,rad
ctx.beginPath();
ctx.moveTo(-DialRadius + gap_dial_hand, 0);
//ctx.lineTo(len, 0); // 沿着x轴绘制针
ctx.font="18px microsoft yahei";
ctx.fillStyle="white";
var x = 4-DialRadius + gap_dial_hand; //指针起点x
ctx.fillText("◀",x,6);
for(i=x+5;i<len;){
ctx.moveTo(i, 0);
ctx.lineTo(i+10, 0);
i = i+20;
}
ctx.lineWidth = width;
ctx.strokeStyle = color;
ctx.lineCap = "round";
ctx.stroke();
ctx.closePath();
ctx.restore();
}
function drawHand2(angle, len, width, color, ctx){
ctx.save();
ctx.translate(DialCenterX, DialCenterY); //把坐标轴的远点平移到原来的中心
ctx.rotate(angle*pi/180 +pi/2); //旋转坐标轴。 x轴就是针的角度
ctx.beginPath();
ctx.moveTo(-DialRadius + gap_dial_hand, 0);
//ctx.lineTo(len, 0); // 沿着x轴绘制针
ctx.font="30px microsoft yahei";
ctx.fillStyle="white";
var x = -DialRadius + gap_dial_hand;
ctx.moveTo(x, 0);
ctx.lineTo(x+20, 10);ctx.lineTo(x+20, 5);
ctx.lineTo(len, 5);ctx.lineTo(len, -5);
ctx.lineTo(x+20, -5);ctx.lineTo(x+20, -10);
ctx.lineTo(x, 0);
ctx.lineWidth = width;
ctx.strokeStyle = color;
ctx.lineCap = "round";
ctx.stroke();
ctx.closePath();
ctx.restore();
}
/*绘制表盘*/
function drawDial(ctx,DialDeg){
let pi = Math.PI;
//ctx.clearRect(0, 0, 600, 600); //清除所有内容
ctx.save();
ctx.translate(DialCenterX, DialCenterY); //移动坐标原点到原来的中心
ctx.beginPath();
ctx.arc(0, 0, DialRadius, 0, 2*pi); //绘制圆周
//ctx.stroke();
//context.clip();
ctx.closePath();
// 填充颜色
ctx.fillStyle = "#202020";
ctx.fill();
for (let i = 0; i < 72; i++){//绘制刻度盘和数字
ctx.save();
ctx.rotate(pi/180*DialDeg + i * pi / 36); //旋转坐标轴。修改第一个参数可以旋转表盘
ctx.beginPath();
ctx.moveTo(DialRadius-37, 0);
if(i % 2 == 0){
ctx.lineTo(DialRadius-1, 0);
}else{
ctx.lineTo(DialRadius-16, 0);
}
ctx.lineWidth = i % 5 ? 4 : 4;
ctx.strokeStyle = i % 5 ? "white" : "white";
ctx.stroke();
ctx.closePath();
if(i % 6 == 0){
ctx.lineWidth = 1;
ctx.font="24px microsoft yahei";
//ctx.strokeText(i/3,0,-150);
//填充
ctx.fillStyle="white";
if(i>9) ctx.fillText(i*0.5,-12,60-DialRadius); //-150
else ctx.fillText(i*0.5,-6,60-DialRadius);
}
ctx.restore();
}
for (let i = 0; i < 8; i++){//绘制三角标
ctx.save();
ctx.rotate(pi/180*0 + i * pi / 4); //旋转坐标轴。修改第一个参数可以旋转表盘
ctx.font="24px microsoft yahei";
ctx.fillStyle="white";
ctx.fillText("▼",-12,-1*DialRadius);
ctx.restore();
}
ctx.restore();
}
VincentyConstants = {
a: 6378137,
b: 6356752.3142,
f: 1/298.257223563
}
/**
*Calculate destination point given start point lat/long (numeric degrees),
* bearing (numeric degrees) & distance (in m).
*/
function destinationVincenty(lonlat, brng, dist) {
var u = this;
var ct = u.VincentyConstants;
var a = ct.a, b = ct.b, f = ct.f;
var lon1 = lonlat.lon*1; //乘一(*1)是为了确保经纬度的数据类型为number
var lat1 = lonlat.lat*1;
var s = dist;
var alpha1 = u.rad(brng);
var sinAlpha1 = Math.sin(alpha1);
var cosAlpha1 = Math.cos(alpha1);
var tanU1 = (1-f) * Math.tan(u.rad(lat1));
var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
var sigma1 = Math.atan2(tanU1, cosAlpha1);
var sinAlpha = cosU1 * sinAlpha1;
var cosSqAlpha = 1 - sinAlpha*sinAlpha;
var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
var sigma = s / (b*A), sigmaP = 2*Math.PI;
while (Math.abs(sigma-sigmaP) > 1e-12) {
var cos2SigmaM = Math.cos(2*sigma1 + sigma);
var sinSigma = Math.sin(sigma);
var cosSigma = Math.cos(sigma);
var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
sigmaP = sigma;
sigma = s / (b*A) + deltaSigma;
}
var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
(1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
var L = lambda - (1-C) * f * sinAlpha *
(sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
var revAz = Math.atan2(sinAlpha, -tmp); // final bearing
var lon_destina = lon1*1+u.deg(L);
//var num_lon_dest = lon_destina*1;
//var lon_destina = new Number;
var lonlat_destination = {lon: lon_destina, lat: u.deg(lat2)};
return lonlat_destination;
}
/**
* 度换成弧度
* @param {Float} d 度
* @return {[Float} 弧度
*/
function rad(d)
{
return d * Math.PI / 180.0;
}
/**
* 弧度换成度
* @param {Float} x 弧度
* @return {Float} 度
*/
function deg(x) {
return x*180/Math.PI;
}
function drawOutline (ctx){
//开始路径
ctx.beginPath();
ctx.moveTo(70, 2);
ctx.lineTo(472, 2);
ctx.lineTo(550, 70);
ctx.lineTo(550, 597);
ctx.lineTo(472, 665);
ctx.lineTo(70, 665);
ctx.lineTo(2, 597);
ctx.lineTo(2, 70);
ctx.lineTo(70, 2);
ctx.closePath();
//路径闭合
//if(strokeStyle)
{
ctx.strokeStyle = "gray";
ctx.lineWidth = 1;
ctx.lineJoin = 'round';
ctx.stroke();
}
//if(fillStyle)
{
ctx.fillStyle = 'rgba(135,162,174,1)';
ctx.fill();
}
ctx.restore();
ctx.beginPath();
ctx.moveTo(40, 84);
ctx.lineTo(511, 84);
ctx.lineTo(511, 510);
ctx.lineTo(390, 642);
ctx.lineTo(169, 642);
ctx.lineTo(40, 510);
ctx.lineTo(40, 84);
ctx.closePath();
{
ctx.strokeStyle = "darkgray";
ctx.lineWidth = 1;
ctx.lineJoin = 'round';
ctx.stroke();
}
//if(fillStyle)
{
ctx.fillStyle = 'rgba(63,74,76,1)';
ctx.fill();
}
}
/**该方法用来绘制一个有填充色的圆角矩形
*@param cxt:canvas的上下文环境
*@param x:左上角x轴坐标
*@param y:左上角y轴坐标
*@param width:矩形的宽度
*@param height:矩形的高度
*@param radius:圆的半径
*@param fillColor:填充颜色
**/
function fillRoundRect(cxt, x, y, width, height, radius, /*optional*/ fillColor) {
//圆的直径必然要小于矩形的宽高
if (2 * radius > width || 2 * radius > height) { return false; }
cxt.save();
cxt.translate(x, y);
//绘制圆角矩形的各个边
drawRoundRectPath(cxt, width, height, radius);
cxt.fillStyle = fillColor || "#000"; //若是给定了值就用给定的值否则给予默认值
cxt.fill();
cxt.restore();
}
/**该方法用来绘制圆角矩形
*@param cxt:canvas的上下文环境
*@param x:左上角x轴坐标
*@param y:左上角y轴坐标
*@param width:矩形的宽度
*@param height:矩形的高度
*@param radius:圆的半径
*@param lineWidth:线条粗细
*@param strokeColor:线条颜色
**/
function strokeRoundRect(cxt, x, y, width, height, radius, /*optional*/ lineWidth, /*optional*/ strokeColor) {
//圆的直径必然要小于矩形的宽高
if (2 * radius > width || 2 * radius > height) { return false; }
cxt.save();
cxt.translate(x, y);
//绘制圆角矩形的各个边
drawRoundRectPath(cxt, width, height, radius);
cxt.lineWidth = lineWidth || 2; //若是给定了值就用给定的值否则给予默认值2
cxt.strokeStyle = strokeColor || "#000";
cxt.stroke();
cxt.restore();
}
function drawRoundRectPath(cxt, width, height, radius) {
cxt.beginPath(0);
//从右下角顺时针绘制,弧度从0到1/2PI
cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
//矩形下边线
cxt.lineTo(radius, height);
//左下角圆弧,弧度从1/2PI到PI
cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
//矩形左边线
cxt.lineTo(0, radius);
//左上角圆弧,弧度从PI到3/2PI
cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
//上边线
cxt.lineTo(width - radius, 0);
//右上角圆弧
cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
//右边线
cxt.lineTo(width, height - radius);
cxt.closePath();
}
</script>
</html>
如何用JavaScript实现方位角计算并且调用指针指示角度?
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
1条回答 默认 最新
关注 方位角(Azimuth)计算通常涉及到地理坐标(纬度和经度)以及一个参考点。对于方位角,我们计算的是从一个点到另一个点的方向。
计算两个地理坐标点之间的方位角:
function calculateAzimuth(lat1, lon1, lat2, lon2) { var dLat = toRadians(lat2-lat1); var dLon = toRadians(lon2-lon1); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * Math.sin(dLon/2) * Math.sin(dLon/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var R = 6371; // 地球半径,单位:公里 var d = R * c; // 两点之间的距离,单位:公里 var bearing = toDegrees(Math.atan2(Math.sin(dLon) * Math.cos(toRadians(lat2)), Math.cos(toRadians(lat1)) * Math.sin(toRadians(lat2)) - Math.sin(toRadians(lat1)) * Math.cos(toRadians(lat2)) * Math.cos(dLon))); if (bearing < 0) { bearing = 360 + bearing; } return bearing; } function toRadians(angle) { return angle * (Math.PI / 180); } function toDegrees(angle) { return angle * (180 / Math.PI); }
这个函数首先使用
toRadians
函数将角度转换为弧度,然后计算两点之间的距离和方位角。最后,使用toDegrees
函数将方位角从弧度转换回角度。接下来,你可以使用HTML和CSS来创建一个指针,并使用JavaScript来动态改变它的角度。以下是一个简单的例子:
HTML:
<div id="compass"> <div id="pointer"></div> </div>
CSS:
#compass { width: 200px; height: 200px; border: 1px solid black; border-radius: 50%; position: relative; overflow: hidden; } #pointer { width: 50px; height: 2px; background-color: black; position: absolute; top: 50%; left: 50%; transform-origin: left; transform: rotate(0deg); }
JavaScript:
var lat1 = 40.7128; // 起始点的纬度 var lon1 = -74.0060; // 起始点的经度 var lat2 = 34.0522; // 目标点的纬度 var lon2 = -118.2437; // 目标点的经度 var bearing = calculateAzimuth(lat1, lon1, lat2, lon2); var pointer = document.getElementById('pointer'); pointer.style.transform = 'rotate(' + bearing + 'deg)';
解决 无用评论 打赏 举报