commit 32189ecd21fb48a43b3665687ae5276dfa19bec9 Author: ari melody Date: Sat Sep 30 02:34:43 2023 +0100 first commit! 🎉 diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..d466cc0 --- /dev/null +++ b/public/index.html @@ -0,0 +1,17 @@ + + + + Open Terminal + + + + + + + +
+

+			
+
+ + diff --git a/public/scripts/main.js b/public/scripts/main.js new file mode 100644 index 0000000..b08ce5d --- /dev/null +++ b/public/scripts/main.js @@ -0,0 +1,87 @@ +var TERM_INTERVAL = 0; +var buffer = ""; +var content; + +const banner = +`OpenTerminal v0.1.0 +made with <3 by ari melody + +`; + +function start() { + content = document.getElementById("content"); + send_text(banner); + loop(); +} + +function loop() { + if (buffer.length > 0) { + const carat = content.querySelector("#carat"); + if (carat) carat.remove(); + + const char = buffer.slice(0, 1); + if (char == "\b") { + content.innerText = content.innerText.slice(0, content.innerText.length - 1); + } else { + content.innerText += char; + } + buffer = buffer.slice(1); + + const new_carat = document.createElement("div"); + new_carat.id = "carat"; + content.appendChild(new_carat); + } + + setTimeout(loop, TERM_INTERVAL); +} + +function handle_input(event) { + // console.debug(event.key); + + if (event.key == "Backspace") { + if (event.ctrlKey) { + const last_space = content.innerText.lastIndexOf(" "); + const last_newline = content.innerText.lastIndexOf("\n"); + + var break_at = last_space; + if (last_newline > last_space) { + break_at = last_newline; + } + + const word_length = content.innerText.length - break_at; + send_text("\b".repeat(word_length)); + return; + } + send_text("\b"); + return; + } + if (event.key.startsWith("Arrow")) { + return; + } + switch (event.key) { + case 'Shift': + case 'Control': + case 'Alt': + return; + case 'Enter': + send_text('\n'); + break; + } + if (event.key.length > 1) { + return; + } + + send_text(event.key); +} + +function send_text(char) { + content.scrollTop = content.scrollHeight; + buffer += char; +} + +document.addEventListener("DOMContentLoaded", () => { + start(); +}); + +document.addEventListener("keydown", handle_input); + diff --git a/public/styles/main.css b/public/styles/main.css new file mode 100644 index 0000000..d978aef --- /dev/null +++ b/public/styles/main.css @@ -0,0 +1,70 @@ +:root { + --term-colour: #00ff00; +} + +body { + margin: 0; + padding: 0; + color: var(--term-colour); + background: #111; + font-family: monospace; + font-size: 12px; +} + +main { + margin: 1rem; + border: 1px solid var(--term-colour); +} + +pre#content { + height: calc(100vh - 66px); + margin: 0; + padding: 1rem; + overflow-x: hidden; + overflow-y: scroll; + white-space: break-spaces; + line-break: anywhere; + text-shadow: 0 0 1em, 0 0 3em; +} + +div#carat { + width: .5em; + height: .9em; + display: inline-block; + background: var(--term-colour); + transform: translateY(1px); + animation: linear .5s infinite forwards carat-blink; +} + +@keyframes carat-blink { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +div#overlay { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-image: linear-gradient(180deg, rgba(0,0,0,0) 15%, rgb(0, 0, 0) 40%, rgb(0, 0, 0) 60%, rgba(0,0,0,0) 85%); + background-size: 100vw .2em; + background-repeat: repeat; + opacity: .5; + pointer-events: none; + animation: linear .05s infinite alternate overlay-flicker; + mix-blend-mode: overlay; +} + +@keyframes overlay-flicker { + from { + opacity: .5; + } + to { + opacity: .6; + } +}