-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathui.js
168 lines (150 loc) · 5.76 KB
/
ui.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
/* File: ui.js
* Provides a method to track user interaction with the simulation and
* an interface to query the GUI at any time.
*/
// GUI constants
ACT_DENSITY_SRC = 0;
ACT_VELOCITY_SRC = 1;
MOUSE_LEFT = 0;
MOUSE_RIGHT = 1;
// UI Class: interfaces with the GUI.
function UI(canvas_id) {
this.canvas = document.getElementById(canvas_id);
this.ctx = this.canvas.getContext("2d");
this.width = this.canvas.width;
this.height = this.canvas.height;
// mouse action variables
this.mouse_dragging = false;
this.mouse_button = MOUSE_LEFT;
this.source = {x:0, y:0};
this.prev_src = {x:0, y:0};
this.drag_frames = 0;
// Getters:
this.getContext = function() {
return this.ctx;
}
// UI constants (call defaults() to change to default).
this.defaults = function() {
this.action_type = ACT_DENSITY_SRC;
this.show_grid = false;
this.show_vels = false;
this.show_stats = false;
this.visc = 0.1;
this.diff = 0.1;
this.dT = 0.01;
this.grid_cols = Math.floor(this.width / 15);
this.grid_rows = Math.floor(this.height / 15);
this.solver_iters = 20;
}
this.defaults();
// Sets the GUI parameters from internal values.
this.setUI = function() {
document.getElementById("show_grid").checked = this.show_grid;
document.getElementById("show_vels").checked = this.show_vels;
document.getElementById("show_stats").checked = this.show_stats;
document.getElementById("visc_val").value = this.visc;
document.getElementById("diff_val").value = this.diff;
document.getElementById("time_step").value = this.dT;
document.getElementById("grid_cols").value = this.grid_cols;
document.getElementById("grid_rows").value = this.grid_rows;
document.getElementById("solver_iters").value = this.solver_iters;
var dens_drag_box = document.getElementById("action_dens_drag");
var vel_drag_box = document.getElementById("action_vel_drag");
if(this.action_type == ACT_DENSITY_SRC) {
dens_drag_box.checked = true;
vel_drag_box.checked = false;
}
else {
dens_drag_box.checked = false;
vel_drag_box.checked = true;
}
}
this.setUI();
// Reads simulation parameters from the GUI.
this.readUI = function() {
this.show_grid = document.getElementById("show_grid").checked;
this.show_vels = document.getElementById("show_vels").checked;
this.show_stats = document.getElementById("show_stats").checked;
this.visc = parseFloat(document.getElementById("visc_val").value);
this.diff = parseFloat(document.getElementById("diff_val").value);
this.dT = parseFloat(document.getElementById("time_step").value);
this.grid_cols = parseInt(document.getElementById("grid_cols").value);
this.grid_rows = parseInt(document.getElementById("grid_rows").value);
this.solver_iters = parseInt(document.getElementById("solver_iters").value);
this.action_type = ACT_DENSITY_SRC;
if(document.getElementById("action_vel_drag").checked)
this.action_type = ACT_VELOCITY_SRC;
}
// Set up listeners for mouse events.
this.canvas.onmousedown = function(event) {
ui.mousedown(event, MOUSE_LEFT);
}
this.canvas.oncontextmenu = function(event) {
event.preventDefault();
ui.mousedown(event, MOUSE_RIGHT);
}
document.onmouseup = function(event) {
ui.mouseup(event);
}
this.canvas.onmousemove = function(event) {
ui.mousemove(event);
}
// Returns the x, y position on the canvas given the JavaScript event
// containing an absolute window position.
this.getPositionOnCanvas = function(event) {
var x = Math.floor(event.pageX - $(this.canvas).position().left);
var y = Math.floor(event.pageY - $(this.canvas).position().top);
return {x:x, y:y};
}
// When the user clicks down the mouse, dragging starts. Left and right
// buttons map to different actions.
this.mousedown = function(event, button) {
this.mouse_button = button;
this.mouse_dragging = true;
this.mousemove(event);
}
// When the user lifts the mouse, dragging ends.
this.mouseup = function(event) {
this.mouse_dragging = false;
this.drag_frames = 0;
}
// When the mouse moves, apply the appropriate source.
this.mousemove = function(event) {
if(!this.mouse_dragging)
return;
var source = this.getPositionOnCanvas(event);
if(this.drag_frames == 0)
this.prev_source = source;
else
this.prev_source = this.source;
this.source = source;
this.drag_frames++;
}
// If there is a source from user action, returns that x, y location.
// Otherwise, returns null if user is not doing anything.
this.getSource = function() {
if(this.mouse_dragging)
return this.source;
else
return null;
}
// Returns the mouse action type that the GUI is currently set to.
this.getActionType = function() {
if( (this.action_type == ACT_DENSITY_SRC
&& this.mouse_button == MOUSE_LEFT)
|| (this.action_type == ACT_VELOCITY_SRC
&& this.mouse_button == MOUSE_RIGHT)
)
return ACT_DENSITY_SRC;
else
return ACT_VELOCITY_SRC;
}
// Returns the X-velocity of the user's current mouse movement.
this.getDragX = function() {
return this.source.x - this.prev_source.x;
}
// Returns the Y-velocity of the user's current mouse movement.
this.getDragY = function() {
return this.source.y - this.prev_source.y;
}
}