aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--about.html35
-rw-r--r--audio/western-cover.m4abin0 -> 663447 bytes
-rw-r--r--dragons.js222
-rw-r--r--fonts/gameofthrones.ttfbin0 -> 28784 bytes
-rw-r--r--images/dragon-sizes.pngbin0 -> 374143 bytes
-rw-r--r--images/hat-texas.gifbin0 -> 161381 bytes
-rw-r--r--images/pink-panther-lasso-rope.gifbin0 -> 756199 bytes
-rw-r--r--images/pixel-lasso.jpegbin0 -> 23529 bytes
-rw-r--r--index.html160
-rw-r--r--style.css71
10 files changed, 488 insertions, 0 deletions
diff --git a/about.html b/about.html
new file mode 100644
index 0000000..c0536e2
--- /dev/null
+++ b/about.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Name my Dragon - About</title>
+ <link rel="stylesheet" href="style.css">
+</head>
+<body>
+ <center>
+ <h1>How it works</h1>
+ <div class="container">
+ <img class="flex" src="images/pixel-lasso.jpeg" max-width="50%" alt="Pixel art of a cowboy lassoing a dragon.">
+ <div class="flex flex2" style="max-width: 500px; color: unset;">
+ <p>
+ This site uses word similarity to score all dragon names in terms of its
+ "closeness" to the given name.
+ The dragon name that is the "closest" is the one selected as the user's dragon.</p>
+ <p>
+ It uses three popular techniques to calculate similarity scores -
+ these are the <a href="https://en.wikipedia.org/wiki/Levenshtein_distance" target="_blank">Levenshtein Distance</a>,
+ <a href="https://en.wikipedia.org/wiki/Cosine_similarity" target="_blank">Cosine Similarity</a>,
+ and <a href="https://en.wikipedia.org/wiki/Jaccard_index" target="_blank">Jaccard Similarity</a>.
+ </p>
+ <p>
+ The final result shown to the user uses cosine similarity only,
+ but top ranking dragons from each of the other two techniques are
+ also shown as alternatives.
+ </p>
+ </div>
+ </div>
+ <a href="index.html">Home</a>
+ </center>
+</body>
+</html>
diff --git a/audio/western-cover.m4a b/audio/western-cover.m4a
new file mode 100644
index 0000000..193a465
--- /dev/null
+++ b/audio/western-cover.m4a
Binary files differ
diff --git a/dragons.js b/dragons.js
new file mode 100644
index 0000000..5dd3ecb
--- /dev/null
+++ b/dragons.js
@@ -0,0 +1,222 @@
+const dragons = [
+ {
+ name: "Drogon",
+ description: "The largest and most aggressive of Daenerys' dragons. Black with red markings.",
+ rider: "Daenerys Targaryen",
+ imageId: "drogon",
+ size: "Very large, wingspan over 100 feet by adulthood",
+ primaryColor: "#000000",
+ secondaryColor: "#8B0000",
+ age: "About 7 years by end of series",
+ notableAbilities: ["Extremely hot flame", "Largest of Daenerys' dragons"]
+ },
+ {
+ name: "Rhaegal",
+ description: "Green-scaled with bronze accents. Named after Daenerys' brother Rhaegar.",
+ rider: "Daenerys Targaryen",
+ imageId: "rhaegal",
+ size: "Large, smaller than Drogon",
+ primaryColor: "#008000",
+ secondaryColor: "#704214",
+ age: "About 7 years by end of series",
+ notableAbilities: ["Agile flyer"]
+ },
+ {
+ name: "Viserion",
+ description: "Cream and gold colored. Named after Daenerys' brother Viserys.",
+ rider: "Daenerys Targaryen",
+ imageId: "viserion",
+ size: "Large, similar to Rhaegal",
+ primaryColor: "#FFFDD0",
+ secondaryColor: "#B8860B",
+ age: "About 7 years by end of series",
+ notableAbilities: ["Ice breath (after death and reanimation)"]
+ },
+ {
+ name: "Balerion the Black Dread",
+ description: "The largest known dragon, black-scaled.",
+ rider: "Aegon the Conqueror",
+ imageId: "balerion",
+ size: "Immense, could swallow a mammoth whole",
+ primaryColor: "#000000",
+ secondaryColor: "#2F4F4F",
+ age: "Approximately 200 years at time of death",
+ notableAbilities: ["Extremely hot flame", "Largest known dragon"]
+ },
+ {
+ name: "Vhagar",
+ description: "One of the three dragons used in the conquest of Westeros. Bronze with greenish-blue highlights.",
+ rider: "Visenya Targaryen",
+ imageId: "vhagar",
+ size: "Nearly as large as Balerion in old age",
+ primaryColor: "#CD7F32",
+ secondaryColor: "#2F4F4F",
+ age: "Approximately 181 years at time of death",
+ notableAbilities: ["One of the largest dragons", "Veteran of many battles"]
+ },
+ {
+ name: "Meraxes",
+ description: "Silver-scaled dragon ridden by Rhaenys Targaryen during the conquest.",
+ rider: "Rhaenys Targaryen",
+ imageId: "meraxes",
+ size: "Large, but smaller than Balerion",
+ primaryColor: "#C0C0C0",
+ secondaryColor: "#4B0082",
+ age: "Unknown",
+ notableAbilities: ["One of the dragons of Aegon's Conquest"]
+ },
+ {
+ name: "Caraxes",
+ description: "Known as the Blood Wyrm, red-scaled and fierce.",
+ rider: "Daemon Targaryen",
+ imageId: "caraxes",
+ size: "Large",
+ primaryColor: "#FF0000",
+ secondaryColor: "#8B0000",
+ age: "Unknown",
+ notableAbilities: ["Fierce in battle", "Formidable fighter"]
+ },
+ {
+ name: "Syrax",
+ description: "Yellow-scaled dragon ridden by Rhaenyra Targaryen.",
+ rider: "Rhaenyra Targaryen",
+ imageId: "syrax",
+ size: "Medium to large",
+ primaryColor: "#FFFF00",
+ secondaryColor: "#8B4513",
+ age: "Unknown",
+ notableAbilities: ["Swift flyer"]
+ },
+ {
+ name: "Meleys",
+ description: "Called the Red Queen, red-scaled with pink wings.",
+ rider: "Rhaenys Targaryen (the Queen Who Never Was)",
+ imageId: "meleys",
+ size: "Large",
+ primaryColor: "#FF0000",
+ secondaryColor: "#8B008B",
+ age: "Unknown",
+ notableAbilities: ["Swift and fearsome in battle"]
+ },
+ {
+ name: "Sunfyre",
+ description: "Described as the most beautiful dragon, with golden scales and pink wing membranes.",
+ rider: "Aegon II Targaryen",
+ imageId: "sunfyre",
+ size: "Medium to large",
+ primaryColor: "#FFD700",
+ secondaryColor: "#8B4513",
+ age: "Young adult during the Dance of the Dragons",
+ notableAbilities: ["Exceptional beauty", "Formidable in combat"]
+ },
+ {
+ name: "Vermithor",
+ description: "Bronze-scaled with tan wings. One of the larger dragons.",
+ rider: "King Jaehaerys I Targaryen",
+ imageId: "vermithor",
+ size: "Very large, third largest after Balerion and Vhagar",
+ primaryColor: "#CD7F32",
+ secondaryColor: "#8B4513",
+ age: "Approximately 100 years during the Dance of the Dragons",
+ notableAbilities: ["Extremely large and powerful"]
+ },
+ {
+ name: "Silverwing",
+ description: "Silver-scaled dragon, often paired with Vermithor.",
+ rider: "Queen Alysanne Targaryen",
+ imageId: "silverwing",
+ size: "Large",
+ primaryColor: "#C0C0C0",
+ secondaryColor: "#4B0082",
+ age: "Approximately 80-90 years during the Dance of the Dragons",
+ notableAbilities: ["Gentle temperament"]
+ },
+ {
+ name: "Dreamfyre",
+ description: "Slender, pale blue dragon with silver markings.",
+ rider: "Helaena Targaryen",
+ imageId: "dreamfyre",
+ size: "Medium",
+ primaryColor: "#ADD8E6",
+ secondaryColor: "#4169E1",
+ age: "Unknown",
+ notableAbilities: ["Agile flyer"]
+ },
+ {
+ name: "Tessarion",
+ description: "Called the Blue Queen, with dark blue scales and wings.",
+ rider: "Prince Daeron Targaryen",
+ imageId: "tessarion",
+ size: "Medium",
+ primaryColor: "#00008B",
+ secondaryColor: "#4B0082",
+ age: "Young during the Dance of the Dragons",
+ notableAbilities: ["Beautiful appearance"]
+ },
+ {
+ name: "Sheepstealer",
+ description: "An aggressive wild dragon with a taste for sheep, brown-scaled.",
+ rider: "Nettles",
+ imageId: "sheepstealer",
+ size: "Medium to large",
+ primaryColor: "#8B4513",
+ secondaryColor: "#2F4F4F",
+ age: "Unknown, but old",
+ notableAbilities: ["Wild and hard to tame", "Preference for eating sheep"]
+ },
+ {
+ name: "Seasmoke",
+ description: "Pale silver-grey dragon ridden by Laenor Velaryon.",
+ rider: "Laenor Velaryon",
+ imageId: "seasmoke",
+ size: "Medium",
+ primaryColor: "#C0C0C0",
+ secondaryColor: "#4682B4",
+ age: "Young adult during the Dance of the Dragons",
+ notableAbilities: ["Swift flyer"]
+ },
+ {
+ name: "Moondancer",
+ description: "Young, slender green dragon ridden by Baela Targaryen.",
+ rider: "Baela Targaryen",
+ imageId: "moondancer",
+ size: "Small to medium",
+ primaryColor: "#00FF00",
+ secondaryColor: "#006400",
+ age: "Very young during the Dance of the Dragons",
+ notableAbilities: ["Quick and nimble"]
+ },
+ {
+ name: "Vermax",
+ description: "Young dragon ridden by Jacaerys Velaryon during the Dance of the Dragons.",
+ rider: "Jacaerys Velaryon",
+ imageId: "vermax",
+ size: "Small to medium",
+ primaryColor: "#808080",
+ secondaryColor: "#2F4F4F",
+ age: "Young during the Dance of the Dragons",
+ notableAbilities: ["Unknown"]
+ },
+ {
+ name: "Arrax",
+ description: "Young dragon ridden by Lucerys Velaryon, described as swift.",
+ rider: "Lucerys Velaryon",
+ imageId: "arrax",
+ size: "Small",
+ primaryColor: "#808080",
+ secondaryColor: "#2F4F4F",
+ age: "Very young during the Dance of the Dragons",
+ notableAbilities: ["Swift flyer"]
+ },
+ {
+ name: "Tyraxes",
+ description: "Young dragon ridden by Joffrey Velaryon, not much is known about its appearance.",
+ rider: "Joffrey Velaryon",
+ imageId: "tyraxes",
+ size: "Small",
+ primaryColor: "#808080",
+ secondaryColor: "#2F4F4F",
+ age: "Very young during the Dance of the Dragons",
+ notableAbilities: ["Unknown"]
+ }
+];
diff --git a/fonts/gameofthrones.ttf b/fonts/gameofthrones.ttf
new file mode 100644
index 0000000..793ddff
--- /dev/null
+++ b/fonts/gameofthrones.ttf
Binary files differ
diff --git a/images/dragon-sizes.png b/images/dragon-sizes.png
new file mode 100644
index 0000000..064f1ff
--- /dev/null
+++ b/images/dragon-sizes.png
Binary files differ
diff --git a/images/hat-texas.gif b/images/hat-texas.gif
new file mode 100644
index 0000000..b97734c
--- /dev/null
+++ b/images/hat-texas.gif
Binary files differ
diff --git a/images/pink-panther-lasso-rope.gif b/images/pink-panther-lasso-rope.gif
new file mode 100644
index 0000000..538ff06
--- /dev/null
+++ b/images/pink-panther-lasso-rope.gif
Binary files differ
diff --git a/images/pixel-lasso.jpeg b/images/pixel-lasso.jpeg
new file mode 100644
index 0000000..c842197
--- /dev/null
+++ b/images/pixel-lasso.jpeg
Binary files differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..785667b
--- /dev/null
+++ b/index.html
@@ -0,0 +1,160 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Name my Dragon - Home</title>
+ <link rel="stylesheet" href="style.css">
+</head>
+<body>
+ <center>
+ <h1>Name my Dragon</h1>
+ <audio id="audio-player" loop>
+ <source src="audio/western-cover.m4a" type="audio/mp4">
+ Enable audio on your browser to get the best experience.
+ </audio>
+ <div class="alert">
+ Warning: The button below will play some sweet tunes!
+ Hit the "Stop music" button to stop it or just mute your device.
+ <span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
+ </div>
+ <div class="container">
+ <form id="nameForm" class="flex">
+ <label style="color: black;" for="firstName">Enter your first name:</label>
+ <input type="text" id="firstName" placeholder="bob" required>
+ <button type="submit">Name my Dragon</button>
+ </form>
+ <div class="flex">
+ <button id="stop-music" onclick="stopMusic();">Stop music</button>
+ </div>
+ </div>
+ <p>And your Dragon is...</p>
+ <div id="results" class="container">
+ <div id="dragonName" class="flex flex1"></div>
+ <div id="dragonStats" class="flex flex2"></div>
+ <div id="lasso" class="flex"></div>
+ </div>
+ <div id="alternatives"></div>
+ <div>
+ <p>See a comparison of all the dragons here:</p>
+ <img src="images/dragon-sizes.png" width="50%" alt="Comparison chart for all the dragons">
+ </div>
+ <a href="about.html">How it works</a>
+ </center>
+
+ <script type="text/javascript" src="dragons.js"></script>
+ <script>
+ const dragonNames = dragons.map(d => d.name);
+ console.log(dragonNames);
+
+ function levenshteinDistance(a, b) {
+ if (a.length === 0) return b.length;
+ if (b.length === 0) return a.length;
+
+ const matrix = [];
+
+ for (let i = 0; i <= b.length; i++) {
+ matrix[i] = [i];
+ }
+
+ for (let j = 0; j <= a.length; j++) {
+ matrix[0][j] = j;
+ }
+
+ for (let i = 1; i <= b.length; i++) {
+ for (let j = 1; j <= a.length; j++) {
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
+ matrix[i][j] = matrix[i - 1][j - 1];
+ } else {
+ matrix[i][j] = Math.min(
+ matrix[i - 1][j - 1] + 1,
+ matrix[i][j - 1] + 1,
+ matrix[i - 1][j] + 1
+ );
+ }
+ }
+ }
+
+ return matrix[b.length][a.length];
+ }
+
+ function cosineSimilarity(a, b) {
+ const aSet = new Set(a.toLowerCase());
+ const bSet = new Set(b.toLowerCase());
+ const intersection = new Set([...aSet].filter(x => bSet.has(x)));
+ return intersection.size / Math.sqrt(aSet.size * bSet.size);
+ }
+
+ function jaccardSimilarity(a, b) {
+ const aSet = new Set(a.toLowerCase());
+ const bSet = new Set(b.toLowerCase());
+ const intersection = new Set([...aSet].filter(x => bSet.has(x)));
+ const union = new Set([...aSet, ...bSet]);
+ return intersection.size / union.size;
+ }
+
+ function calculateSimilarities(name) {
+ const results = dragonNames.map(n => ({
+ name: n,
+ levenshtein: 1 - levenshteinDistance(name, n) / Math.max(name.length, n.length),
+ cosine: cosineSimilarity(name, n),
+ jaccard: jaccardSimilarity(name, n)
+ }));
+
+ return {
+ levenshtein: results.sort((a, b) => b.levenshtein - a.levenshtein).slice(0, 5),
+ cosine: results.sort((a, b) => b.cosine - a.cosine).slice(0, 5),
+ jaccard: results.sort((a, b) => b.jaccard - a.jaccard).slice(0, 5)
+ };
+ }
+
+ function getDragonObject(name) {
+ return dragons.filter(dragon => (dragon.name === name))[0];
+ }
+
+ function stopMusic() {
+ document.getElementById('audio-player').pause();
+ }
+
+ document.getElementById('nameForm').addEventListener('submit', function(e) {
+ e.preventDefault();
+ const name = document.getElementById('firstName').value;
+ const similarities = calculateSimilarities(name);
+ console.log(similarities);
+
+ const topChoice = similarities.cosine[0].name;
+ const topChoiceDragon = getDragonObject(topChoice);
+ const possibleAlternatives = new Set(
+ Array.prototype.concat(
+ similarities.jaccard.slice(0, 2).map(n => n.name),
+ similarities.levenshtein.slice(0, 2).map(n => n.name)
+ )
+ ).difference(
+ new Set([topChoice])
+ );
+
+ document.getElementById('dragonName').innerHTML =
+ `<p><span style="font-size:xx-large;" class="legible">${topChoice}</span></p>`;
+ document.getElementById('dragonName').style.backgroundColor = topChoiceDragon.primaryColor;
+
+ document.getElementById('dragonStats').innerHTML = `
+ <p>${topChoiceDragon.description}</p>
+ <p>
+ Size: ${topChoiceDragon.size}<br>
+ Age: ${topChoiceDragon.age}<br>
+ Abilities: ${topChoiceDragon.notableAbilities}<br>
+ </p>`;
+ document.getElementById('dragonStats').style.backgroundColor = topChoiceDragon.secondaryColor;
+
+ document.getElementById('lasso').innerHTML = `
+ <img src="images/hat-texas.gif" width="100%" alt="Cowboy lasso gif">`;
+ document.getElementById('lasso').style.backgroundColor = topChoiceDragon.primaryColor;
+
+ document.getElementById('alternatives').innerHTML =
+ `<p>Possible alternatives: <strong>${[...possibleAlternatives].join(', ')}</strong></p>`;
+
+ document.getElementById('audio-player').play();
+ });
+ </script>
+</body>
+</html>
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..9445212
--- /dev/null
+++ b/style.css
@@ -0,0 +1,71 @@
+@font-face {
+ font-family: 'GOTFont';
+ src: url('fonts/gameofthrones.ttf');
+}
+
+body {
+ background: #faf0e5
+}
+
+h1 {
+ font-family: 'GOTFont', Georgia, serif;
+}
+
+.legible {
+ color: white;
+ text-shadow:
+ 0.05em 0 black,
+ 0 0.05em black,
+ -0.05em 0 black,
+ 0 -0.05em black,
+ -0.05em -0.05em black,
+ -0.05em 0.05em black,
+ 0.05em -0.05em black,
+ 0.05em 0.05em black;
+}
+
+.container {
+ margin: 0;
+ padding: 0;
+ display: flex;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+.flex {
+ padding: 10px;
+ border: 3px solid #faf0e5;
+ color: white;
+ font-size: 14px;
+ text-align: center;
+ position: relative;
+ margin-bottom: 33px;
+}
+
+.flex1 {
+ min-width: 150px;
+}
+
+.flex2 {
+ font-size: large;
+ text-align: left;
+}
+
+.alert {
+ margin-bottom: 15px;
+ padding: 20px;
+ background-color: orange; /* Red */
+ color: white;
+}
+
+/* The close button */
+.closebtn {
+ margin-left: 15px;
+ color: white;
+ font-weight: bold;
+ float: right;
+ font-size: 22px;
+ line-height: 20px;
+ cursor: pointer;
+ transition: 0.3s;
+}