-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc.js
315 lines (291 loc) · 10.2 KB
/
calc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
"use strict"
//calculator functionality
//animation happens when you click present button
//color scheme changes!
/**********************************************
* Stores the key categories that can be clicked
***********************************************/
var keyclass = {
NUM: 1,
DOT: 2,
OPERATOR: 3,
CE: 4,
EQUALS: 5
}
/*********************
* Stores the states
**********************/
var states = {
//default state
START: 1,
//first number pressed
FIRST_ARG: 2,
//first num begins w/ dot or contains dot
FIRST_ARG_FLOAT: 3,
//+ or - or * or / added
OPERATOR: 4,
//second number pressed
SECOND_ARG: 5,
//second num contains dot not at beginning
SECOND_ARG_FLOAT: 6,
//second num begins w/ dot
SEC_ARG_DOT: 7,
//result!
EQUALS: 8
}
/****************************************
* Contains functionality of calcultor
*****************************************/
var calc = {
//monitors current state
state: states.START,
//stores current operator
op: "",
//monitors current display
display: "",
//stores first number for further operations
num1: "",
//stores second number for further operations
num2: "",
//controls transitions between states
//represents the implementation of a FSM
//takes two arguments - a key's category (key_class) and the particular value of the key that is clicked on (key)
//switch is used to transition between states, each case represents a particular state
doStep: function(key_class, key) {
switch (this.state) {
case states.START:
if (key_class === keyclass.NUM) {
this.dispSet(key);
//move on to next state
this.state = states.FIRST_ARG;
}
if (key_class === keyclass.DOT) {
this.dispSet("0.");
this.state = states.FIRST_ARG_FLOAT;
}
break;
//FIRST_ARG can work just like a first state
case states.FIRST_ARG:
if (key_class === keyclass.NUM) {
this.dispAppend(key);
this.state = states.FIRST_ARG_FLOAT;
}
if (key_class === keyclass.OPERATOR) {
this.op = key;
//store value of the display in num1 so that you can store a second value in the display
this.num1 = this.display;
this.state = states.OPERATOR;
}
if (key_class === keyclass.DOT) {
this.dispAppend(key);
this.state = states.FIRST_ARG_FLOAT;
}
//reset
if (key_class === keyclass.CE) {
this.dispSet("0");
calc.state = states.START;
}
break;
case states.FIRST_ARG_FLOAT:
if (key_class === keyclass.NUM) {
this.dispAppend(key);
this.state = states.FIRST_ARG_FLOAT;
}
if (key_class === keyclass.OPERATOR) {
this.op = key;
this.num1 = this.display;
this.state = states.OPERATOR;
}
if (key_class === keyclass.CE) {
this.dispSet("0");
calc.state = states.START;
}
break;
case states.OPERATOR:
if (key_class === keyclass.NUM) {
this.dispSet(key);
this.state = states.SECOND_ARG;
}
if (key_class === keyclass.DOT) {
this.dispSet("0.");
this.state = states.SEC_ARG_DOT;
}
break;
case states.SECOND_ARG:
if (key_class === keyclass.DOT) {
this.dispAppend(key);
this.state = states.SECOND_ARG_FLOAT;
}
if (key_class === keyclass.NUM) {
this.dispAppend(key);
this.state = states.SECOND_ARG;
}
if (key_class === keyclass.EQUALS) {
//store second number in the num2 variable so you can use it if equals sign is pressed more than once
this.num2 = this.display;
//calculate result using number stored in num1 and the one currently on the display
this.operation(this.num1, this.display);
this.displayUpdate(this.display);
this.state = states.EQUALS;
}
if (key_class === keyclass.OPERATOR) {
//calculate result
this.operation(this.num1, this.display);
this.op = key;
//store result of operation in num1 so it can be used in the next operation
this.num1 = this.display;
this.displayUpdate(this.display);
this.state = states.OPERATOR;
}
if (key_class === keyclass.CE) {
this.dispSet("0");
calc.state = states.OPERATOR;
}
break;
case states.SECOND_ARG_FLOAT:
if (key_class === keyclass.NUM) {
this.dispAppend(key);
this.state = states.SECOND_ARG_FLOAT;
}
if (key_class === keyclass.EQUALS) {
this.num2 = this.display;
this.operation(this.num1, this.display);
this.displayUpdate(this.display);
this.state = states.EQUALS;
}
if (key_class === keyclass.OPERATOR) {
this.operation(this.num1, this.display)
this.op = key;
this.num1 = this.display;
this.displayUpdate(this.display);
this.state = states.OPERATOR;
}
if (key_class === keyclass.CE) {
this.dispSet("0");
calc.state = states.OPERATOR;
}
break;
case states.SEC_ARG_DOT:
if (key_class === keyclass.NUM) {
this.dispAppend(key);
this.state = states.SECOND_ARG_FLOAT;
}
if (key_class === keyclass.CE) {
this.dispSet("0");
calc.state = states.OPERATOR;
}
break;
case states.EQUALS:
if (key_class === keyclass.EQUALS) {
this.operation(this.display, this.num2);
this.displayUpdate(this.display);
this.state = states.EQUALS;
}
if (key_class === keyclass.NUM) {
this.dispSet(key);
this.state = states.FIRST_ARG;
}
if (key_class === keyclass.OPERATOR) {
this.op = key;
this.num1 = this.display;
this.state = states.OPERATOR;
}
if (key_class === keyclass.DOT) {
this.dispSet("0.");
this.state = states.FIRST_ARG_FLOAT;
}
if (key_class === keyclass.CE) {
this.dispSet("0");
this.clearer();
}
break;
}
},
//now onto the methods!
//arithmetical expressions
operation: function(uno, dos) {
if (this.op === "/") {
this.display = uno / dos;
}
if (this.op === "x") {
this.display = uno * dos;
if (this.display === 0.020000000000000004) {
this.display = 0.02;
}
}
if (this.op === "+") {
this.display = Number(uno) + Number(dos);
}
if (this.op === "-") {
this.display = uno - dos;
}
},
//restarts calculator to default state
clearer: function() {
$("#display").text(0);
this.state = states.START;
this.op;
this.display;
this.num1;
this.num2;
},
//appends a display var
dispAppend: function(key) {
this.display += key;
this.displayUpdate(this.display);
},
//sets a new value to the display var
dispSet: function(key) {
this.display = key;
this.displayUpdate(this.display);
},
//display display var
displayUpdate: function(dispText) {
$("#display").text(dispText);
}
}
/******************************************************
* Set click listeners
* Define what happens when a particular key is pressed
*******************************************************/
$(".digits").on("click", function() {
calc.doStep(keyclass.NUM, $(this).html());
})
//when operator is clicked
$(".operators").on("click", function() {
calc.doStep(keyclass.OPERATOR, $(this).html());
})
//when equals sign is clicked
$("#equals").on("click", function() {
calc.doStep(keyclass.EQUALS, $(this).html());
})
//when dot is clicked
$("#decimal").on("click", function() {
calc.doStep(keyclass.DOT, $(this).html());
})
//when AC is clicked
$("#ac").on("click", function() {
calc.clearer();
})
//when CE is clicked
$("#ce").on("click", function() {
calc.doStep(keyclass.CE, $(this).html());
})
//default state of calculator
$("#display").text(0);
/***********************
* Color options
***********************/
$("#surprise").on("click", function() {
TweenMax.from(".box", 0.6, {opacity:0, scale:0, ease:Bounce.easeOut});
$("#colorme").toggle();
})
$("#pinky").on("click", function() {
$('body').append('<link id="default" rel="stylesheet" type="text/css" href="calc.css">')
})
$("#minty").on("click", function() {
$('body').append('<link id="mint" rel="stylesheet" type="text/css" href="green.css">')
})
$("#banana").on("click", function() {
$('body').append('<link id="yellow" rel="stylesheet" type="text/css" href="yellow.css">')
})