Phi: add a scale to map
[fg:fgdata.git] / webgui / widgets / efis.js
1 define([
2       'knockout', 'text!./efis.svg', 'sprintf'
3 ], function(ko, htmlString, sprintf) {
4
5     function ViewModel(params) {
6         var self = this;
7         params = params||{}
8         
9         self.rateLimit = params.rateLimit || 100;
10
11         self.propertyMap = {
12             pitch : 'pitch',
13             roll : 'roll',
14             airspeed : 'airspeed',
15             altitude : 'altitude',
16             heading : 'heading',
17             slip : 'slip'
18         }
19
20         this.pitch = ko.observable(0).extend({
21             fgprop : self.propertyMap.pitch
22         }).extend({rateLimit: self.rateLimit });
23         this.roll = ko.observable(0).extend({
24             fgprop : self.propertyMap.roll
25         }).extend({rateLimit: self.rateLimit });
26         this.airspeed = ko.observable(0).extend({
27             fgprop : self.propertyMap.airspeed
28         }).extend({rateLimit: self.rateLimit });
29         this.altitude = ko.observable(0).extend({
30             fgprop : self.propertyMap.altitude
31         }).extend({rateLimit: self.rateLimit });
32         this.heading = ko.observable(0).extend({
33             fgprop : self.propertyMap.heading
34         }).extend({rateLimit: self.rateLimit });
35         
36         this.slip = ko.observable(0).extend({
37             fgprop : self.propertyMap.slip
38         }).extend({rateLimit: self.rateLimit });
39
40         this.horizonAnimation = ko.pureComputed(function() {
41             return "rotate(" + (-self.roll()) + " 512 384) translate(0 " + (self.pitch() * 20) + ")";
42         });
43
44         this.compassAnimation = ko.pureComputed(function() {
45             return "rotate(" + (-self.heading()) + " 512 1108.175)";
46         });
47
48         this.headingTextAnimation = ko.pureComputed(function() {
49             return sprintf.sprintf("%03d", self.heading());
50         });
51
52         this.asiTextAnimation = ko.pureComputed(function() {
53             return sprintf.sprintf("%3d", self.airspeed());
54         });
55
56         this.altimeterThousandsTextAnimation = ko.pureComputed(function() {
57             return sprintf.sprintf("%2d", self.altitude() / 1000);
58         });
59
60         this.altimeterHundretsTextAnimation = ko.pureComputed(function() {
61             return sprintf.sprintf("%03d", Math.abs(self.altitude() % 1000));
62         });
63
64         this.asiLadderLabelAnimation0 = ko.pureComputed(function() {
65             return self._getAsiLadderLabel(0);
66         });
67
68         this.asiLadderLabelAnimation1 = ko.pureComputed(function() {
69             return self._getAsiLadderLabel(1);
70         });
71
72         this.asiLadderLabelAnimation2 = ko.pureComputed(function() {
73             return self._getAsiLadderLabel(2);
74         });
75
76         this.asiLadderLabelAnimation3 = ko.pureComputed(function() {
77             return self._getAsiLadderLabel(3);
78         });
79
80         this.asiLadderLabelAnimation4 = ko.pureComputed(function() {
81             return self._getAsiLadderLabel(4);
82         });
83
84         this.altitudeLadderLabelAnimation0 = ko.pureComputed(function() {
85             return self._getAltitudeLadderLabel(0);
86         });
87
88         this.altitudeLadderLabelAnimation1 = ko.pureComputed(function() {
89             return self._getAltitudeLadderLabel(1);
90         });
91
92         this.altitudeLadderLabelAnimation2 = ko.pureComputed(function() {
93             return self._getAltitudeLadderLabel(2);
94         });
95
96         this.altitudeLadderLabelAnimation3 = ko.pureComputed(function() {
97             return self._getAltitudeLadderLabel(3);
98         });
99
100         this.altitudeLadderLabelAnimation4 = ko.pureComputed(function() {
101             return self._getAltitudeLadderLabel(4);
102         });
103
104         this.asiLadderLabelTransform = ko.pureComputed(function() {
105             var v = self.airspeed();
106             var y = v > 40 ? 38 * 8 + 152 * (v % 20) / 20 : 38 * v / 5;
107             return "translate(0 " + y + ")";
108         });
109
110         this.asiLadderTransform = ko.pureComputed(function() {
111             var v = self.airspeed();
112             var y = v > 40 ? 38 * 8 + 76 * (v % 10) / 10 : 38 * v / 5;
113             return "translate(0 " + y + ")";
114         });
115
116         this.altimeterLadderLabelTransform = ko.pureComputed(function() {
117             var v = self.altitude();
118             var y = 152 * (v % 200) / 200;
119             return "translate(0 " + y + ")";
120         });
121
122         this.altimeterLadderTransform = ko.pureComputed(function() {
123             var v = self.altitude();
124             var y = 76 * (v % 100) / 100;
125             return "translate(0 " + y + ")";
126         });
127
128         this.slipSkidTransform = ko.pureComputed(function() {
129             var v = self.slip() * -71.6125;
130             var x = v < -125 ? -125 : v > 125 ? 125 : v;
131             return "translate(" + x + " 0)";
132         });
133     }
134
135     ViewModel.prototype._getAsiLadderLabel = function(n) {
136         // draw labels every 20kt
137         var v = ((this.airspeed() / 20) | 0) * 20 - 40;
138         v = v < 0 ? 0 : v;
139         return sprintf.sprintf("%3d", v + n * 20)
140     }
141
142     ViewModel.prototype._getAltitudeLadderLabel = function(n) {
143         // draw labels every 200ft
144         var v = ((this.altitude() / 200) | 0) * 2 - 4;
145         return sprintf.sprintf("%2.1f", (v + n * 2) / 10);
146     }
147
148     // Return component definition
149     return {
150         viewModel : ViewModel,
151         template : htmlString
152     };
153 });