194 lines
5.2 KiB
Markdown
Executable file
194 lines
5.2 KiB
Markdown
Executable file
---
|
|
description: words, visual, technicalities.
|
|
extra_css:
|
|
- assets/css/_index.css
|
|
extra_js:
|
|
- assets/js/gsap/gsap.min.js
|
|
- assets/js/gsap/ScrollTrigger.min.js
|
|
hide:
|
|
- toc
|
|
- navigation
|
|
search:
|
|
exclude: true
|
|
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="content">
|
|
<ul class="list">
|
|
<li>gugulet.hu</li>
|
|
<li>Words</li>
|
|
<li>Visuals</li>
|
|
<li>Technicalities</li>
|
|
</ul>
|
|
<div class="fill"></div>
|
|
<div class="right">
|
|
<div class="slide center">
|
|
<img src="assets/media/gugulet.hu-combined-face-1276x1276.webp" alt="1" />
|
|
</div>
|
|
<div class="slide center">
|
|
<img src="assets/media/gugulet.hu-writing-face-1276x1276.webp" alt="2" />
|
|
</div>
|
|
<div class="slide center">
|
|
<img src="assets/media/gugulet.hu-visual-face-1276x1276.webp" alt="3" />
|
|
</div>
|
|
<div class="slide center">
|
|
<img src="assets/media/gugulet.hu-technical-face-1276x1276.webp" alt="4" />
|
|
</div>
|
|
</div>
|
|
</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>
|