-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
259 lines (205 loc) Β· 9.07 KB
/
index.html
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Toucanny</title>
<style>
body {
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
width: 67%;
min-width: 384px;
margin-left: auto;
margin-right: auto;
color: #FFFFFF;
background-color: #0F172A;
}
.header-image {
width: 67%;
margin-left: auto;
margin-right: auto;
}
code {
font-family: 'Courier New', Courier, monospace;
color: #22C55E;
}
pre {
background-color: #1E293B;
border-radius: 8px;
overflow: auto;
padding: 16px;
}
a {
color: #0EA5E9;
}
a:visited {
color: #A855F7;
}
</style>
<style>
#demo {
padding: 32px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 16px;
background-color: #1e293b;
}
#api-input {
margin: 10px;
padding: 8px;
border: none;
border-radius: 8px;
background-color: #475569;
color: #ffffff;
}
#api-button {
padding: 8px;
border-radius: 8px;
background-color: #2ecc71;
color: #fff;
border: none;
cursor: pointer;
}
#output-image {
border-radius: 10%;
}
</style>
</head>
<body>
<p align="center">
<img class="header-image" src="/Toucanny Collage.png" alt="Project logo">
</p>
<h1 align="center">Toucanny</h1>
<div align="center">
<a href=""><img src="https://img.shields.io/badge/status-active-success.svg" alt="Status"></a>
<a href="https://github.com/Jeshwin/toucanny"><img
src="https://img.shields.io/github/commit-activity/t/Jeshwin/toucanny" alt="GitHub commit activity"></a>
<a href="https://github.com/Jeshwin/toucanny/stargazers"><img
src="https://img.shields.io/github/stars/Jeshwin/toucanny" alt="GitHub Repo stars"></a>
<a href="https://github.com/Jeshwin/toucanny/issues"><img
src="https://img.shields.io/github/issues/Jeshwin/toucanny" alt="GitHub issues"></a>
<a href="/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a>
</div>
<hr>
<p align="center">
Toucanny is a default username and avatar generation service
<br>
</p>
<h2>π Table of Contents</h2>
<ul>
<li><a href="#about">About</a></li>
<li><a href="#getting_started">Getting Started</a></li>
<li><a href="#installing">Installing</a></li>
<li><a href="#usage">Usage</a></li>
<li><a href="#deployment">Deployment</a></li>
<li><a href="#built_using">Built Using</a></li>
<li><a href="#references">References</a></li>
</ul>
<h2>π§ About <a name="about"></a></h2>
<p>While working on another one of my personal projects, <a href="https://www.codenest.space">CodeNest</a>, I wanted
a custom solution for generating a default username and avatar when a user signs up. Currently, we are using <a
href="https://auth0.com">Auth0</a> to handle user login and signup, and they already create a default avatar
using <a href="https://gravatar.com">Gravatar</a>, but I found it to be too boring, just the user's initials and
a background color π΄. So, I decided to make my own version, and add a username generator on top.</p>
<p>My objective for this project was to create a username and avatar generator that</p>
<ol>
<li>Generates a unique username and avatar for each new user (no duplicates)</li>
<li>Creates a memorable and interesting output, not just random characters and a bland image</li>
</ol>
<h2>π Getting Started <a name="getting_started"></a></h2>
<p>These instructions will get you a copy of the project up and running on your local machine for development and
testing purposes.</p>
<h3>Installing <a name="installing"></a></h3>
<p>Clone the repository</p>
<pre>
<code>git clone https://https://github.com/Jeshwin/toucanny.git</code>
</pre>
<p>Change to the <code>toucanny</code> directory</p>
<pre>
<code>cd toucanny</code>
</pre>
<p>Download the node dependencies</p>
<pre>
<code>npm install</code>
</pre>
<p>Run the development build</p>
<pre>
<code>npm run start</code>
</pre>
<p>The instance will be available on <code>localhost:3030</code></p>
<h2>π₯ Usage <a name="usage"></a></h2>
<p>There are two main routes that the Toucanny API uses.</p>
<h3><code>/username?userid={userid}</code></h3>
<p>This route takes in a required query parameter <code class="inline">userid</code> that is used to seed a random
number
generator. This way, every user gets a unique output, and it will always be the same output for the same user.
To make the username interesting, it is formatted as a random sentence with five words of the form
<code class="inline">adjective-noun-verb-adjective-noun</code>. Using a list of 64 adjectives, nouns, and verbs
each, this
leads to more than 1 billion usernames!
</p>
<p>The output is a json object of the form <code>{ username : "adjective-noun-verb-adjective-noun" }</code>.</p>
<h3><code>/avatar?userid={userid}&w={width}</code></h3>
<p>This route takes in a required query parameter <code class="inline">userid</code> that is used to seed a random
number
generator. It also takes an optional query parameter <code class="inline">w</code> that is used to define the
width and height
of the output image. The output image is a toucan made from 9 uniquely generated colors, 6 for the beak and 1
each for the body, background, and branch colors. This creates over 1 * 10<sup>65</sup> possible avatars! (It's
actually a bit less because the background color has fewer possibilities, but at this order of magnitude, it
doesn't really make a difference) Some example avatars generated using Toucanny are in the header image of this
README.</p>
<p>The output is an image with the specified width and height, or 420x420 px by default.</p>
<h2>π Deployment <a name="deployment"></a></h2>
<p>Toucanny is deployed using <a href="https://www.serverless.com/">Serverless</a> on <a
href="https://aws.amazon.com/">AWS</a> and is publicly available <a
href="https://api.toucanny.net">here</a>!</p>
<p>Here's a little demo of Toucanny in action!</p>
<div id="demo">
<div>
<input type="text" id="api-input" placeholder="Enter User ID">
<button id="api-button" onclick="callToucannyAPI()">Generate</button>
</div>
<h3>Username</h3>
<span id="output-username">friendly-eyes-paste-difficult-winds</span>
<h3>Avatar</h3>
<img id="output-image" src="https://api.toucanny.net/avatar?userid=Enter User ID&w=300" alt="Generated Avatar">
</div>
<h2>βοΈ Built Using <a name="built_using"></a></h2>
<ul>
<li><a href="https://expressjs.com/">Express.js</a> - Node.js API Framework</li>
<li><a href="https://www.npmjs.com/package/canvas">node-canvas</a> - Image Creation Library</li>
<li><a href="https://aws.amazon.com/">AWS</a> - Web Hosting</li>
<li><a href="https://www.serverless.com/">Serverless</a> - Serverless Deployment</li>
</ul>
<h2>π References <a name="references"></a></h2>
<ul>
<li><a href="https://dribbble.com/shots/3706929-Toucan">Toucan reference image</a></li>
<li>Inspired by <a href="https://www.peardeck.com/">Peardeck's</a> word-based code generator</li>
</ul>
<hr>
<p>
Β© Jeshwin Prince 2023.
<a href="https://www.github.com/Jeshwin">GitHub</a>
<a href="https://www.linkedin.com/in/jeshwinprince/">LinkedIn</a>
<a href="https://www.youtube.com/@math-a-magic9820">YouTube</a>
</p>
<script>
async function callToucannyAPI() {
const userId = document.getElementById('api-input').value;
const apiUrl = `https://api.toucanny.net/username?userid=${userId}`;
try {
const response = await fetch(apiUrl);
const data = await response.json();
// Display the output
document.getElementById('output-username').innerText = data.username;
document.getElementById('output-image').src = `https://api.toucanny.net/avatar?userid=${userId}&w=300`;
} catch (error) {
console.error('Error fetching data:', error);
}
}
</script>
</body>
</html>