2017-03-13 02:27:24 +00:00
|
|
|
function ahrsRenderer(locationId) {
|
2015-10-14 21:35:41 +00:00
|
|
|
this.width = -1;
|
|
|
|
this.height = -1;
|
|
|
|
|
2017-03-13 02:27:24 +00:00
|
|
|
this.locationId = locationId;
|
|
|
|
this.canvas = document.getElementById(locationId);
|
|
|
|
this.resize();
|
|
|
|
|
|
|
|
// State variables
|
|
|
|
this.pitch = 0;
|
|
|
|
this.roll = 0;
|
|
|
|
this.heading = 0;
|
|
|
|
this.slipSkid = 0;
|
|
|
|
this.altitude = 0;
|
|
|
|
|
|
|
|
var ai = SVG(locationId).viewbox(-200, -200, 400, 400).group().addClass('ai'),
|
|
|
|
defs = ai.defs(),
|
|
|
|
earthClip = defs.rect(2400, 1200).x(-1200).y(0),
|
|
|
|
screenClip = defs.rect(400, 400).cx(0).cy(0);
|
|
|
|
this.pitchClip = defs.circle(320).cx(0).cy(0);
|
|
|
|
this.rollClip = defs.polygon('0,0 -200,-200 200,-200');
|
|
|
|
|
|
|
|
ai = ai.clipWith(screenClip).group();
|
|
|
|
|
|
|
|
// card is the earth+sky+pitch marks, moves with both pitch and roll.
|
|
|
|
this.card = ai.group();
|
|
|
|
this.card.circle(2400).cx(0).cy(0).addClass('sky'); // Sky
|
|
|
|
this.card.line(-1200, 0, 1200, 0).addClass('marks'); // Horizon line
|
|
|
|
this.card.circle(2400).cx(0).cy(0).addClass('earth').clipWith(earthClip); // Earth
|
|
|
|
|
|
|
|
var pitchMarks = this.card.group().addClass('marks').clipWith(this.pitchClip);
|
|
|
|
for (i = -1050; i <= 1050; i+=25) {
|
|
|
|
switch (i%100) {
|
|
|
|
case 0:
|
|
|
|
pitchMarks.line(-40, i, 40, i);
|
|
|
|
if (i!=0) {
|
|
|
|
pitchMarks.text(Math.abs(i) <= 900 ? Math.abs(i / 10).toString() : '80').x(-55).cy(i).addClass('markText');
|
|
|
|
pitchMarks.text(Math.abs(i) <= 900 ? Math.abs(i / 10).toString() : '80').x(+55).cy(i).addClass('markText');
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 50:
|
|
|
|
pitchMarks.line(-20, i, 20, i);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pitchMarks.line(-10, i, 10, i);
|
|
|
|
}
|
|
|
|
}
|
2017-01-06 04:00:35 +00:00
|
|
|
|
2017-03-13 02:27:24 +00:00
|
|
|
this.rollMarks = ai.group().addClass('marks').clipWith(this.rollClip);
|
|
|
|
for (i=-180; i<180; i+=10) {
|
|
|
|
if (i == 0) {
|
|
|
|
this.rollMarks.polygon('-10,-189 0,-175 10,-189').style('stroke-width', 0);
|
|
|
|
}
|
|
|
|
else if (i % 30 == 0) {
|
|
|
|
this.rollMarks.line(0, -175, 0, -195).rotate(i, 0, 0);
|
|
|
|
} else {
|
|
|
|
this.rollMarks.line(0, -175, 0, -189).rotate(i, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var rollPointer = ai.group().addClass('marks');
|
|
|
|
rollPointer.polygon('-10,-160 0,-174 10,-160').style('stroke-width', 0);
|
|
|
|
rollPointer.polygon('-10,+160 0,+174 10,+160').style('stroke-width', 0);
|
|
|
|
this.skidBar = ai.rect(20, 6).cx(0).y(-158).style('stroke-width', 0).addClass('marks');
|
|
|
|
|
|
|
|
var pointer = ai.group().addClass('pointer');
|
|
|
|
pointer.polygon('-150,-3 -78,-3 -75,0 -78,3 -150,3');
|
|
|
|
pointer.polygon('+150,-3 +78,-3 +75,0 +78,3 +150,3');
|
|
|
|
pointer.polygon('-75,25 0,0 75,25 25,25 25,20 -25,20 -25,25').addClass('pointerBG');
|
|
|
|
pointer.polygon('-75,25 0,0 75,25 0,10');
|
|
|
|
pointer.line(0, 0, 0, 10);
|
|
|
|
|
|
|
|
this.headingMarks = ai.group().addClass('marks');
|
|
|
|
for (i=-200; i<=920; i+=20) {
|
|
|
|
if (i%60==0) {
|
|
|
|
this.headingMarks.line(i, 175, i, 178);
|
|
|
|
this.headingMarks.text((i<0 ? (i/2+360) : i/2).toString()).x(i).cy(185).addClass('markText');
|
|
|
|
this.headingMarks.line(i, 192, i, 195);
|
|
|
|
} else {
|
|
|
|
this.headingMarks.line(i, 175, i, 195).style('stroke-width', 1);
|
|
|
|
}
|
|
|
|
}
|
2015-10-14 21:35:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ahrsRenderer.prototype = {
|
|
|
|
constructor: ahrsRenderer,
|
|
|
|
|
2017-03-13 02:27:24 +00:00
|
|
|
resize: function () {
|
|
|
|
var canvasWidth = this.canvas.parentElement.offsetWidth - 12;
|
|
|
|
|
|
|
|
if (canvasWidth !== this.width) {
|
|
|
|
this.width = canvasWidth;
|
|
|
|
this.height = canvasWidth * 0.5;
|
|
|
|
|
|
|
|
this.canvas.width = this.width;
|
|
|
|
this.canvas.height = this.height;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
update: function (pitch, roll, heading, slipSkid) {
|
|
|
|
this.pitch = pitch;
|
|
|
|
this.roll = roll;
|
|
|
|
this.heading = heading;
|
2017-03-08 23:11:05 +00:00
|
|
|
this.slipSkid = slipSkid;
|
2017-03-13 02:27:24 +00:00
|
|
|
|
|
|
|
this.pitchClip.translate(0, -10 * this.pitch);
|
|
|
|
this.rollClip.rotate(this.roll, 0, 0);
|
|
|
|
this.card.rotate(0, 0, 0).translate(0, 10 * this.pitch);
|
|
|
|
this.card.rotate(-this.roll, 0, -10 * this.pitch);
|
|
|
|
this.rollMarks.rotate(-this.roll, 0, 0);
|
|
|
|
this.headingMarks.translate(-2 * (this.heading % 360), 0);
|
|
|
|
this.skidBar.translate(-2 * this.slipSkid, 0);
|
2015-10-14 21:35:41 +00:00
|
|
|
}
|
2017-01-06 04:00:35 +00:00
|
|
|
};
|
2017-03-11 03:03:35 +00:00
|
|
|
|
|
|
|
function gMeterRenderer(locationId, plim, nlim) {
|
2017-03-11 14:20:26 +00:00
|
|
|
this.plim = plim;
|
|
|
|
this.nlim = nlim;
|
|
|
|
this.nticks = Math.floor(plim+1) - Math.floor(nlim) + 1;
|
|
|
|
|
|
|
|
this.width = -1;
|
|
|
|
this.height = -1;
|
|
|
|
|
|
|
|
this.locationId = locationId;
|
|
|
|
this.canvas = document.getElementById(locationId);
|
|
|
|
this.resize();
|
|
|
|
|
|
|
|
// State variables
|
|
|
|
this.g = 1;
|
|
|
|
this.min = 1;
|
|
|
|
this.max = 1;
|
|
|
|
|
|
|
|
// Draw the G Meter using the svg.js library
|
|
|
|
var gMeter = SVG(locationId).viewbox(-200, -200, 400, 400).group().addClass('gMeter');
|
|
|
|
|
|
|
|
var el, card = gMeter.group().addClass('card');
|
|
|
|
card.circle(390).cx(0).cy(0);
|
|
|
|
card.line(-150, 0, -190, 0)
|
|
|
|
.addClass('marks one');
|
|
|
|
for (i=Math.floor(nlim); i<=Math.floor(plim+1); i++) {
|
|
|
|
if (i%2 == 0) {
|
|
|
|
el = card.line(-150, 0, -190, 0).addClass('big');
|
|
|
|
card.text(i.toString())
|
|
|
|
.addClass('text')
|
|
|
|
.cx(-105).cy(0)
|
|
|
|
.transform({ rotation: (i-1)/this.nticks*360, cx: 0, cy: 0, relative: true })
|
|
|
|
.transform({ rotation: -(i-1)/this.nticks*360, relative: true });
|
|
|
|
} else {
|
|
|
|
el = card.line(-165, 0, -190, 0);
|
2017-03-11 03:03:35 +00:00
|
|
|
|
2017-03-11 14:20:26 +00:00
|
|
|
}
|
|
|
|
el.addClass('marks')
|
|
|
|
.rotate((i-1)/this.nticks*360, 0, 0);
|
2017-03-11 03:03:35 +00:00
|
|
|
}
|
2017-03-11 14:20:26 +00:00
|
|
|
card.line(-140, 0, -190, 0).addClass('marks limit').rotate((plim-1)/this.nticks*360, 0, 0);
|
|
|
|
card.line(-140, 0, -190, 0).addClass('marks limit').rotate((nlim-1)/this.nticks*360, 0, 0);
|
|
|
|
|
|
|
|
var ax = -Math.cos(2*Math.PI/this.nticks),
|
|
|
|
ay = -Math.sin(2*Math.PI/this.nticks);
|
|
|
|
card.path('M -170 0, A 170 170 0 0 1 ' + 170*ax + ' ' + 170*ay)
|
|
|
|
.rotate(-Math.floor(plim)/this.nticks*360, 0, 0)
|
|
|
|
.addClass('marks')
|
|
|
|
.style('fill-opacity', '0');
|
|
|
|
card.path('M -175 0, A 175 175 0 0 1 ' + 175*ax + ' ' + 175*ay)
|
|
|
|
.rotate(-Math.floor(plim)/this.nticks*360, 0, 0)
|
|
|
|
.addClass('marks')
|
|
|
|
.style('fill-opacity', '0');
|
|
|
|
|
2017-03-12 00:39:49 +00:00
|
|
|
this.min_el = gMeter.group().addClass('min');
|
|
|
|
this.min_el.polygon('0,0 -170,0 -160,-5 0,-5').addClass('pointer');
|
|
|
|
this.min_el.polygon('0,0 -170,0 -160,+5 0,+5').addClass('pointerBG');
|
2017-03-11 14:20:26 +00:00
|
|
|
|
|
|
|
this.pointer_el = gMeter.group().addClass('g');
|
|
|
|
this.pointer_el.polygon('0,0 -170,0 -150,-10 0,-10').addClass('pointer');
|
|
|
|
this.pointer_el.polygon('0,0 -170,0 -150,+10 0,+10').addClass('pointerBG');
|
|
|
|
|
|
|
|
this.max_el = gMeter.group().addClass('max');
|
|
|
|
this.max_el.polygon('0,0 -170,0 -150,-5 0,-5').addClass('pointer');
|
|
|
|
this.max_el.polygon('0,0 -170,0 -150,+5 0,+5').addClass('pointerBG');
|
|
|
|
|
|
|
|
gMeter.circle(40).cx(0).cy(0).addClass('center');
|
|
|
|
|
|
|
|
var reset = gMeter.group().cx(-165).cy(165).addClass('reset');
|
|
|
|
reset.circle(60).cx(0).cy(0).addClass('reset');
|
2017-03-13 02:27:24 +00:00
|
|
|
reset.text('RESET').cx(0).cy(0).addClass('text');
|
2017-03-11 14:20:26 +00:00
|
|
|
reset.on('click', function() {
|
|
|
|
reset.animate(200).rotate(20, 0, 0);
|
|
|
|
this.reset();
|
|
|
|
reset.animate(200).rotate(0, 0, 0);
|
|
|
|
}, this);
|
|
|
|
}
|
2017-03-11 03:03:35 +00:00
|
|
|
|
|
|
|
gMeterRenderer.prototype = {
|
|
|
|
constructor: gMeterRenderer,
|
|
|
|
|
|
|
|
resize: function () {
|
|
|
|
var canvasWidth = this.canvas.parentElement.offsetWidth - 12;
|
|
|
|
|
|
|
|
if (canvasWidth !== this.width) {
|
|
|
|
this.width = canvasWidth;
|
|
|
|
this.height = canvasWidth * 0.5;
|
|
|
|
|
|
|
|
this.canvas.width = this.width;
|
|
|
|
this.canvas.height = this.height;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
update: function (g) {
|
|
|
|
this.g = g;
|
|
|
|
this.max = g > this.max ? g : this.max;
|
|
|
|
this.min = g < this.min ? g : this.min;
|
|
|
|
|
|
|
|
this.pointer_el.animate(50).rotate((g-1)/this.nticks*360, 0, 0);
|
|
|
|
this.max_el.animate(50).rotate((this.max-1)/this.nticks*360, 0, 0);
|
|
|
|
this.min_el.animate(50).rotate((this.min-1)/this.nticks*360, 0, 0);
|
|
|
|
},
|
|
|
|
|
|
|
|
reset: function() {
|
2017-03-12 00:39:49 +00:00
|
|
|
this.g = 1;
|
|
|
|
this.max = 1;
|
|
|
|
this.min = 1;
|
2017-03-11 03:03:35 +00:00
|
|
|
}
|
|
|
|
};
|