Properly implemented the home animation sequence.

This commit is contained in:
g_it 2026-02-04 22:10:31 +01:00
commit 1b3ef37a16
Signed by untrusted user who does not match committer: g_it
GPG key ID: A2B0A7C06A054627
8 changed files with 246 additions and 387 deletions

View file

@ -1,11 +1,10 @@
@import url(_colours.css);
/*****************************
* INDEX
* Styling for index pages.
* CHAPTER
* Styling for chapter pages.
*****************************/
/* Hide all the extra space around the content */
.md-content__inner,
.md-main__inner,
.md-grid,
@ -18,7 +17,6 @@ body,
max-width: none;
}
/* Make the content fill the entire viewing space */
article,
.md-container {
min-height: 100%;
@ -41,13 +39,11 @@ body {
height: 100%;
}
/* Hide the navigation elements and the title of the page */
header,
.md-content .md-typeset h1 {
display: none !important;
}
/* This was creating an annoying space at the top */
article.md-content__inner.md-typeset:before,
article.md-content__inner.md-typeset:after {
content: none;

140
content/assets/css/_home.css Executable file
View file

@ -0,0 +1,140 @@
@import url(_colours.css);
/*****************************
* HOME
* Styling for the homepage.
*****************************/
* {
box-sizing: border-box;
}
.content {
align-items: center;
display: flex;
flex-direction: column;
justify-content: flex-start;
margin: 0 auto;
max-width: 900px;
padding: 0;
position: relative;
width: 100%;
}
.content ul {
align-items: center;
display: flex;
font-size: 30px;
height: 1.4em;
justify-content: center;
left: 50%;
line-height: 1.4em;
list-style: none;
margin: 0 !important;
max-width: 900px;
overflow: visible;
pointer-events: none;
padding: 0;
position: absolute;
text-align: center;
top: 20px;
transform: translateX(-50%);
width: 100%;
z-index: 5;
}
.content ul li {
align-items: center;
box-sizing: border-box;
display: flex;
font-size: calc((min(100vw, 900px)) / 10);
inset: 0;
justify-content: center;
margin: 0;
padding: 0;
pointer-events: auto;
position: absolute;
text-align: center;
white-space: nowrap;
width: 100%;
}
.content ul li a {
text-decoration: none !important;
}
.content ul li:nth-child(2) {
font-family: var(--primary-font);
}
.content ul li:nth-child(3) {
font-family: var(--secondary-font);
}
.content ul li:nth-child(4) {
font-family: var(--tertiary-font);
}
.content .faces {
align-items: center;
flex-grow: 0;
display: flex;
justify-content: center;
min-height: 320px;
margin-top: 0;
position: relative;
width: 100%;
}
.faces .slide {
border-radius: 10px;
left: 50%;
max-width: 600px;
opacity: 0;
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
visibility: hidden;
width: 80%;
z-index: 1;
}
.faces .slide img {
border-radius: 10px;
display: block;
height: auto;
width: 100%;
}
.down-arrow {
animation: flash 1s infinite;
bottom: 20px;
color: var(--secondary-colour);
font-size: 2rem;
left: 50%;
position: fixed;
transform: translateX(-50%);
}
@keyframes flash {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.hero {
align-items: center;
display: flex;
height: 100vh;
justify-content: center;
margin: 0;
overflow: hidden;
padding: 0;
width: 100%;
}

View file

@ -1,10 +1,6 @@
@import url(_colours.css);
@import url(_fonts.css);
@import url(_size.css);
@import url(_loader.css);
@import url(_page-resume.css);
@import url(_hero-text.css);
@import url(_faces.css);
@import url(_media-player.css);

View file

@ -1,213 +0,0 @@
@import url(_colours.css);
@import url("https: //api.fonts.coollabs.io/css2?family=Lato:wght@300;400;700;900&family=Libre+Baskerville&family=DM+Mono:wght@400;500&display=swap");
header,
nav,
footer,
.md-content .md-typeset h1 {
display: none !important;
}
article,
.md-container {
min-height: 100vh;
width: 100%;
margin: 0;
padding: 0;
}
.md-content__inner,
.md-main__inner,
.md-grid,
html,
body,
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.md-grid {
max-width: none;
}
/* This was creating an annoying space at the top */
article.md-content__inner.md-typeset:before,
article.md-content__inner.md-typeset:after {
content: none;
}
body {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: white;
width: 100%;
}
.container {
width: 100%;
height: 100%;
}
.columns {
display: flex;
justify-content: space-between;
width: 100%;
height: 50vh;
}
.top-row {
flex: 1;
min-width: 100vw;
height: 50vh;
display: flex;
flex-direction: row;
justify-content: center;
padding: 5em;
font-family: 'Libre Baskerville', serif;
}
.top-row h2 {
margin-bottom: 0.1em;
font-size: 5vw;
font-weight: 900;
overflow: hidden;
border-right: .15em solid #818589;
white-space: nowrap;
letter-spacing: .05em;
animation:
typing 5s steps(40, end) forwards 2s,
blink-caret 0.75s step-end infinite;
}
@keyframes typing {
from {
width: 0
}
to {
width: 100%
}
}
@keyframes blink-caret {
from,
to {
border-color: transparent;
}
50% {
border-color: #818589;
}
}
.top-row p {
font-size: 3vw;
color: #818589;
}
.top-row * {
text-align: left;
}
/* Image Container Styling */
.image-container {
width: 100%;
height: 33.33vh;
position: relative;
overflow: hidden;
}
.image-container:hover {
filter: invert(50%);
}
.image-container img {
width: 100%;
height: 100%;
object-fit: contain;
}
/* Responsive Design */
@media (max-width: 768px) {
.columns {
flex-direction: column;
}
}
#loader {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #EFE5DC;
display: flex !important;
justify-content: center;
align-items: center;
z-index: 9998;
transition: opacity 1s ease-out, transform 0.5s ease-out;
}
#loader.fade-out {
opacity: 0;
transform: scale(1.1);
}
#loader img {
width: 50px;
height: 50px;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#loading-text {
font-family: Arial, sans-serif;
font-size: 24px;
color: black;
/* Change text color if needed */
animation: pulse 1s ease-in-out infinite;
}
@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
/* Add fade-out animation */
@keyframes fadeOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(1.1);
}
}
.fade-out {
animation: fadeOut 1s ease-out forwards;
}

86
content/assets/js/home.js Executable file
View file

@ -0,0 +1,86 @@
// HOME.js
// Manages the animations on the home page
document.addEventListener('DOMContentLoaded', function () {
// Register the GSAP plugin to use
try { gsap.registerPlugin(ScrollTrigger); } catch (e) { console.warn(e); }
console.clear();
// Lists the assets to use: backgrounds, images, and content
const backgroundPatterns = {
0: `none`,
1: `
repeating-linear-gradient(0deg, rgba(75, 85, 99, 0.08), rgba(75, 85, 99, 0.08) 2px, transparent 2px, transparent 6px),
repeating-linear-gradient(90deg, rgba(107, 114, 128, 0.06), rgba(107, 114, 128, 0.06) 2px, transparent 2px, transparent 6px)
`,
2: `
repeating-linear-gradient(22.5deg, transparent, transparent 2px, rgba(75, 85, 99, 0.06) 2px, rgba(75, 85, 99, 0.06) 3px, transparent 3px, transparent 8px),
repeating-linear-gradient(67.5deg, transparent, transparent 2px, rgba(107, 114, 128, 0.05) 2px, rgba(107, 114, 128, 0.05) 3px, transparent 3px, transparent 8px),
repeating-linear-gradient(112.5deg, transparent, transparent 2px, rgba(55, 65, 81, 0.04) 2px, rgba(55, 65, 81, 0.04) 3px, transparent 3px, transparent 8px),
repeating-linear-gradient(157.5deg, transparent, transparent 2px, rgba(31, 41, 55, 0.03) 2px, rgba(31, 41, 55, 0.03) 3px, transparent 3px, transparent 8px)
`,
3: `
repeating-linear-gradient(0deg, transparent, transparent 19px, rgba(75, 85, 99, 0.08) 19px, rgba(75, 85, 99, 0.08) 20px, transparent 20px, transparent 39px, rgba(75, 85, 99, 0.08) 39px, rgba(75, 85, 99, 0.08) 40px),
repeating-linear-gradient(90deg, transparent, transparent 19px, rgba(75, 85, 99, 0.08) 19px, rgba(75, 85, 99, 0.08) 20px, transparent 20px, transparent 39px, rgba(75, 85, 99, 0.08) 39px, rgba(75, 85, 99, 0.08) 40px),
radial-gradient(circle at 20px 20px, rgba(55, 65, 81, 0.12) 2px, transparent 2px),
radial-gradient(circle at 40px 40px, rgba(55, 65, 81, 0.12) 2px, transparent 2px)
`,
};
const pinSection = document.querySelector(".pin-section");
const list = pinSection?.querySelector(".list");
const listItems = list ? gsap.utils.toArray("li", list) : [];
const slides = pinSection ? gsap.utils.toArray(".slide", pinSection) : [];
// Sets the initial state and settings for the animation
if (!pinSection || listItems.length === 0 || slides.length === 0) {
console.warn("Missing required elements for animation.");
} else {
gsap.set(listItems, { autoAlpha: 0 });
gsap.set(slides, { autoAlpha: 0, display: "none" });
gsap.set(listItems[0], { autoAlpha: 1 });
gsap.set(slides[0], { autoAlpha: 1, display: "block" });
gsap.set(pinSection, { backgroundImage: backgroundPatterns[0], backgroundColor: "white" });
const totalSteps = listItems.length;
const endDistance = totalSteps * 80; // Set the scroll length
const endString = "+=" + endDistance + "%";
const tl = gsap.timeline({
scrollTrigger: {
trigger: pinSection,
start: "top top",
end: endString,
pin: true,
scrub: true
}
});
tl.to({}, { duration: 0.4 });
// The initial fill scale so it represents a single list item
listItems.forEach((item, i) => {
if (i > 0) {
tl.to(item, { autoAlpha: 1, duration: 0.2 }, "+=0.4")
.to(slides[i], { autoAlpha: 1, display: "block", duration: 0.2 }, "<")
.to(listItems[i - 1], { autoAlpha: 0, duration: 0.2 }, "<0.2")
.to(slides[i - 1], { autoAlpha: 0, display: "none", duration: 0.2 }, "<")
// set the background for this step (use a tiny instant tween so ScrollTrigger respects it)
.set(pinSection, { backgroundImage: backgroundPatterns[i] });
}
});
// Ensures the final state stays visible
tl.to(listItems[totalSteps - 1], { autoAlpha: 1, duration: 0.2 }, "+=0.5")
.set(pinSection, { backgroundImage: backgroundPatterns[totalSteps - 1] });
}
// Attach links to pages
const links = ['#', 'https://gugulet.hu/words', 'https://gugulet.hu/visuals', 'https://gugulet.hu/technical'];
document.querySelectorAll('.list li').forEach((item, index) => {
item.innerHTML = `<a href="${links[index]}">${item.innerHTML}</a>`;
});
document.querySelectorAll('.slide').forEach((slide, index) => {
slide.innerHTML = `<a href="${links[index]}">${slide.innerHTML}</a>`;
});
});

View file

@ -1,10 +1,12 @@
---
description: words, visual, technicalities.
description: words, visual, technical.
extra_css:
- assets/css/_index.css
- assets/css/_chapter.css
- assets/css/_home.css
extra_js:
- assets/js/gsap/gsap.min.js
- assets/js/gsap/ScrollTrigger.min.js
- assets/js/home.js
hide:
- toc
- navigation
@ -15,98 +17,18 @@ title: Home
<!-- markdownlint-disable MD033 -->
<style>
* { box-sizing: border-box; }
:root{
--color-surface50: #444;
--color-surface-white: #fff;
--color-shockingly-green: #0ae448;
}
.section {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.content {
width: 100%;
max-width: 1200px;
margin: 0 auto;
display: flex;
padding: 0 10px;
position: relative;
align-items: stretch;
}
.content ul {
font-size: 30px;
color: var(--color-surface-white);
margin: 0;
padding: 0 12px 0 0;
list-style: none;
z-index: 5;
}
.content .fill {
position: absolute;
top: 0;
left: 10px; /* aligns to content padding */
width: 4px;
height: 100%;
background-color: var(--color-shockingly-green);
transform-origin: top left;
z-index: 2;
transform: scaleY(0);
}
.content .right {
flex-grow: 1;
position: relative;
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
}
.right .slide {
position: absolute;
width: 50%;
max-width: 600px;
top: 50%;
transform: translateY(-50%);
right: 1rem;
opacity: 0;
visibility: hidden;
border-radius: 10px;
z-index: 3;
}
.right .slide img {
display: block;
width: 100%;
height: auto;
border-radius: 10px;
}
h3 { margin: 0; font-size: 32px; color: #ddd; }
</style>
<div class="section pin-section">
<div class="hero pin-section">
<div class="content">
<ul class="list">
<li>gugulet.hu</li>
<li>Words</li>
<li>Visuals</li>
<li>Technicalities</li>
<li></li>
<li>words</li>
<li>visuals</li>
<li>technical</li>
</ul>
<div class="fill"></div>
<div class="right">
<div class="faces">
<div class="slide center">
<img src="assets/media/gugulet.hu-combined-face-1276x1276.webp" alt="1" />
<img src="assets/media/gugulet.hu-unedited-face-1276x1276.webp" alt="1" />
</div>
<div class="slide center">
<img src="assets/media/gugulet.hu-writing-face-1276x1276.webp" alt="2" />
@ -121,74 +43,6 @@ title: Home
</div>
</div>
<script>
// Ensure ScrollTrigger is registered
try {
gsap.registerPlugin(ScrollTrigger);
} catch (e) {
console.warn("GSAP or ScrollTrigger not found. Check your local script paths.", e);
}
console.clear();
// Grab the pin-section element (explicitly using single section to match original intent)
const pinSection = document.querySelector(".pin-section");
const list = pinSection?.querySelector(".list");
const fill = pinSection?.querySelector(".fill");
const listItems = list ? gsap.utils.toArray("li", list) : [];
const slides = pinSection ? gsap.utils.toArray(".slide", pinSection) : [];
if (!pinSection || listItems.length === 0 || slides.length === 0) {
console.warn("Missing required elements for animation. Make sure HTML structure matches.");
} else {
// number of items / slides
const totalSteps = listItems.length;
// timeline end distance (adjust multiplier as needed)
const endDistance = totalSteps * 50; // percent per original approach
const endString = "+=" + endDistance + "%";
// timeline with ScrollTrigger pinned to the single pinSection
const tl = gsap.timeline({
scrollTrigger: {
trigger: pinSection,
start: "top top",
end: endString,
pin: true,
scrub: true
// markers: true
}
});
// initial fill scale so it represents a single list item
gsap.set(fill, {
scaleY: 1 / totalSteps,
transformOrigin: "top left"
});
// Build timeline: show each slide, color current list item, dim previous
listItems.forEach((item, i) => {
const prevItem = listItems[i - 1];
if (i === 0) {
// make first item active immediately
gsap.set(item, { color: "#0ae448" });
gsap.set(slides[i], { autoAlpha: 1 });
} else {
// every step advances the timeline by 0.5 (arbitrary pacing chosen to match original)
tl.set(item, { color: "#0ae448" }, 0.5 * i)
.to(slides[i], { autoAlpha: 1, duration: 0.2 }, "<")
.set(prevItem, { color: "#fffce1" }, "<")
.to(slides[i - 1], { autoAlpha: 0, duration: 0.2 }, "<");
}
});
// animate the fill bar to full height across the timeline
tl.to(fill, {
scaleY: 1,
transformOrigin: "top left",
ease: "none",
duration: tl.duration()
}, 0);
}
</script>
<div class="down-arrow" markdown >
:fontawesome-solid-angle-down:
</div>

View file

@ -1,5 +1,5 @@
<div class="footer">
<a href="#">© all rights reserved</a>
<a href="https://www.linkedin.com/in/gugulet-hu/">contact</a>
<a href="https://zensical.org/">made with zensical</a>
<span>© all rights reserved</span>
<span><a href="https://www.linkedin.com/in/gugulet-hu/">contact</a></span>
<span>made with <a href="https://zensical.org/">zensical</a></span>
</div>