-
Notifications
You must be signed in to change notification settings - Fork 1
/
sketchDebugger.js
377 lines (300 loc) · 10.1 KB
/
sketchDebugger.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
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
// ####################
// ### INITIALIZERS ###
// ####################
/**
* Initializes the body at start.
*/
function init() {
// initialize the sketch collection and current index
sketch = [];
currentIndex = 0;
hasReadBefore = false;
// load files at file input
input = document.querySelector('input'); // access the <input> tag
input.addEventListener('change', loadFiles);
// get the canvas and its context
drawCanvas = document.getElementById('drawCanvas');
if (drawCanvas.getContext) {
drawContext = drawCanvas.getContext('2d');
}
// initially disable all other buttons (until data is finally loaded later)
disableInputTagStates(true);
}
/**
* Loads the file or files from the file open dialog window.
* @param {Object} event The loading files event.
*/
function loadFiles(event) {
// display loading message
document.getElementById("indexDisplay").innerHTML = "Waiting for sketches to be loaded...";
// initially disable the buttons
disableInputTagStates(true);
// get the files that were selected from the <input> tag's file open dialog window
var files = event.target.files;
// no file or files selected => quit function
if (files.length === 0) { alert("Failed to load files"); }
// initialze the repsective counts and flag
numReads = 0;
numFiles = files.length;
hasReadBefore = false;
// collet the sketches from the file or files
sketches = [];
for (var i = 0; i < files.length; i++) {
// get the current file
var file = files[i];
// set up the reader once it is ready to load the file
// note: closure is used to ensure that code is processed in-line
var reader = new FileReader();
reader.onload = ( function(file) {
return function(e) {
// get the curent local sketch
var text = e.target.result;
var localSketches = JSON.parse(text);
// add the sketch to the general collection of contents
for (var j = 0; j < localSketches.length; j++) {
var localSketch = localSketches[j];
sketches.push(localSketch);
}
// check if file-reading has been done before after lodaing the files
if (!hasReadBefore) {
// 1. get the first sketch
// 2. display the first sketch
// 3. indicate that file reading has been done
var first = localSketches[0];
displaySketch(first, strokeColor);
// enable the read-before flag
hasReadBefore = true;
}
//
numReads++;
if (numReads === numFiles) {
// enable all the buttons
if (sketches.length > 1) {
disableInputTagStates(false);
document.getElementById("backButton").disabled = true;;
}
else {
disableInputTagStates(true);
}
//
currentIndex = 0;
updateIndexDisplay(currentIndex, sketches.length - 1);
//
document.getElementById("sketchDataUploadsButton").value = "";
}
};
})(file);
// read the current file
reader.readAsText(file);
}
}
// ##########################
// ### CONTENT DISPLAYERS ###
// ##########################
/**
* Displays the sketch to the canvas.
* @param {Object} sketch - The input sketch.
* @param {String} color - The sketch's stroke colors.
*/
function displaySketch(sketch, color) {
//
var originalColor = this.strokeColor; // save original color
strokeColor = color; // change color
drawContext.fillStyle = color;
//
drawCanvas.width = sketch.canvasWidth;
drawCanvas.height = sketch.canvasHeight;
// iterate through each stroke
var strokes = sketch.strokes;
for (var i = 0; i < strokes.length; i++) {
var points = strokes[i].points;
// iterate through each point in the stroke
for (var j = 0; j < points.length - 1; j++) {
var currPoint = points[j];
var nextPoint = points[j + 1];
drawLineSegment(drawContext, currPoint.x, currPoint.y, nextPoint.x, nextPoint.y, strokeColor, strokeSize);
}
}
strokeColor = originalColor; // revert color
drawContext.fillStyle = strokeColor;
}
function displaySketchInContext(sketch, color, context) {
//
var originalColor = this.strokeColor; // save original color
strokeColor = color; // change color
context.fillStyle = color;
//
//drawCanvas.width = sketch.canvasWidth;
//drawCanvas.height = sketch.canvasHeight;
// iterate through each stroke
var strokes = sketch.strokes;
for (var i = 0; i < strokes.length; i++) {
var points = strokes[i].points;
// iterate through each point in the stroke
for (var j = 0; j < points.length - 1; j++) {
var currPoint = points[j];
var nextPoint = points[j + 1];
drawLineSegment(context, currPoint.x, currPoint.y, nextPoint.x, nextPoint.y, strokeColor, strokeSize);
}
}
strokeColor = originalColor; // revert color
context.fillStyle = strokeColor;
}
/**
* Draw a line segment between two points on the display canvas.
* @param {Object} context - The display context.
* @param {Number} x0 - The first x-coordinate.
* @param {Number} y0 - The first y-coordinate.
* @param {Number} x1 - The second x-coordinate.
* @param {Number} y1 - The second y-coordinate,
* @param {String} color - The stroke color.
* @param {Number} size - The stroke size.
*/
function drawLineSegment(context, x0, y0, x1, y1, color, size) {
// select a fill style
context.strokeStyle = color;
// draw a filled line
context.beginPath();
// move to the old previous position
context.moveTo(x0, y0);
// draw a line to the current touch/pointer position
context.lineTo(x1, y1);
// set the line thickness and draw the line
context.lineWidth = size;
context.stroke();
context.closePath();
}
/**
* Displays the current sketch index and the total number ofsketches.
* @param {Number} index - The current sketch index.
* @param {Number} total - The total number of sketches.
*/
function updateIndexDisplay(index, total) {
document.getElementById("indexDisplay").innerHTML = "" + index + " / " + total;
}
// ######################
// ### HELPER METHODS ###
// ######################
/**
* Displays the previous sketch.
* @param {Object} canvas - The display canvas.
* @param {Object} context - The display context.
*/
function backButton(canvas, context) {
// update the current index
--currentIndex;
updateIndexDisplay(currentIndex, sketches.length - 1);
// disable the previous button if at the first sketch
document.getElementById("nextButton").disabled = false;
if (currentIndex === 0) {
document.getElementById("backButton").disabled = true;
}
// clear the previous sketch and display the current sketch
clearCanvas(canvas, context);
displaySketch(sketches[currentIndex], strokeColor);
}
/**
* Displays the next sketch.
* @param {Object} canvas - The display canvas.
* @param {Object} context - The display context.
*/
function nextButton(canvas, context) {
// update the current index
++currentIndex;
updateIndexDisplay(currentIndex, sketches.length - 1);
// disable the next button if at the last sketch
document.getElementById("backButton").disabled = false;
if (currentIndex === sketches.length - 1) {
document.getElementById("nextButton").disabled = true;
}
// clear the previous sketch and display the current sketch
clearCanvas(canvas, context);
displaySketch(sketches[currentIndex], strokeColor);
}
/**
* Displays the inputted index's sketch.
* @param {Object} canvas - The display canvas.
* @param {Object} context - The display context.
*/
function jumpButton(canvas, context) {
// get the input target index from the corresponding text box
var targetIndex = document.getElementById("targetIndex").value;
// check for range
if (targetIndex < 0 || targetIndex > sketches.length) {
alert("ALERT: You have entered an index value that is out of range.");
return;
}
// check for valid parsing
targetIndex = Number.parseInt(targetIndex);
if (Number.isNaN(targetIndex) || typeof targetIndex !== 'number') {
alert("ALERT: You have entered a non-numerical index value.");
}
// 1. clear the canvas
// 2. set the inputted index as the current index
// 3. display the new current sketch to the canvas
// 4. update the displayed current index
clearCanvas(canvas, context);
currentIndex = targetIndex;
displaySketch(sketches[currentIndex], "black");
updateIndexDisplay(currentIndex, sketches.length - 1);
}
// ######################
// ### HELPER METHODS ###
// ######################
/**
* Determines whether the input file is of type JSON.
* @param {Object} file - The input file.
* @return {Boolean} Whether the input file is of type JSON.
*/
function validFileType(file) {
// get the file extension
var fileName = file.name;
if (fileName.length <= 5) { return false; }
var fileType = fileName.slice((fileName.length - 5) + 1, fileName.length);
// compare the extension to the JSON extension
if (fileType.toLowerCase() === "json") {
return true;
}
return false;
}
/**
* Handles the disable states of the interface buttons.
* @param {Boolean} disable - Indicates whether to disable the interface buttons or not.
*/
function disableInputTagStates(disable) {
// retrieve all buttons with the "buttonlook" class
var buttonElements = document.querySelectorAll(".buttonlook");
// individually set the disable state of each button
for (var i = 0; i < buttonElements.length; i++) {
buttonElements[i].disabled = disable;
}
}
/**
* Clears the canvas of strokes.
* @param {Object} canvas - The display canvas.
* @param {Object} context - The display context.
*/
function clearCanvas(canvas, context) {
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
}
// ##########
// # FIELDS #
// ##########
// Accesses the canvas and its information.
var drawCanvas;
var drawContext;
// Keeps track of the sketches and index of the currently-viewed sketch.
var sketches;
var currentIndex;
// Stores the stroke visual details.
var strokeSize = 3;
var strokeColor = "black";
// Flag for whether a file has been read yet after initial loading.
// If true, then the currently-read file is the first file being read.
// So get the first file's first sketch to load into display canvas.
var hasReadBefore;
// Keeps track of the number of file reads after loading and number of files.
// If the number of reads match the number of files, then the reading is done.
var numReads;
var numFiles;