123 lines
4.6 KiB
Text
123 lines
4.6 KiB
Text
---
|
|
import annualProjects from "../../data/annualProjects.json";
|
|
import { FaGear } from "react-icons/fa6";
|
|
import { GoArrowDownRight } from "react-icons/go";
|
|
import { IoIosArrowDroprightCircle } from "react-icons/io";
|
|
import { Image } from "astro:assets";
|
|
---
|
|
|
|
<div class="flex gap-[1.5vw] h-[50vh]">
|
|
{
|
|
Object.entries(annualProjects).map(([title, project], index) => (
|
|
<a
|
|
href={project.url || "#"}
|
|
class={`project-card group relative flex-1 rounded-[1.5vw] overflow-hidden transition-all duration-500 ease-in-out md:hover:flex-[2] cursor-pointer ${index === 0 ? "expanded" : ""}`}
|
|
data-project={index + 1}
|
|
target={title === "Supercomputing" ? "_blank" : "_self"}
|
|
>
|
|
<Image
|
|
src={project.image}
|
|
alt={`${title} Project`}
|
|
width={668}
|
|
height={990}
|
|
class="opacity-70 w-full h-full object-cover rounded-[1.5vw] aspect-[2/3] transition-transform duration-500 ease-in-out md:group-hover:scale-110"
|
|
/>
|
|
<div class="absolute flex items-end bottom-0 left-0 px-[5%] pb-[5%] pt-[17%] bg-gradient-to-b from-transparent to-black via-black rounded-b-[1.5vw] text-white z-10 w-full transition-transform duration-300 md:[.expanded_&]:pb-[5%]">
|
|
<div class="w-full">
|
|
<p class="py-[1.5%] px-[8%] w-fit border-[0.1vw] border-white rounded-full text-nowrap text-[1.2vw] font-light mb-[5%]">
|
|
{title}
|
|
</p>
|
|
<p class="hidden [.expanded_&]:contents transition-all duration-300 overflow-hidden">
|
|
{project.description}
|
|
</p>
|
|
<div class="w-full flex justify-end invisible [.expanded_&]:visible h-0 [.expanded_&]:h-auto">
|
|
<div class="flex items-center text-[1.3vw] [.expanded_&]:mt-[5%]">
|
|
more details
|
|
<IoIosArrowDroprightCircle className="ml-[0.5vw] text-[1.4vw]" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<GoArrowDownRight className="text-[3.2vw] [.expanded_&]:text-[0px] pt-[2%]" />
|
|
</div>
|
|
|
|
<div class="bg-white w-fit rounded-full aspect-square p-[0.5vw] text-ieee-black text-[2vw] absolute top-[3%] right-[5%]">
|
|
<FaGear />
|
|
</div>
|
|
</a>
|
|
))
|
|
}
|
|
</div>
|
|
|
|
<style>
|
|
.project-card {
|
|
background-size: cover;
|
|
background-position: center;
|
|
}
|
|
|
|
.project-card img {
|
|
transition: transform 0.3s ease-in-out;
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
.project-card.expanded {
|
|
flex: 2;
|
|
}
|
|
|
|
.project-card.expanded img {
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
.project-card.expanded p {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
function initializeProjectCards() {
|
|
const projectCards = document.querySelectorAll(".project-card");
|
|
const STORAGE_KEY = "lastExpandedCardIndex";
|
|
|
|
// Function to remove expanded class from all cards
|
|
function removeExpandedFromAll() {
|
|
projectCards.forEach((card) => {
|
|
card.classList.remove("expanded");
|
|
});
|
|
}
|
|
|
|
// Function to expand a card by index
|
|
function expandCard(index: number) {
|
|
if (window.innerWidth >= 768) {
|
|
removeExpandedFromAll();
|
|
projectCards[index]?.classList.add("expanded");
|
|
localStorage.setItem(STORAGE_KEY, index.toString());
|
|
}
|
|
}
|
|
|
|
// Get the last expanded card index from localStorage
|
|
// Prevents bug where the expanded card breaks upon page reload
|
|
const lastExpandedIndex = parseInt(
|
|
localStorage.getItem(STORAGE_KEY) || "0"
|
|
);
|
|
expandCard(lastExpandedIndex);
|
|
|
|
// Add hover listeners to each card
|
|
projectCards.forEach((card, index) => {
|
|
card.addEventListener("mouseenter", () => {
|
|
expandCard(index);
|
|
});
|
|
});
|
|
|
|
// Handle window resize
|
|
window.addEventListener("resize", () => {
|
|
const currentIndex = parseInt(
|
|
localStorage.getItem(STORAGE_KEY) || "0"
|
|
);
|
|
expandCard(currentIndex);
|
|
});
|
|
}
|
|
|
|
initializeProjectCards();
|
|
|
|
document.addEventListener("astro:page-load", initializeProjectCards);
|
|
</script>
|