first commit! 🎉
This commit is contained in:
commit
32189ecd21
17
public/index.html
Normal file
17
public/index.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ie">
|
||||||
|
<head>
|
||||||
|
<title>Open Terminal</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="styles/main.css">
|
||||||
|
|
||||||
|
<script src="scripts/main.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<pre id="content"></pre>
|
||||||
|
<div id="overlay"></div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
87
public/scripts/main.js
Normal file
87
public/scripts/main.js
Normal file
|
@ -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);
|
||||||
|
|
70
public/styles/main.css
Normal file
70
public/styles/main.css
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue