js-typing

This commit is contained in:
2025-03-10 06:12:55 -04:00
parent 89f1d0b358
commit ec75142396
4 changed files with 166 additions and 71 deletions

View File

@@ -18,10 +18,10 @@ export const options = {
root, root,
service_worker: false, service_worker: false,
templates: { templates: {
app: ({ head, body, assets, nonce, env }) => "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <link rel=\"icon\" href=\"" + assets + "/favicon.png\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n " + head + "\n </head>\n <body data-sveltekit-preload-data=\"hover\">\n <div style=\"display: contents\">" + body + "</div>\n </body>\n</html>\n\n<style>\n body {\n background-color: #181818;\n }\n</style>\n", app: ({ head, body, assets, nonce, env }) => "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <link rel=\"icon\" href=\"" + assets + "/favicon.png\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <link rel=\"stylesheet\" href=\"src/style.css\"\n " + head + "\n </head>\n <body id=\"background\" data-sveltekit-preload-data=\"hover\">\n <div class=\"background\">" + body + "</div>\n </body>\n</html>\n\n",
error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>" + message + "</title>\n\n\t\t<style>\n\t\t\tbody {\n\t\t\t\t--bg: white;\n\t\t\t\t--fg: #222;\n\t\t\t\t--divider: #ccc;\n\t\t\t\tbackground: var(--bg);\n\t\t\t\tcolor: var(--fg);\n\t\t\t\tfont-family:\n\t\t\t\t\tsystem-ui,\n\t\t\t\t\t-apple-system,\n\t\t\t\t\tBlinkMacSystemFont,\n\t\t\t\t\t'Segoe UI',\n\t\t\t\t\tRoboto,\n\t\t\t\t\tOxygen,\n\t\t\t\t\tUbuntu,\n\t\t\t\t\tCantarell,\n\t\t\t\t\t'Open Sans',\n\t\t\t\t\t'Helvetica Neue',\n\t\t\t\t\tsans-serif;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.error {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tmax-width: 32rem;\n\t\t\t\tmargin: 0 1rem;\n\t\t\t}\n\n\t\t\t.status {\n\t\t\t\tfont-weight: 200;\n\t\t\t\tfont-size: 3rem;\n\t\t\t\tline-height: 1;\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -0.05rem;\n\t\t\t}\n\n\t\t\t.message {\n\t\t\t\tborder-left: 1px solid var(--divider);\n\t\t\t\tpadding: 0 0 0 1rem;\n\t\t\t\tmargin: 0 0 0 1rem;\n\t\t\t\tmin-height: 2.5rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.message h1 {\n\t\t\t\tfont-weight: 400;\n\t\t\t\tfont-size: 1em;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\t--bg: #222;\n\t\t\t\t\t--fg: #ddd;\n\t\t\t\t\t--divider: #666;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"error\">\n\t\t\t<span class=\"status\">" + status + "</span>\n\t\t\t<div class=\"message\">\n\t\t\t\t<h1>" + message + "</h1>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>\n" error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>" + message + "</title>\n\n\t\t<style>\n\t\t\tbody {\n\t\t\t\t--bg: white;\n\t\t\t\t--fg: #222;\n\t\t\t\t--divider: #ccc;\n\t\t\t\tbackground: var(--bg);\n\t\t\t\tcolor: var(--fg);\n\t\t\t\tfont-family:\n\t\t\t\t\tsystem-ui,\n\t\t\t\t\t-apple-system,\n\t\t\t\t\tBlinkMacSystemFont,\n\t\t\t\t\t'Segoe UI',\n\t\t\t\t\tRoboto,\n\t\t\t\t\tOxygen,\n\t\t\t\t\tUbuntu,\n\t\t\t\t\tCantarell,\n\t\t\t\t\t'Open Sans',\n\t\t\t\t\t'Helvetica Neue',\n\t\t\t\t\tsans-serif;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.error {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tmax-width: 32rem;\n\t\t\t\tmargin: 0 1rem;\n\t\t\t}\n\n\t\t\t.status {\n\t\t\t\tfont-weight: 200;\n\t\t\t\tfont-size: 3rem;\n\t\t\t\tline-height: 1;\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -0.05rem;\n\t\t\t}\n\n\t\t\t.message {\n\t\t\t\tborder-left: 1px solid var(--divider);\n\t\t\t\tpadding: 0 0 0 1rem;\n\t\t\t\tmargin: 0 0 0 1rem;\n\t\t\t\tmin-height: 2.5rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.message h1 {\n\t\t\t\tfont-weight: 400;\n\t\t\t\tfont-size: 1em;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\t--bg: #222;\n\t\t\t\t\t--fg: #ddd;\n\t\t\t\t\t--divider: #666;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"error\">\n\t\t\t<span class=\"status\">" + status + "</span>\n\t\t\t<div class=\"message\">\n\t\t\t\t<h1>" + message + "</h1>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>\n"
}, },
version_hash: "i6vb0w" version_hash: "1mj17wc"
}; };
export async function get_hooks() { export async function get_hooks() {

View File

@@ -4,15 +4,11 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="src/style.css"
%sveltekit.head% %sveltekit.head%
</head> </head>
<body data-sveltekit-preload-data="hover"> <body id="background" data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div> <div class="background">%sveltekit.body%</div>
</body> </body>
</html> </html>
<style>
body {
background-color: #181818;
}
</style>

View File

@@ -1,78 +1,84 @@
<!-- <div id="navbar">
<button>Home</button>
<button>About</button>
<!-- turning ideas into reality with tech -->
<!-- into gritty hard-scifi games -->
<!-- <button>Projects</button>
<button>Hobbies</button>
<button>Contact</button>
</div> -->
<div class="card"> <svelte:head>
<p>Hey, I'm</p> <title>Jeremy Janella | Computer Scientist</title>
<div id="display"> </svelte:head>
<h1 id="jeremymaxxing">JEREMY JANELLA</h1>
</div> <div id="name-card" class="align-right card">
<p>Computer nerd, gamer, mountain biker, adventurer</p> <p id="HeyIm">Hey! My name is</p>
<span use:animateTyping={["Jeremy Janella"]} id="jeremymaxxing"></span>
<p>An experienced full stack developer, cybersecurity enthusiest, and computer science student at the University of Toronto active in CTFs, hackathons, programming competitions, and indie developer of the soon-to-be-released game Subterworks</p>
<p>This site is still being ported!</p>
<!-- <p>Computer nerd, gamer, mountain biker, adventurer, hard sci-fi enjoyer, ethics enjoyer, swimmer, jumper</p> -->
</div> </div>
<!-- <p>Computer Science Student, Interested in Cyber Security, Networiking, Open source, and always learning something new</p>--> <!-- <p>Computer Science Student, Interested in Cyber Security, Networiking, Open source, and always learning something new</p>-->
<!-- Game dev, servers experiements, cyberpatriot, linux, ai serversresume--> <!-- Game dev, servers experiements, cyberpatriot, linux, ai serversresume-->
<style> <script lang="ts">
* { export function animateTyping(node: HTMLElement, texts: string[]) {
color: rgb(212 212 216); let textsToType = texts;
background-color: #222;
font-family: sans-serif;
}
button {
border-width: 0px;
margin: 0px;
padding: 16px;
font-size: 1em;
}
#navbar { let textsIndex = 0;
margin: 4px; let charIndex = 0;
border-radius: 12px; let currentText = '';
}
#display { const updateInnerHTML = () => {
display: inline-block; // Always include the zero-width space and conditionally add the text and cursor
} node.innerHTML = '&#8203;' + currentText;
};
.card { const waitMsec = (delay: number) => {
margin: 8px; setTimeout(() => { updateInnerHTML();}, delay);
padding: 8px; };
border-radius: 12px;
}
#jeremymaxxing { // Typing animation effect
font-weight: 800; const typeEffect = () => {
font-size: clamp(2.5rem,7vw,4rem); const currentString = textsToType[textsIndex];
line-height: 1.25; const delay = currentString[charIndex] === ' ' ? 25 : 30;
margin: 0px;
text-shadow: 2px 1px orangered, -2px -1px cornflowerblue;
}
/* https://css-tricks.com/snippets/css/typewriter-effect/ */ if (charIndex < currentString.length) {
h1 { currentText += currentString[charIndex++];
font-family: monospace; setTimeout(typeEffect, delay);
padding: 8px; } else {
display: inline-block; waitMsec(3000);
overflow: hidden; /* Ensures the content is not revealed until the animation */ setTimeout(deleteEffect, 6000); // Wait before starting to delete
border-right: .1em solid orangered; /* The typwriter cursor */ }
white-space: nowrap; /* Keeps the content on a single line */
/* margin: 0 auto; /* Gives that scrolling effect as the typing happens */
padding: 0px;
animation:
typing 0.5s steps(16),
blink 0.5s step-end infinite;
}
updateInnerHTML();
};
/* The typing effect */ // Deleting animation effect
@keyframes typing { const deleteEffect = () => {
from { width: 0 } if (charIndex > 0) {
to { width: 100% } currentText = currentText.slice(0, --charIndex);
} setTimeout(deleteEffect, 20);
} else {
textsIndex = (textsIndex + 1) % textsToType.length;
currentText = ''; // Clear text but keep zero-width space
setTimeout(typeEffect, 1250);
}
/* The typewriter cursor effect */ updateInnerHTML();
@keyframes blink { };
from, to { border-color: transparent }
50% { border-color: orangered; }
}
</style> // Start typing effect
setTimeout(typeEffect, 250);
return {
onDestroy() {},
update(newTexts: string[]) {
textsToType = newTexts;
}
};
}
</script>

93
site/src/style.css Normal file
View File

@@ -0,0 +1,93 @@
#name-card {
background-color: #222;
}
#projects-card {
background-color: maroon;
}
#hobbies-card {
background-color: #FFCE00;
}
button {
border-radius: 0px;
background-color: #222;
border-width: 0;
padding: 20px;;
}
.card {
margin-top: 2rem;
min-width: 55vmax;
max-width: 70vmax;
width: min-content;
margin-bottom: 2rem;
padding: 12px;
}
.align-right {
float: right;
border-left: 0.8rem solid orangered;
}
.align-left {
margin-right: 25%;
}
#HeyIm {
padding-left: 5ch;
font-weight: 600;
margin: 10px;
margin-bottom: 15px;
}
body {
background-color: #000;
margin: 0px;
}
* {
color: rgb(212 212 216);
font-family: sans-serif;
}
#jeremymaxxing {
font-weight: 1000;
font-size: 5rem;
line-height: 1;
margin: 20px;
text-shadow: 2px 2px orangered, -2px -2px cornflowerblue;
letter-spacing: 2px;
width: fit-content;
border-right: 0.4rem solid orangered;
}
.title {
font-weight: 600;
font-size: 4rem;
}
/* https://css-tricks.com/snippets/css/typewriter-effect/ */
.typed {
font-family: monospace;
overflow: hidden; /* Ensures the content is not revealed until the animation */
border-right: .1em solid orangered; /* The typwriter cursor */
white-space: nowrap; /* Keeps the content on a single line */
/* margin: 0 auto; /* Gives that scrolling effect as the typing happens */
animation:
typing 0.5s steps(16);
}
/* The typing effect */
@keyframes typing {
from { width: 0 }
to { width: 110% }
}
/* The typewriter cursor effect */
@keyframes blink {
from, to { border-color: orangered}
50% { border-color: transparent; }
}