animations

This commit is contained in:
N0\A
2025-10-30 08:41:03 +01:00
parent a3d382b1b7
commit eadbf18661
5 changed files with 385 additions and 142 deletions

31
animations.js Normal file
View File

@@ -0,0 +1,31 @@
(function () {
const backToTopButton = document.getElementById("back-to-top");
if (backToTopButton) {
function toggleBackToTop() {
if (window.pageYOffset > 300) {
backToTopButton.classList.add("visible");
} else {
backToTopButton.classList.remove("visible");
}
}
backToTopButton.addEventListener("click", function () {
window.scrollTo({
top: 0,
behavior: "smooth",
});
});
window.addEventListener("scroll", toggleBackToTop);
toggleBackToTop();
}
const listItems = document.querySelectorAll("li");
listItems.forEach((item, index) => {
if (!item.style.animationDelay) {
item.style.animationDelay = `${0.1 + index * 0.05}s`;
}
});
})();

View File

@@ -3,41 +3,41 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Krzak.org</title> <title>Krzak.org - Contact</title>
<link rel="stylesheet" href="/styles.css"> <link rel="stylesheet" href="/styles.css" />
</head> </head>
<body> <body>
<div class="container"> <div class="container fade-in">
<h1> <h1 class="slide-down">
<span class="icon"> <span class="icon">
<img src="/icon.svg" alt="krzak.org" /> <img src="/icon.svg" alt="krzak.org" />
</span> </span>
Krzak.org Krzak.org
</h1> </h1>
<p>Contact:</p> <p class="slide-down">Contact:</p>
<ul> <ul>
<li> <li class="slide-up" style="animation-delay: 0.1s">
<a href="https://fedi.krzak.org/@krzak"> <a href="https://fedi.krzak.org/@krzak">
<strong>Fediverse</strong> <strong>Fediverse</strong>
<span>@krzak@fedi.krzak.org</span> <span>@krzak@fedi.krzak.org</span>
</a> </a>
</li> </li>
<li> <li class="slide-up" style="animation-delay: 0.15s">
<a href="mailto:admin@krzak.org"> <a href="mailto:admin@krzak.org">
<strong>Mail</strong> <strong>Mail</strong>
<span>admin@krzak.org</span> <span>admin@krzak.org</span>
</a> </a>
</li> </li>
<li> <li class="slide-up" style="animation-delay: 0.2s">
<a href=""> <a href="">
<strong>Discord</strong> <strong>Discord</strong>
<span>n0va_bot</span> <span>n0va_bot</span>
</a> </a>
</li> </li>
</ul> </ul>
<p>Support:</p> <p class="fade-in" style="animation-delay: 0.25s">Support:</p>
<ul> <ul>
<li> <li class="slide-up" style="animation-delay: 0.3s">
<a href=""> <a href="">
<strong>Blik</strong> <strong>Blik</strong>
<span>+48 536 605 450</span> <span>+48 536 605 450</span>
@@ -46,13 +46,37 @@
</ul> </ul>
<br /> <br />
<ul> <ul>
<li> <li class="slide-up" style="animation-delay: 0.35s">
<a href="/"> <a href="/">
<strong>Back</strong> <strong>Back</strong>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<!-- Back to top button -->
<button
id="back-to-top"
class="back-to-top"
aria-label="Back to top"
title="Back to top"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="18 15 12 9 6 15"></polyline>
</svg>
</button>
<script src="/refresh.js"></script> <script src="/refresh.js"></script>
<script src="/animations.js"></script>
</body> </body>
</html> </html>

View File

@@ -6,72 +6,138 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Favicons --> <!-- Favicons -->
<link rel="icon" type="image/svg+xml" href="/favicons/favicon.svg"> <link rel="icon" type="image/svg+xml" href="/favicons/favicon.svg" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png"> <link
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png"> rel="icon"
<link rel="icon" type="image/png" sizes="48x48" href="/favicons/favicon-48x48.png"> type="image/png"
<link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png"> sizes="16x16"
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/favicon-192x192.png"> href="/favicons/favicon-16x16.png"
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/favicon-180x180.png"> />
<link rel="shortcut icon" href="/favicons/favicon.ico"> <link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicons/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="48x48"
href="/favicons/favicon-48x48.png"
/>
<link
rel="icon"
type="image/png"
sizes="96x96"
href="/favicons/favicon-96x96.png"
/>
<link
rel="icon"
type="image/png"
sizes="192x192"
href="/favicons/favicon-192x192.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/favicons/favicon-180x180.png"
/>
<link rel="shortcut icon" href="/favicons/favicon.ico" />
<!-- Android Chrome --> <!-- Android Chrome -->
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/favicon-192x192.png"> <link
<link rel="icon" type="image/png" sizes="512x512" href="/favicons/favicon-512x512.png"> rel="icon"
type="image/png"
sizes="192x192"
href="/favicons/favicon-192x192.png"
/>
<link
rel="icon"
type="image/png"
sizes="512x512"
href="/favicons/favicon-512x512.png"
/>
<!-- PWA --> <!-- PWA -->
<link rel="manifest" href="/manifest.json"> <link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#2a1a5e"> <meta name="theme-color" content="#2a1a5e" />
<link rel="stylesheet" href="/styles.css"> <link rel="stylesheet" href="/styles.css" />
</head> </head>
<body> <body>
<div class="container"> <div class="container fade-in">
<h1> <h1 class="slide-down">
<span class="icon"> <span class="icon">
<img src="/icon.svg" alt="krzak.org" /> <img src="/icon.svg" alt="krzak.org" />
</span> </span>
Krzak.org Krzak.org
</h1> </h1>
<p>Hi, welcome to krzak.org</p> <p class="slide-down">Hi, welcome to krzak.org</p>
<ul> <ul>
<li> <li class="slide-up" style="animation-delay: 0.1s">
<a href="https://fedi.krzak.org"> <a href="https://fedi.krzak.org">
<strong>Fediverse</strong> <strong>Fediverse</strong>
<span>Sharkey</span> <span>Sharkey</span>
</a> </a>
</li> </li>
<li> <li class="slide-up" style="animation-delay: 0.15s">
<a href="https://mail.krzak.org"> <a href="https://mail.krzak.org">
<strong>Mail</strong> <strong>Mail</strong>
<span>Mailu</span> <span>Mailu</span>
</a> </a>
</li> </li>
<li> <li class="slide-up" style="animation-delay: 0.2s">
<a href="https://music.krzak.org"> <a href="https://music.krzak.org">
<strong>Music</strong> <strong>Music</strong>
<span>Navidrome</span> <span>Navidrome</span>
</a> </a>
</li> </li>
<li> <li class="slide-up" style="animation-delay: 0.25s">
<a href="https://mu.krzak.org"> <a href="https://mu.krzak.org">
<strong>Music Upload</strong> <strong>Music Upload</strong>
</a> </a>
</li> </li>
<li> <li class="slide-up" style="animation-delay: 0.3s">
<a href="https://git.krzak.org"> <a href="https://git.krzak.org">
<strong>Git</strong> <strong>Git</strong>
<span>Gitea</span> <span>Gitea</span>
</a> </a>
</li> </li>
<li> <li class="slide-up" style="animation-delay: 0.35s">
<a href="/contact.html"> <a href="/contact.html">
<strong>Contact</strong> <strong>Contact</strong>
</a> </a>
</li> </li>
</ul> </ul>
<p>If you want an account on any of these, want to suggest something new or get a subdomain, just message me</p> <p class="fade-in" style="animation-delay: 0.4s">
If you want an account on any of these, want to suggest something new or
get a subdomain, just message me
</p>
</div> </div>
<!-- Back to top button -->
<button
id="back-to-top"
class="back-to-top"
aria-label="Back to top"
title="Back to top"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="18 15 12 9 6 15"></polyline>
</svg>
</button>
<script src="/refresh.js"></script> <script src="/refresh.js"></script>
<script src="/animations.js"></script>
</body> </body>
</html> </html>

View File

@@ -1,61 +1,55 @@
(function () { (function () {
// Configuration
const SSE_PORT = 8765; const SSE_PORT = 8765;
const RECONNECT_DELAY = 5000; // 5 seconds const RECONNECT_DELAY = 5000; // miliseconds
let eventSource = null; let eventSource = null;
let reconnectTimer = null; let reconnectTimer = null;
function connect() { function connect() {
// Clear any existing reconnect timer
if (reconnectTimer) { if (reconnectTimer) {
clearTimeout(reconnectTimer); clearTimeout(reconnectTimer);
reconnectTimer = null; reconnectTimer = null;
} }
// Close existing connection
if (eventSource) { if (eventSource) {
eventSource.close(); eventSource.close();
} }
// Connect to SSE server
const url = `${window.location.protocol}//${window.location.hostname}:${SSE_PORT}/events`; const url = `${window.location.protocol}//${window.location.hostname}:${SSE_PORT}/events`;
eventSource = new EventSource(url); eventSource = new EventSource(url);
eventSource.onmessage = function (event) { eventSource.onmessage = function (event) {
try { try {
const data = JSON.parse(event.data); const data = JSON.parse(event.data);
if (data.type === 'reload') { if (data.type === "reload") {
console.log('Repository updated, reloading page...'); console.log("Repository updated, reloading page...");
// Hard reload to bypass cache // Hard reload to bypass cache
window.location.reload(true); window.location.reload(true);
} }
} catch (e) { } catch (e) {
console.error('Error parsing SSE message:', e); console.error("Error parsing SSE message:", e);
} }
}; };
eventSource.onerror = function (error) { eventSource.onerror = function (error) {
console.log('SSE connection error, will reconnect...'); console.log("SSE connection error, will reconnect...");
eventSource.close(); eventSource.close();
// Attempt to reconnect after delay // Attempt to reconnect
reconnectTimer = setTimeout(connect, RECONNECT_DELAY); reconnectTimer = setTimeout(connect, RECONNECT_DELAY);
}; };
eventSource.onopen = function () { eventSource.onopen = function () {
console.log('Connected to auto-refresh service'); console.log("Connected to auto-refresh service");
}; };
} }
// Start connection when page loads if (document.readyState === "loading") {
if (document.readyState === 'loading') { document.addEventListener("DOMContentLoaded", connect);
document.addEventListener('DOMContentLoaded', connect);
} else { } else {
connect(); connect();
} }
// Cleanup on page unload window.addEventListener("beforeunload", function () {
window.addEventListener('beforeunload', function() {
if (eventSource) { if (eventSource) {
eventSource.close(); eventSource.close();
} }

View File

@@ -16,6 +16,10 @@
box-sizing: border-box; box-sizing: border-box;
} }
html {
scroll-behavior: smooth;
}
body { body {
background: linear-gradient( background: linear-gradient(
var(--bg-gradient-1), var(--bg-gradient-1),
@@ -130,6 +134,24 @@ li a {
gap: 12px; gap: 12px;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
touch-action: manipulation; touch-action: manipulation;
position: relative;
overflow: hidden;
}
li a::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(244, 162, 97, 0.1),
transparent
);
transition: left 0.5s ease;
} }
li a:active { li a:active {
@@ -160,12 +182,100 @@ br {
content: ""; content: "";
} }
/* Back to top button */
.back-to-top {
position: fixed;
bottom: 24px;
right: 24px;
width: 48px;
height: 48px;
border-radius: 50%;
background: var(--link-bg);
border: 1px solid var(--container-border);
color: var(--link-color);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
z-index: 1000;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.3);
}
.back-to-top.visible {
opacity: 1;
visibility: visible;
}
.back-to-top:hover {
background: var(--link-hover-bg);
border-color: var(--link-hover-border);
transform: translateY(-2px);
}
.back-to-top:active {
transform: translateY(0);
}
/* Animations */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in {
animation: fadeIn 0.6s ease-out forwards;
}
.slide-down {
animation: slideDown 0.6s ease-out forwards;
}
.slide-up {
animation: slideUp 0.6s ease-out forwards;
opacity: 0;
}
@media (hover: hover) { @media (hover: hover) {
li a:hover { li a:hover {
background-color: var(--link-hover-bg); background-color: var(--link-hover-bg);
border-color: var(--link-hover-border); border-color: var(--link-hover-border);
transform: scale(1.02); transform: scale(1.02);
} }
li a:hover::before {
left: 100%;
}
} }
@media (min-width: 768px) { @media (min-width: 768px) {
@@ -209,11 +319,29 @@ br {
li a span { li a span {
font-size: 0.85rem; font-size: 0.85rem;
} }
.back-to-top {
bottom: 16px;
right: 16px;
width: 44px;
height: 44px;
}
} }
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
* { * {
animation: none !important; animation: none !important;
transition: none !important; transition: none !important;
} }
.fade-in,
.slide-down,
.slide-up {
opacity: 1 !important;
transform: none !important;
}
} }