initial commit
This commit is contained in:
commit
5fc1858e75
61
index.html
Normal file
61
index.html
Normal file
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>heonian web dictionary</title>
|
||||
<meta name="description" content="now with 50% less unix requirement">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="./main.css">
|
||||
<link rel="preload" href="./wordlist.json" as="fetch">
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
entry screen, centered {
|
||||
hisho
|
||||
[search box, has a button to click to toggle heonian IME]
|
||||
[show all words] [other resource links, idk link to google doc, heonian-conversation, github]
|
||||
}
|
||||
|
||||
click search box or show all words, screen animates search box and. title and all that to top of screen
|
||||
and. results appear n stuff,
|
||||
Vewy Cool Fancy Totally Not Waste Of Resources
|
||||
|
||||
RUBY TAGS HOLY SHIT
|
||||
um,
|
||||
results layout would kinda look like,,,
|
||||
|
||||
[words - 420 found / expressions - 69 found / wahtever else - ygettheidea] (click one to filter to just those)
|
||||
|
||||
word {
|
||||
word [word in latin, in ruby]
|
||||
[tags like. common word, slang, formal???, type, etc]
|
||||
[maybe formal and non-formal versions of word could be shown]
|
||||
[show inflections button (steal from jisho)]
|
||||
[play audio clip would also be cool....]
|
||||
|
||||
short english translation, followed by . long description/explanation of word
|
||||
maybe an example? usage?
|
||||
and. source/who made it/etc
|
||||
repeat for all meanings of word,
|
||||
}
|
||||
-->
|
||||
<header class="fullscreen">
|
||||
<span class="heonian"></span>
|
||||
<div id="search">
|
||||
<input type="text" placeholder="loading...">
|
||||
<button>
|
||||
H
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#">show all words</a> <a href="#">uh. something else</a>
|
||||
</div>
|
||||
<noscript>turn on js doofus</noscript>
|
||||
</header>
|
||||
<main>
|
||||
|
||||
</main>
|
||||
|
||||
<script src="./main.js"></script>
|
||||
</body>
|
||||
</html>
|
128
main.css
Normal file
128
main.css
Normal file
@ -0,0 +1,128 @@
|
||||
@font-face {
|
||||
font-family: "heonian";
|
||||
src: url("./font.otf");
|
||||
}
|
||||
|
||||
@keyframes clearly-cheating {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--font: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-h: "heonian", "Helvatica Neue", Helvetica, Arial, sans-serif;
|
||||
--nice-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||
--grey: rgb(226, 226, 226);
|
||||
--darkgrey: rgb(150, 150, 150);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: var(--font);
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgb(119, 205, 233);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.heonian {
|
||||
font-family: "heonian";
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
flex-flow: row wrap;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid var(--grey);
|
||||
}
|
||||
|
||||
header * {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
header #search {
|
||||
flex-grow: 1;
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
header #search button {
|
||||
all: unset;
|
||||
position: relative;
|
||||
left: -64px;
|
||||
top: -2px;
|
||||
width: 48px;
|
||||
text-align: center;
|
||||
height: 2rem;
|
||||
border-left: 1px solid var(--grey);
|
||||
}
|
||||
|
||||
header input {
|
||||
height: 2rem;
|
||||
font-size: 1.5rem;
|
||||
font-family: var(--font-h);
|
||||
padding: 4px;
|
||||
padding-right: calc(4px + 48px); /* space for heonian ime button */
|
||||
border: 1px solid var(--grey);
|
||||
border-radius: 4px;
|
||||
font-weight: 100;
|
||||
transition: border-color 0.3s;
|
||||
width: calc(100% - 52px - 24px);
|
||||
}
|
||||
|
||||
header input:focus {
|
||||
outline: none;
|
||||
border: 1px solid var(--darkgrey);
|
||||
}
|
||||
|
||||
header span.heonian {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
header.fullscreen {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
padding-bottom: 0px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
header.fullscreen span.heonian {
|
||||
font-size: 8rem;
|
||||
}
|
||||
|
||||
header.fullscreen #search {
|
||||
flex-grow: 0;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.header-animation {
|
||||
animation: clearly-cheating 1s ease-in-out;
|
||||
}
|
||||
|
||||
.header-animation-reverse {
|
||||
animation: clearly-cheating 1s ease-in-out reverse;
|
||||
}
|
118
main.js
Normal file
118
main.js
Normal file
@ -0,0 +1,118 @@
|
||||
let json = null;
|
||||
|
||||
let searchDictionary = {};
|
||||
|
||||
let header = null;
|
||||
let main = null;
|
||||
|
||||
function animateHeader(inout = false) {
|
||||
//todo: debounce this
|
||||
if (inout) {
|
||||
header.classList.add("header-animation-reverse");
|
||||
header.classList.remove("header-animation");
|
||||
setTimeout(() => {
|
||||
header.classList.add("fullscreen");
|
||||
},500);
|
||||
setTimeout(() => {
|
||||
header.classList.remove("header-animation-reverse");
|
||||
},1000);
|
||||
} else {
|
||||
header.classList.add("header-animation");
|
||||
header.classList.remove("header-animation-reverse");
|
||||
setTimeout(() => {
|
||||
header.classList.remove("fullscreen");
|
||||
},500);
|
||||
setTimeout(() => {
|
||||
header.classList.remove("header-animation");
|
||||
},1000);
|
||||
}
|
||||
//somewhere here we animate in the actual page too, but it.. doesnt exist yet
|
||||
}
|
||||
|
||||
// on space animateHeader()
|
||||
document.addEventListener("keydown", (e) => {
|
||||
//on / key press
|
||||
if (e.keyCode === 191) {
|
||||
e.preventDefault();
|
||||
header.querySelector("input").focus();
|
||||
}
|
||||
if (e.keyCode === 27) {
|
||||
//if search box not focused, and if we're not on the home page, go back to home page
|
||||
if (!header.querySelector("input").matches(":focus") && !header.classList.contains("fullscreen")) {
|
||||
e.preventDefault();
|
||||
animateHeader(true);
|
||||
}
|
||||
}
|
||||
if (e.keyCode === 13) {
|
||||
if (header.querySelector("input").matches(":focus")) {
|
||||
//search
|
||||
e.preventDefault();
|
||||
animateHeader(); //just in case
|
||||
doSearch();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function stripWord(word) {
|
||||
return word.replace(/[^a-zA-Z]/g, "");
|
||||
}
|
||||
|
||||
function loadDictionary() {
|
||||
fetch("/wordlist.json").then((e) => {
|
||||
if (e.status === 200) {
|
||||
//convert to json lmao
|
||||
e.json().then((e) => {
|
||||
json = e;
|
||||
|
||||
let values = Object.values(json);
|
||||
let keys = Object.keys(json);
|
||||
//prepare search. maybe async this if we're loading a specific word?
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
//create array
|
||||
searchDictionary[keys[i]] = [];
|
||||
|
||||
//add: base word (obvious, will always exist)
|
||||
searchDictionary[keys[i]].push(stripWord(keys[i]));
|
||||
//add: base word, but in heonian (todo, needs translator)
|
||||
|
||||
//add: translation (will always exist, i hope)
|
||||
searchDictionary[keys[i]].push(stripWord(values[i].translation));
|
||||
}
|
||||
|
||||
//ok, we're all ready!
|
||||
document.querySelector("header input").placeholder = "search";
|
||||
});
|
||||
} else {
|
||||
alert("yeah something went horribly wrong loading the wordlist so uh,,, certified ike moment");
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function search(word) {
|
||||
word = stripWord(word);
|
||||
let result = [];
|
||||
for (let key in searchDictionary) {
|
||||
for (let value in searchDictionary[key]) {
|
||||
if (searchDictionary[key][value].includes(word)) {
|
||||
result.push(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function doSearch() {
|
||||
let results = search(header.querySelector("input").value);
|
||||
if (results.length == 0) {
|
||||
main.innerHTML = "no results lulw";
|
||||
} else {
|
||||
//actually render results or w/e
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = () => {
|
||||
header = document.querySelector("header");
|
||||
main = document.querySelector("main");
|
||||
loadDictionary();
|
||||
}
|
15
wordlist.json
Normal file
15
wordlist.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"a.bae": {
|
||||
"translation": "young",
|
||||
"type": "modifier"
|
||||
},
|
||||
"a.e mo?": {
|
||||
"translation": "isn't it right?",
|
||||
"type": "expression"
|
||||
},
|
||||
"a.ga.ka": {
|
||||
"translation": "at, towards, for",
|
||||
"type": "marker",
|
||||
"notes": "also used like"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user