From 7814a16c34ae493a4534361638934056c4d4df20 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 15 Nov 2025 17:17:52 -0300 Subject: [PATCH] all the js shit. yea all of it. gonna do some changes so commiting before i break shit --- assets/animations.css | 119 ++++++++++++++++++++++++ assets/base.css | 176 +++++++++++++++-------------------- assets/main.js | 212 +++++++++++++++++++++++++++++++++++++++++- assets/nojs.css | 0 index.html | 22 +++-- 5 files changed, 415 insertions(+), 114 deletions(-) create mode 100644 assets/animations.css create mode 100644 assets/nojs.css diff --git a/assets/animations.css b/assets/animations.css new file mode 100644 index 0000000..9fa030f --- /dev/null +++ b/assets/animations.css @@ -0,0 +1,119 @@ +/* loading animation */ + +@keyframes appear { + 0% { + visibility: visible; + display: block + } + 99% { + visibility: hidden; + display: none + } +} + +.nojs { + animation: 4.5s 1 reverse appear; + animation-delay: 4.5s; + animation-fill-mode: forwards; + visibility: hidden; + position: fixed +} + +.credit { + animation: 4.5s 1 reverse appear; + animation-delay: 4.5s; + animation-fill-mode: forwards; + visibility: hidden; + position: fixed +} + +.skip-animation { + animation: 4.5s 1 linear appear; + visibility: hidden; + position: fixed; + width: 100vw; + height: 100vh; + top: 0; + left: 0; +} + +.loading > p:first-child { + animation: 0.9s 1 linear appear; + animation-fill-mode: forwards; + animation-delay: 0.3s; + visibility: hidden; + position: fixed +} + +.loading > p:not(:first-child):not(:last-child) { + animation: 0.9s 1 linear appear; + animation-delay: 1.2s; + animation-fill-mode: forwards; + visibility: hidden; + position: fixed +} + +.loading > p:last-child { + animation: 0.9s 1 linear appear; + animation-delay: 2.1s; + animation-fill-mode: forwards; + visibility: hidden; + position: fixed +} + +@keyframes splash { + 0%, 100% { + visibility: visible; + color: var(--c-bg); + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } +} + +.splash { + animation-duration: 1.5s, 1.5s; + animation-iteration-count: 1, 1; + animation-timing-function: linear, linear; + animation-name: appear, splash; + animation-delay: 3s, 3s; + visibility: hidden; + position: fixed +} + +@keyframes splash-bg { + 0%, 100% { + background-color: var(--c-splash); + } +} + +html { + animation: 1.5s 1 linear splash-bg; + animation-delay: 3s +} + +@keyframes splash-fg { + 0%, 100% { + color: var(--c-bg); + } +} + +.skip-notice { + animation-duration: 4.5s, 1.5s; + animation-iteration-count: 1, 1; + animation-timing-function: linear, linear; + animation-name: appear, splash-fg; + animation-delay: 0s, 3s; + visibility: hidden; +} + +@keyframes js { + 0%, 100% { + visibility: hidden; + } +} + +.js { + animation: 4.5s 1 linear js; + position: fixed; +} \ No newline at end of file diff --git a/assets/base.css b/assets/base.css index 64e718b..2d95c98 100644 --- a/assets/base.css +++ b/assets/base.css @@ -2,7 +2,8 @@ html { background-color: var(--c-bg); - scrollbar-color: var(--c-border) transparent + scrollbar-color: var(--c-border) transparent; + scrollbar-width: thin; } /* text, links and lists :3 */ @@ -14,7 +15,7 @@ t { } -p { +p, d { font-family: "mono"; color: var(--c-fg); margin-top: 0; @@ -27,11 +28,15 @@ a { text-decoration: none; } -a:hover { +a:focus { color: var(--c-bg); background-color: var(--c-highlight); } +:is(a, d) + p { + display: none +} + ul { margin: 0 0 0 -16px; } @@ -42,7 +47,7 @@ li { /* lil text on the borders :3 */ -.title, .credit, .skip-notice { +.title, .title2, .credit, .skip-notice { height: 24px; background-color: var(--c-bg); color: var(--c-title); @@ -68,12 +73,13 @@ li { right: 8px; color: var(--c-fg); background-color: transparent; - font-weight: normal + font-weight: normal; + opacity: 0 } /* here are some @media rules to choose when to display ascii art */ -.ascii, .splash { +.ascii > div, .splash { font-family: "mono"; color: var(--c-fg); white-space: pre; @@ -89,13 +95,13 @@ li { @media screen and (min-width: 420px) and (max-width: 649px) { .ascii-2 { - display: block + display: block !important } } @media screen and (min-width: 650px) { .ascii-1 { - display: block; + display: block !important } } @@ -109,8 +115,7 @@ body > .nojs { overflow: hidden } - -main { +main, .js > div > div { overflow: hidden auto; width: 100%; height: 100%; @@ -118,111 +123,80 @@ main { box-sizing: border-box; } -/* loading animation */ - -@keyframes appear { - 0% { - visibility: visible; - display: block - } - 99% { - visibility: hidden; - display: none - } -} - -.nojs { - animation: 4.5s 1 reverse appear; - animation-delay: 4.5s; - animation-fill-mode: forwards; - visibility: hidden; - position: fixed -} - -.credit { - animation: 4.5s 1 reverse appear; - animation-delay: 4.5s; - animation-fill-mode: forwards; - visibility: hidden; - position: fixed -} - -.skip-animation { - animation: 4.5s 1 linear appear; +/* styling for the js mode! */ +.js { visibility: hidden; + border: 2px solid var(--c-border); + box-sizing: border-box; position: fixed; - width: 100vw; - height: 100vh; - top: 0; - left: 0; + width: calc(100vw - 16px); + height: calc(100vh - 16px); + top: 8px; + left: 8px } -.loading > p:first-child { - animation: 0.9s 1 linear appear; - animation-fill-mode: forwards; - animation-delay: 0.3s; - visibility: hidden; - position: fixed +.js > div { + box-sizing: border-box; + border: 2px solid var(--c-border); + overflow: hidden; + position: fixed; } -.loading > p:not(:first-child):not(:last-child) { - animation: 0.9s 1 linear appear; - animation-delay: 1.2s; - animation-fill-mode: forwards; - visibility: hidden; - position: fixed -} - -.loading > p:last-child { - animation: 0.9s 1 linear appear; - animation-delay: 2.1s; - animation-fill-mode: forwards; - visibility: hidden; - position: fixed -} - -@keyframes splash { - 0%, 100% { - visibility: visible; - color: var(--c-bg); - top: 50%; - left: 50%; - transform: translate(-50%, -50%); +@media screen and (min-aspect-ratio: 1/1) { + .js > div:first-child { + width: calc(50vw - 4px - 11px); + height: calc(100vh - 16px - 10px); + top: 13px; + left: 13px + } + .js > div:last-child { + width: calc(50vw - 4px - 11px); + height: calc(100vh - 16px - 10px); + top: 13px; + right: 13px + } + .title2 { + top: 0; + left: calc(50vw + 32px); } } -.splash { - animation-duration: 1.5s, 1.5s; - animation-iteration-count: 1, 1; - animation-timing-function: linear, linear; - animation-name: appear, splash; - animation-delay: 3s, 3s; - visibility: hidden; - position: fixed -} - -@keyframes splash-bg { - 0%, 100% { - background-color: var(--c-splash); +@media screen and (max-aspect-ratio: 1000/1001) { + .js > div:first-child { + width: calc(100vw - 16px - 10px); + height: calc(50vh - 4px - 11px); + top: 13px; + left: 13px + } + .js > div:last-child { + width: calc(100vw - 16px - 10px); + height: calc(50vh - 4px - 11px); + bottom: 13px; + left: 13px + } + .title2 { + top: calc(50vh - 12px); + left: 32px; } } -html { - animation: 1.5s 1 linear splash-bg; - animation-delay: 3s +.js > div:only-child { + width: calc(100vw - 16px - 10px); + height: calc(100vh - 16px - 10px); + top: 13px; + left: 13px } -@keyframes splash-fg { - 0%, 100% { - color: var(--c-bg); - } +.buttons { + white-space: pre; + margin-left: 24px } -.skip-notice { - animation-duration: 4.5s, 1.5s; - animation-iteration-count: 1, 1; - animation-timing-function: linear, linear; - animation-name: appear, splash-fg; - animation-delay: 0s, 3s; - visibility: hidden; +.back { + margin-bottom: 8px; + display: inline-block +} + +:focus { + outline: none } \ No newline at end of file diff --git a/assets/main.js b/assets/main.js index bf09d22..26113f6 100644 --- a/assets/main.js +++ b/assets/main.js @@ -1,16 +1,43 @@ let stylesheet +var audio = new(window.AudioContext) +let jsDiv +let mode +let side +let focusMain +let focusSecond +const focusSelector = "a, d" +const back = document.createElement("a") +back.setAttribute("onclick", "tui.home()") +back.setAttribute("tabindex", "0") +back.className = "back" +back.innerHTML = `⬑Back` window.addEventListener("load", () => { stylesheet = document.styleSheets[0]; - + + // randomize loading text + fetch("/assets/loading.txt") + .then(r => r.text()) + .then(t => Load(t)) + + // allow the user to skip on click let skipNode = document.createElement("div"); skipNode.setAttribute("class", "skip-animation"); skipNode.setAttribute("onclick", "skipAnimation()"); document.body.appendChild(skipNode); - fetch("/assets/loading.txt") - .then(r => r.text()) - .then(t => Load(t)) + // get rid of shit since we have javascript babyyyyyyy + if (matchMedia("(min-width: 430px) and (min-height: 430px").matches) { + for (let node of document.getElementsByClassName("nojs")) { + node.style.display = "none" + } + stylesheet.insertRule(".js { visibility: visible }", stylesheet.cssRules.length) + stylesheet.insertRule(".skip-notice { opacity: 1 }", stylesheet.cssRules.length) + stylesheet.insertRule("d:focus { color: var(--c-bg); background-color: var(--c-fg) }", stylesheet.cssRules.length) + document.querySelectorAll("head style").forEach(style => style.remove()); + jsDiv = document.getElementsByClassName("js")[0] + tui.home() + } }); // skip animations and shit @@ -42,3 +69,180 @@ function Load (text) { loading.children[1].innerHTML = loadText + ".." loading.children[2].innerHTML = loadText + "..." } + +// beep! +function beep() { + var oscillator = audio.createOscillator() + + oscillator.type = "square" + oscillator.frequency.value = "1200" + oscillator.connect(audio.destination) + oscillator.start() + + setTimeout(() => { + oscillator.stop() + }, 200) +} + +// here are the functions that create every different section +const tui = { + home: function() { + mode = "home" + + const div = document.createElement("div") + div.appendChild(document.getElementsByClassName("ascii")[0].cloneNode(true)); + + let buttons = document.createElement("div") + buttons.className = "buttons" + buttons.innerHTML = `About +Users +Services +Linuxposting +Beep` + div.appendChild(buttons) + + const title = document.createElement("span") + title.className = "title" + title.innerHTML = "Linuxposting Tilde~" + div.appendChild(title) + + jsDiv.children[0].replaceChildren(div) + if (jsDiv.children[1]) {jsDiv.children[1].remove()} + + indexFocus() + }, + + about: function() { + mode = "about" + + const div = document.createElement("div") + + div.appendChild(back) + + div.appendChild(document.getElementsByClassName("ascii")[0].cloneNode(true)); + div.appendChild(document.getElementById("about").cloneNode(true)); + + const title = document.createElement("span") + title.className = "title" + title.innerHTML = "About" + div.appendChild(title) + + jsDiv.children[0].replaceChildren(div) + if (jsDiv.children[1]) {jsDiv.children[1].remove()} + + indexFocus() + }, + + users: function() { + mode = "users" + + const div = document.createElement("div") + + div.appendChild(back) + + div.appendChild(document.getElementById("users").cloneNode(true)); + + const title = document.createElement("span") + title.className = "title" + title.innerHTML = "Users" + div.appendChild(title) + + const div2 = document.createElement("div") + + const title2 = document.createElement("span") + title2.className = "title2" + title2.innerHTML = "Description" + div2.appendChild(document.createElement("div")) + div2.appendChild(title2) + + jsDiv.children[0].replaceChildren(div) + if (jsDiv.children[1]) {jsDiv.children[1].remove()} + jsDiv.appendChild(div2) + + indexFocus() + }, + + services: function() { + mode = "services" + + const div = document.createElement("div") + + div.appendChild(back) + + div.appendChild(document.getElementById("services").cloneNode(true)); + + const title = document.createElement("span") + title.className = "title" + title.innerHTML = "Services" + div.appendChild(title) + + const div2 = document.createElement("div") + + const title2 = document.createElement("span") + title2.className = "title2" + title2.innerHTML = "Description" + div2.appendChild(document.createElement("div")) + div2.appendChild(title2) + + jsDiv.children[0].replaceChildren(div) + if (jsDiv.children[1]) {jsDiv.children[1].remove()} + jsDiv.appendChild(div2) + + indexFocus() + }, + + updateFocus: function() { + const focused = document.activeElement + const sibling = focused.nextElementSibling + switch(mode) { + case "users": + case "services": + if (sibling && sibling.tagName === "P") { + jsDiv.children[1].children[0].replaceChildren(sibling.cloneNode(true)) + } else { + jsDiv.children[1].children[0].innerHTML = "" + } + break + } + } +} + +function indexFocus() { + focusList = Array.from(document.querySelectorAll(focusSelector)).filter(el => el.offsetParent !== null) + if (jsDiv.children[1]) { + focusList = focusList.filter(el => !jsDiv.children[1].contains(el)) + } +} + +document.addEventListener("mouseover", (e) => { + if (e.target.tagName.toLowerCase() === "a" || e.target.tagName.toLowerCase() === "d") { + e.target.focus() + tui.updateFocus() + } +}) + +document.addEventListener("keydown", (e) => { + if (!jsDiv) { return } + const currentFocus = focusList.indexOf(document.activeElement) + const focused = document.activeElement + switch(e.key) { + case "Escape": + tui.home() + break + case "ArrowDown": + case "ArrowRight": + e.preventDefault() + focusList[Math.min(currentFocus+1, focusList.length-1)].focus() + tui.updateFocus() + break + case "ArrowUp": + case "ArrowLeft": + e.preventDefault() + focusList[Math.max(0, currentFocus-1)].focus() + tui.updateFocus() + break + case "Enter": + case " ": + focused.click() + } +}) \ No newline at end of file diff --git a/assets/nojs.css b/assets/nojs.css new file mode 100644 index 0000000..e69de29 diff --git a/index.html b/index.html index 9a518c1..7e7d2cb 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,9 @@ Linuxposting Tilde + + @@ -21,20 +23,21 @@ ┘ ┘ + site by Magdalunaa :3 Click to skip