mirror of
https://git.ari.lt/ari.lt/ari.lt.git
synced 2025-02-04 09:39:25 +01:00
update @ Sun 22 May 14:57:42 EEST 2022
Signed-off-by: Ari Archer <ari.web.xyz@gmail.com>
This commit is contained in:
parent
e197ecafae
commit
c087e4fb41
6 changed files with 459 additions and 1 deletions
|
@ -5,7 +5,8 @@ module.exports = {
|
|||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest"
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
}
|
||||
|
|
34
content/js/ttytheme/events.js
Normal file
34
content/js/ttytheme/events.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
"use strict";
|
||||
|
||||
import {
|
||||
clear_states,
|
||||
generate_theme,
|
||||
export_element_as_file,
|
||||
copy_elem_to_clip,
|
||||
} from "./menu.js";
|
||||
|
||||
const ONCLICK_EVENTS = {
|
||||
"clear-states": () => {
|
||||
clear_states();
|
||||
window.location.reload();
|
||||
},
|
||||
"generate-theme": generate_theme,
|
||||
"export-file": export_element_as_file,
|
||||
copy: copy_elem_to_clip,
|
||||
};
|
||||
|
||||
function main() {
|
||||
for (let id in ONCLICK_EVENTS)
|
||||
document.getElementById(id).addEventListener("click", async () => {
|
||||
ONCLICK_EVENTS[id]();
|
||||
|
||||
let self_elem = document.getElementById(id);
|
||||
let old_text = self_elem.innerText;
|
||||
|
||||
self_elem.innerText = "Done!";
|
||||
await new Promise((r) => setTimeout(r, 800));
|
||||
self_elem.innerText = old_text;
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", main);
|
209
content/js/ttytheme/menu.js
Normal file
209
content/js/ttytheme/menu.js
Normal file
|
@ -0,0 +1,209 @@
|
|||
"use strict";
|
||||
|
||||
import { gp } from "../../js/utils/index.js";
|
||||
|
||||
var tty_clrs = {
|
||||
black: [0, 0, 0],
|
||||
red: [170, 0, 0],
|
||||
green: [0, 170, 0],
|
||||
orange: [170, 85, 0],
|
||||
blue: [0, 0, 170],
|
||||
magenta: [170, 0, 170],
|
||||
cyan: [0, 170, 170],
|
||||
gray: [170, 170, 170],
|
||||
dark_gray: [85, 85, 85],
|
||||
light_red: [255, 85, 85],
|
||||
light_green: [85, 255, 85],
|
||||
yellow: [255, 255, 85],
|
||||
light_blue: [85, 85, 255],
|
||||
light_magenta: [255, 85, 255],
|
||||
light_cyan: [85, 255, 255],
|
||||
white: [255, 255, 255],
|
||||
};
|
||||
const CLRS = ["r", "g", "b"];
|
||||
const BLACKLIST_LC = ["username", "password"];
|
||||
const TTY_MODS = {
|
||||
black: "0",
|
||||
red: "9",
|
||||
green: "2",
|
||||
orange: "1",
|
||||
blue: "4",
|
||||
magenta: "5",
|
||||
cyan: "6",
|
||||
gray: "7",
|
||||
dark_gray: "5",
|
||||
light_red: "5",
|
||||
light_green: "A",
|
||||
yellow: "B",
|
||||
light_blue: "C",
|
||||
light_magenta: "D",
|
||||
light_cyan: "E",
|
||||
white: "F",
|
||||
};
|
||||
|
||||
function new_colourpicker(id, clr_map) {
|
||||
let div = document.createElement("div");
|
||||
|
||||
div.id = id;
|
||||
|
||||
CLRS.forEach((item, index) => {
|
||||
let clr = document.createElement("input");
|
||||
|
||||
clr.type = "range";
|
||||
clr.min = 0;
|
||||
clr.max = 255;
|
||||
clr.name = item;
|
||||
clr.value = clr_map[index];
|
||||
clr.addEventListener("input", () => update_colour(id));
|
||||
|
||||
div.appendChild(clr);
|
||||
});
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
function update_colour(id) {
|
||||
let picker = document.getElementById(id);
|
||||
let gc = (value) => Number(picker.children[value].value); // get colour
|
||||
let rgb = [gc("r"), gc("g"), gc("b")];
|
||||
|
||||
picker.style.backgroundColor = `rgb(${rgb.join(",")})`;
|
||||
localStorage.setItem(id, JSON.stringify({ rgb: rgb }));
|
||||
|
||||
tty_clrs[id] = rgb;
|
||||
generate_theme();
|
||||
}
|
||||
|
||||
function load_from_localtorage() {
|
||||
let keys = Object.keys(tty_clrs);
|
||||
|
||||
Object.keys(localStorage).forEach((key) => {
|
||||
if (!BLACKLIST_LC.includes(key) && keys.includes(key))
|
||||
tty_clrs[key] = JSON.parse(localStorage.getItem(key))["rgb"].map(
|
||||
Number
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function component_to_hex(c) {
|
||||
var hex = c.toString(16);
|
||||
return hex.length == 1 ? "0" + hex : hex;
|
||||
}
|
||||
|
||||
function rgb_to_hex(rgb) {
|
||||
let hex = "";
|
||||
rgb.forEach((item) => (hex += component_to_hex(item)));
|
||||
return hex;
|
||||
}
|
||||
|
||||
function save(filename, data) {
|
||||
const blob = new Blob([data], { type: "text/plain" });
|
||||
|
||||
if (window.navigator.msSaveOrOpenBlob)
|
||||
window.navigator.msSaveBlob(blob, filename);
|
||||
else {
|
||||
const elem = window.document.createElement("a");
|
||||
|
||||
elem.href = window.URL.createObjectURL(blob);
|
||||
elem.download = filename;
|
||||
|
||||
document.body.appendChild(elem);
|
||||
elem.click();
|
||||
document.body.removeChild(elem);
|
||||
}
|
||||
}
|
||||
|
||||
export function generate_theme(query = "#theme-output") {
|
||||
document.body.style.backgroundColor = `rgb(${tty_clrs["black"].join(",")})`;
|
||||
document.body.style.color = `rgb(${tty_clrs["white"].join(",")})`;
|
||||
|
||||
let elem = document.querySelector(query);
|
||||
if (!elem) throw ReferenceError(`${query} did not match any results`);
|
||||
|
||||
let text = `# Theme generated using: ${window.location.href}
|
||||
# Installation: Just add these lines to your ~/.bashrc
|
||||
|
||||
__tty_theme() {
|
||||
[ "$TERM" != 'linux' ] && return # Only run in a TTY
|
||||
|
||||
`;
|
||||
|
||||
for (const key in tty_clrs) {
|
||||
let key_rgb = tty_clrs[key];
|
||||
let key_hex = rgb_to_hex(key_rgb);
|
||||
let rgb_str = `rgb(${key_rgb.join(", ")})`;
|
||||
|
||||
text += ` printf "\\e]P${TTY_MODS[key]}${key_hex}" # ${key}${gp(
|
||||
key,
|
||||
15
|
||||
)}${rgb_str}${gp(rgb_str, 20)}#${key_hex}\n`;
|
||||
}
|
||||
|
||||
text += `
|
||||
clear # To fix the background
|
||||
}
|
||||
|
||||
__tty_theme
|
||||
`;
|
||||
elem.innerText = text;
|
||||
}
|
||||
|
||||
export function export_element_as_file(query = "#theme-output") {
|
||||
generate_theme(query);
|
||||
save("ari_web_theme.bash", document.querySelector(query).innerText);
|
||||
}
|
||||
|
||||
export function clear_states() {
|
||||
Object.keys(localStorage).forEach((key) => {
|
||||
if (!BLACKLIST_LC.includes(key)) localStorage.removeItem(key);
|
||||
});
|
||||
}
|
||||
|
||||
export function copy_elem_to_clip(query = "#theme-output") {
|
||||
let elem = document.querySelector(query);
|
||||
if (!elem) throw ReferenceError(`Query '${query}' did not return anything`);
|
||||
|
||||
let text_area = document.createElement("textarea");
|
||||
|
||||
text_area.style.position = "fixed";
|
||||
text_area.style.top = 0;
|
||||
text_area.style.left = 0;
|
||||
|
||||
text_area.style.width = "2em";
|
||||
text_area.style.height = "2em";
|
||||
|
||||
text_area.style.padding = 0;
|
||||
|
||||
text_area.style.border = "none";
|
||||
text_area.style.outline = "none";
|
||||
text_area.style.boxShadow = "none";
|
||||
|
||||
text_area.style.background = "transparent";
|
||||
|
||||
text_area.value = elem.innerText;
|
||||
|
||||
document.body.appendChild(text_area);
|
||||
text_area.focus();
|
||||
text_area.select();
|
||||
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(text_area);
|
||||
}
|
||||
|
||||
function main() {
|
||||
load_from_localtorage();
|
||||
let menu = document.getElementById("menu");
|
||||
|
||||
for (const key in tty_clrs) {
|
||||
let [r, g, b] = tty_clrs[key];
|
||||
let picker = new_colourpicker(key, [r, g, b]);
|
||||
|
||||
picker.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
|
||||
|
||||
menu.appendChild(picker);
|
||||
}
|
||||
|
||||
generate_theme();
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", main);
|
10
content/js/utils/index.js
Normal file
10
content/js/utils/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
"use strict";
|
||||
|
||||
// Get padding
|
||||
export function gp(str, pad) {
|
||||
let ammount = pad - str.length;
|
||||
|
||||
if (ammount <= 0) return "";
|
||||
|
||||
return " ".repeat(ammount);
|
||||
}
|
125
content/styles/ttytheme/styles.css
Normal file
125
content/styles/ttytheme/styles.css
Normal file
|
@ -0,0 +1,125 @@
|
|||
@import url("https://cdn.jsdelivr.net/npm/hack-font@3/build/web/hack.min.css");
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
font-family: sans-serif;
|
||||
color: inherit;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: Hack, hack, monospace;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
text-rendering: optimizeSpeed;
|
||||
line-height: 1.5;
|
||||
padding: 2em;
|
||||
max-width: 1600px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.split {
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
|
||||
-ms-grid-columns: auto 4em auto;
|
||||
grid-template-columns: auto auto;
|
||||
|
||||
grid-gap: 4em;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
padding: 0.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.buttons button {
|
||||
padding: 0.5em;
|
||||
margin: 0.1em;
|
||||
margin-bottom: 1em;
|
||||
background-color: #404040;
|
||||
border: none;
|
||||
|
||||
-webkit-transition: 0.3s -webkit-filter ease-in-out;
|
||||
transition: 0.3s -webkit-filter ease-in-out;
|
||||
-o-transition: 0.3s filter ease-in-out;
|
||||
transition: 0.3s filter ease-in-out;
|
||||
transition: 0.3s filter ease-in-out, 0.3s -webkit-filter ease-in-out;
|
||||
}
|
||||
|
||||
button:hover,
|
||||
button:focus {
|
||||
cursor: pointer;
|
||||
|
||||
-webkit-filter: brightness(120%);
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
#menu {
|
||||
text-align: center;
|
||||
margin: 4em 0 4em 0;
|
||||
}
|
||||
|
||||
#menu div input {
|
||||
margin: 0.1em;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1300px) {
|
||||
.split {
|
||||
display: block;
|
||||
-ms-grid-columns: auto;
|
||||
|
||||
grid-template-columns: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
scroll-behavior: auto;
|
||||
|
||||
-webkit-animation-duration: 0.01ms !important;
|
||||
animation-duration: 0.01ms !important;
|
||||
|
||||
-webkit-animation-iteration-count: 1 !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
|
||||
-webkit-transition-duration: 0.01ms !important;
|
||||
-o-transition-duration: 0.01ms !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
79
page/ttytheme/index.html
Normal file
79
page/ttytheme/index.html
Normal file
|
@ -0,0 +1,79 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Ari::web -> TTY</title>
|
||||
|
||||
<meta name="description" content="TTY generator by ari-web" />
|
||||
<meta
|
||||
name="keywords"
|
||||
content="tty theme linux cli terminal generator theme-generator foss unlicense"
|
||||
/>
|
||||
<meta name="robots" content="follow" />
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="color-scheme" content="dark" />
|
||||
|
||||
<script
|
||||
type="module"
|
||||
src="/content/js/ttytheme/events.js"
|
||||
defer
|
||||
></script>
|
||||
<script type="module" src="/content/js/ttytheme/menu.js" defer></script>
|
||||
|
||||
<link rel="stylesheet" href="/content/styles/ttytheme/styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Linux TTY theme generator by Ari::web</h1>
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
.nojs {
|
||||
background-color: darkred !important;
|
||||
padding: 1em !important;
|
||||
}
|
||||
|
||||
.nojs * {
|
||||
color: whitesmoke !important;
|
||||
font-weight: bold !important;
|
||||
font-family: sans-serif !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="nojs">
|
||||
<h1>This generator won't work without JavaScript enabled :(</h1>
|
||||
<h1>
|
||||
If you don't trust me, check the JavaScript yourself
|
||||
<a
|
||||
href="https://github.com/TruncatedDinosour/website/tree/terminal/content/js/ttytheme"
|
||||
target=""
|
||||
_blank
|
||||
>on GitHub</a
|
||||
>
|
||||
</h1>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
<h2>
|
||||
All themes generated here are under
|
||||
<a href="https://unlicense.org/" target="_blank">unlicense</a>, but
|
||||
credit is appriciated :), source code:
|
||||
<a href="/git" target="_blank">git</a>
|
||||
</h2>
|
||||
|
||||
<div class="buttons">
|
||||
<button id="clear-states">Clear saved slider states</button>
|
||||
<button id="generate-theme">Generate (refresh) theme</button>
|
||||
<button id="export-file">Export theme as file</button>
|
||||
<button id="copy">Copy to clipboard</button>
|
||||
</div>
|
||||
|
||||
<div class="split">
|
||||
<div id="menu"></div>
|
||||
<pre id="theme-output" class="output"></pre>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue