-
Notifications
You must be signed in to change notification settings - Fork 1
/
ecco.js
133 lines (117 loc) · 3.9 KB
/
ecco.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
// Ecco the Dolphin Text Generator
// Written by Austin Bricker, 2017-2019
// Dynamically generates a .png image of entered text in the style of Ecco the Dolphin
// Letters of atypical width. All others not listed are 14 px wide
// These values are the letter sprite's width, plus a 2 px buffer
var unusualLetters = {"M": 24, "W": 24, "X": 18};
// Generates canvasj
var canvas = document.getElementById('eccoCanvas');
ctx = canvas.getContext('2d');
const max_rows = 18;
const x_margin = 16;
const y_margin = 26;
const bkg_width = 320;
const bkg_height = 240;
var img = new Image();
img.src = "./EccoBackground.png";
var text = document.getElementById('eccoText');
// Update text with every keystroke
text.addEventListener('keyup', drawEcco);
img.onload = function() {
drawEcco();
}
function drawEcco() {
// Remove error message on new key
document.getElementById("error").innerHTML = ""
// Clear, redraw background
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
// Separate text into lines of proper length
var text = document.getElementById('eccoText').value;
text = text.toUpperCase();
var lines = setLines(ctx, text, max_rows, x_margin, y_margin);
var valid_char = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!.,'?:-".split('');
var row_num = 0;
// Finds Y starting position
// Needs to be offset of midpoint by number of lines
var y_pos = 132 - (lines.length * Math.floor(y_margin / 2));
for (var row of lines){
// Finds X starting position
var x_pos = centerText(row);
for (var letter of row){
// If letter is a space
if (letter == " "){
x_pos += x_margin;
} else {
// Check if letter is one of the usable characters
// If not, put a message on the page
if (valid_char.indexOf(letter) >= 0) {
if (letter == "."){ // If letter is a period
letter = 'DOT';
} else if (letter == ':') { // If letter is a colon
letter = 'COLON';
} else if (letter == '?') { // If letter is a ?
letter = 'QUESTION';
}
// Convert letter into corresponding image, paste onto background
var latest_letter = new Image();
latest_letter.src = './EccoFont/' + letter + '.png';
if (latest_letter.complete) {
// If image has loaded, display it
// Previously used characters seem to go here, while newly used ones aren't ready
ctx.drawImage(latest_letter, x_pos, y_pos, latest_letter.width, latest_letter.height);
} else {
// If not, wait for it to load, then display it
// For some reason, they're shifted down and over, so include small adjustment
latest_letter.onload = function () {
ctx.drawImage(latest_letter, (x_pos - 2), (y_pos - y_margin), latest_letter.width, latest_letter.height);
};
}
// Shift over letter length plus small margin
x_pos += latest_letter.width + 2;
} else {
document.getElementById("error").innerHTML = "I'm sorry, but " + letter + " is not a valid character";
}
}
}
// Shift down a row
row_num++;
// console.log("Finished line");
y_pos += y_margin;
}
}
// Separates a phrase into lines that will fit on a screen's width
// "context" needs to be included in this function. I have no idea why.
function setLines(context, text, maxWidth) {
var words = text.split(" ");
var new_rows = [];
var new_line = words[0];
if (words.length == 1){
new_rows.push(new_line);
} else {
for (var i = 1; i < words.length; i++){
if (new_line.length + words[i].length < maxWidth){
new_line += " " + words[i];
} else {
new_rows.push(new_line);
new_line = words[i];
}
if (i == (words.length - 1)){
new_rows.push(new_line);
}
}
}
return new_rows;
}
// Calculates the initial x offset needed to center a row
function centerText(row) {
c = bkg_width / 2;
for (var letter of row) {
if (letter in unusualLetters) {
c -= Math.floor(unusualLetters[letter] / 2);
} else {
c -= x_margin / 2;
}
}
return c;
}