240 lines
6.6 KiB
Plaintext
240 lines
6.6 KiB
Plaintext
---
|
|
import { getAllProjectImages } from "@lib/utils";
|
|
|
|
import Paragraph from "@components/Paragraph.astro";
|
|
import TextLink from "@components/TextLink.astro";
|
|
import Token from "@components/Token.astro";
|
|
import { Icon } from "astro-icon/components";
|
|
import { Image } from "astro:assets";
|
|
import type { CollectionEntry } from "astro:content";
|
|
|
|
import { slugify } from "@lib/utils";
|
|
|
|
interface Props {
|
|
project: CollectionEntry<"projects">;
|
|
textOn?: "left" | "right";
|
|
quality?: number;
|
|
class?: string;
|
|
}
|
|
|
|
const {
|
|
project,
|
|
textOn = "left",
|
|
quality = "80",
|
|
class: className,
|
|
...attrs
|
|
} = Astro.props;
|
|
|
|
const images = getAllProjectImages(project);
|
|
|
|
const translateXOptions = [
|
|
"group-hover:translate-x-8",
|
|
"group-hover:translate-x-9",
|
|
"group-hover:translate-x-10",
|
|
"group-hover:translate-x-11",
|
|
"group-hover:translate-x-12",
|
|
"group-hover:translate-x-13",
|
|
"group-hover:translate-x-14",
|
|
"group-hover:translate-x-15",
|
|
"group-hover:translate-x-16",
|
|
"group-hover:translate-x-17",
|
|
"group-hover:translate-x-18",
|
|
"group-hover:translate-x-19",
|
|
"group-hover:translate-x-20",
|
|
"group-hover:translate-x-21",
|
|
"group-hover:translate-x-22",
|
|
"group-hover:translate-x-23",
|
|
"group-hover:translate-x-24",
|
|
"group-hover:-translate-x-8",
|
|
"group-hover:-translate-x-9",
|
|
"group-hover:-translate-x-10",
|
|
"group-hover:-translate-x-11",
|
|
"group-hover:-translate-x-12",
|
|
"group-hover:-translate-x-13",
|
|
"group-hover:-translate-x-14",
|
|
"group-hover:-translate-x-15",
|
|
"group-hover:-translate-x-16",
|
|
"group-hover:-translate-x-17",
|
|
"group-hover:-translate-x-18",
|
|
"group-hover:-translate-x-19",
|
|
"group-hover:-translate-x-20",
|
|
"group-hover:-translate-x-21",
|
|
"group-hover:-translate-x-22",
|
|
"group-hover:-translate-x-23",
|
|
"group-hover:-translate-x-24"
|
|
];
|
|
|
|
const translateYOptions = [
|
|
"group-hover:translate-y-8",
|
|
"group-hover:translate-y-9",
|
|
"group-hover:translate-y-10",
|
|
"group-hover:translate-y-11",
|
|
"group-hover:translate-y-12",
|
|
"group-hover:translate-y-13",
|
|
"group-hover:translate-y-14",
|
|
"group-hover:translate-y-15",
|
|
"group-hover:translate-y-16",
|
|
"group-hover:translate-y-17",
|
|
"group-hover:translate-y-18",
|
|
"group-hover:translate-y-19",
|
|
"group-hover:translate-y-20",
|
|
"group-hover:translate-y-21",
|
|
"group-hover:translate-y-22",
|
|
"group-hover:translate-y-23",
|
|
"group-hover:translate-y-24",
|
|
"group-hover:-translate-y-9",
|
|
"group-hover:-translate-y-10",
|
|
"group-hover:-translate-y-11",
|
|
"group-hover:-translate-y-12",
|
|
"group-hover:-translate-y-13",
|
|
"group-hover:-translate-y-14",
|
|
"group-hover:-translate-y-15",
|
|
"group-hover:-translate-y-16",
|
|
"group-hover:-translate-y-17",
|
|
"group-hover:-translate-y-18",
|
|
"group-hover:-translate-y-19",
|
|
"group-hover:-translate-y-20",
|
|
"group-hover:-translate-y-21",
|
|
"group-hover:-translate-y-22",
|
|
"group-hover:-translate-y-23",
|
|
"group-hover:-translate-y-24"
|
|
];
|
|
|
|
const rotateOptions = [
|
|
"rotate-1",
|
|
"rotate-2",
|
|
"rotate-3",
|
|
"rotate-4",
|
|
"rotate-5",
|
|
"rotate-6",
|
|
"rotate-7",
|
|
"rotate-8",
|
|
"rotate-9",
|
|
"rotate-10",
|
|
"rotate-11",
|
|
"rotate-12",
|
|
"-rotate-1",
|
|
"-rotate-2",
|
|
"-rotate-3",
|
|
"-rotate-4",
|
|
"-rotate-5",
|
|
"-rotate-6",
|
|
"-rotate-7",
|
|
"-rotate-8",
|
|
"-rotate-9",
|
|
"-rotate-10",
|
|
"-rotate-11",
|
|
"-rotate-12"
|
|
];
|
|
|
|
const projectHasBody = project.body && project.body.trim().length > 0;
|
|
const link = `/projects/${slugify(project.data.type)}/${slugify(project.data.slug)}/`;
|
|
---
|
|
|
|
<div
|
|
class:list={["grid grid-cols-1 text-left md:grid-cols-2", className]}
|
|
{...attrs}
|
|
>
|
|
<div
|
|
class:list={[
|
|
"order-1 flex flex-col items-start justify-center py-4",
|
|
textOn === "right" ? "md:order-2" : "md:order-1"
|
|
]}
|
|
>
|
|
<span
|
|
><h2 class="font-header-alt inline-block text-lg font-semibold">
|
|
{
|
|
projectHasBody && (
|
|
<TextLink href={link}>{project.data.title}</TextLink>
|
|
)
|
|
}{!projectHasBody && project.data.title}{
|
|
!project.data.ongoing && (
|
|
<span class="text-sm font-light italic">
|
|
{" "}
|
|
({project.data.date.getFullYear()})
|
|
</span>
|
|
)
|
|
}
|
|
</h2></span
|
|
>
|
|
<h3 class="font-header-alt font-base font-medium">
|
|
{project.data.role}
|
|
</h3>
|
|
<div class="mt-2">
|
|
<Token>{project.data.type}</Token>
|
|
</div>
|
|
{
|
|
project.data.keyFigure && project.data.keyFigure.length > 0 && (
|
|
<div class="mt-2 text-sm">
|
|
{project.data.keyFigure.map((figure) => {
|
|
return (
|
|
<div>
|
|
<span class="font-bold">{figure.title}:</span>
|
|
<span>
|
|
{figure.href && (
|
|
<TextLink href={figure.href}>{figure.name}</TextLink>
|
|
)}
|
|
{!figure.href && figure.name}
|
|
</span>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
)
|
|
}
|
|
<Paragraph
|
|
class:list={["px-0", "my-2", textOn === "right" ? "" : "md:pr-10"]}
|
|
>{project.data.description}</Paragraph
|
|
>
|
|
{
|
|
project.data.externalLinks !== undefined && (
|
|
<span class="relative order-3 ml-auto flex w-full items-start justify-start space-x-2 text-xl">
|
|
{project.data.externalLinks.map((link) => (
|
|
<TextLink
|
|
href={link.href}
|
|
includeExternalLinkIcon={false}
|
|
aria-label={link.name}
|
|
>
|
|
<Icon name={link.icon} />
|
|
</TextLink>
|
|
))}
|
|
</span>
|
|
)
|
|
}
|
|
</div>
|
|
<div
|
|
class:list={[
|
|
"group relative order-2 ml-auto flex h-full min-h-64 w-full items-center justify-center",
|
|
textOn === "right" ? "md:order-1" : "md:order-2"
|
|
]}
|
|
>
|
|
{
|
|
images
|
|
.reverse()
|
|
.map((image, index) => (
|
|
<Image
|
|
id={`hero-image-${index}`}
|
|
class:list={[
|
|
"animate-floaty absolute h-48 w-auto origin-center transform rounded object-cover shadow-lg/50 transition duration-300 ease-in-out md:group-hover:z-30 md:group-hover:scale-130 md:hover:z-40",
|
|
translateXOptions[
|
|
Math.floor(Math.random() * translateXOptions.length)
|
|
],
|
|
translateYOptions[
|
|
Math.floor(Math.random() * translateYOptions.length)
|
|
],
|
|
rotateOptions[Math.floor(Math.random() * rotateOptions.length)]
|
|
]}
|
|
src={image}
|
|
alt=""
|
|
loading="lazy"
|
|
layout="constrained"
|
|
fit="cover"
|
|
height={250}
|
|
style={`animation-delay: -${Math.floor(Math.random() * (12 - 4) + 4)}s; animation-direction: ${Math.random() < 0.5 ? "normal" : "reverse"};`}
|
|
quality={quality}
|
|
/>
|
|
))
|
|
}
|
|
</div>
|
|
</div>
|