project component

This commit is contained in:
liyunze 2025-06-20 12:24:01 +10:00
parent d6b10ca360
commit cb53ad26f4
4 changed files with 311 additions and 327 deletions

View file

@ -0,0 +1,123 @@
---
import { Image } from "astro:assets";
interface Tag {
text: string;
textColor: string;
bgColor: string;
}
interface Props {
image: ImageMetadata;
alt: string;
href: string;
title: string;
description: string;
label?: string;
tags?: Tag[];
}
const {
image,
alt,
href,
title,
description,
label = "View Repository",
tags = [],
} = Astro.props;
---
<div
class="flex h-fit w-full flex-col justify-center px-10 lg:flex-row lg:px-20"
>
<div
class="image-container relative mb-5 flex aspect-video w-full [perspective:200px] lg:mr-5 lg:mb-0 lg:ml-auto lg:w-1/2"
>
<Image
src={image}
alt={alt}
class=`absolute max-w-full
aspect-video
top-1/2 left-1/2
[transform:rotateY(5deg)_rotateX(0deg)_translateZ(-50px)_translateX(-45%)_translateY(-50%)] opacity-40
border-2 border-solid border-white rounded-xl`
width="700"
/>
<Image
src={image}
alt={alt}
width="700"
class=`absolute max-w-full
aspect-video
top-1/2 left-1/2
[transform:rotateY(5deg)_rotateX(0deg)_translateZ(-50px)_translateX(-43%)_translateY(-52%)] opacity-100
border-2 border-solid border-white rounded-xl`
/>
<div
class="visit-div absolute top-1/2 left-1/2 aspect-video w-[700px] max-w-full [transform:translateX(-50%)_translateY(-50%)] rounded-xl border-2 border-solid border-white bg-[rgba(0,0,0,0.5)] opacity-0"
>
<a
href={href}
target="_blank"
class="absolute top-1/2 left-1/2 hidden [transform:translateX(-50%)_translateY(-50%)] rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500 lg:block"
>{label}</a
>
</div>
</div>
<div class="mb-10 flex items-center justify-center lg:hidden">
<a
href={href}
target="_blank"
class="rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500"
>{label}</a
>
</div>
<div
class="flex h-fit w-full flex-col items-center justify-center lg:h-[340px] lg:w-1/2 lg:items-start lg:px-10"
>
<h2 class="mb-5 text-center text-3xl font-bold lg:text-left">
{title}
</h2>
<p
class="max-w-lg text-center text-xl text-balance lg:max-w-none lg:text-left"
>
{description}
</p>
<div
class="mt-5 flex w-full flex-row flex-wrap justify-center lg:justify-start"
>
{
tags.map((tag) => (
<div
class="my-1 mr-1 w-fit rounded-full px-3 py-1 transition-colors duration-300"
style={`
background-color: ${tag.bgColor || "black"};
color: ${tag.textColor || "white"};
`}
>
{tag.text}
</div>
))
}
</div>
</div>
</div>
<style>
.image-container img {
transition: transform 0.5s ease-in-out;
}
@media (min-width: 1025px) {
.image-container:hover > img {
transform: rotateY(0deg) rotateX(0deg) translateZ(0px)
translateX(-50%) translateY(-50%);
}
.image-container:hover > .visit-div {
opacity: 100%;
transition: opacity 0.3s ease-in-out;
transition-delay: 0.3s;
}
}
</style>

View file

@ -0,0 +1,121 @@
---
import { Image } from "astro:assets";
interface Tag {
text: string;
textColor: string;
bgColor: string;
}
interface Props {
image: ImageMetadata;
alt: string;
href: string;
title: string;
description: string;
label?: string;
tags?: Tag[];
}
const {
image,
alt,
href,
title,
description,
label = "View Repository",
tags,
} = Astro.props;
---
<div
class="mt-10 flex h-fit w-full flex-col-reverse justify-center px-10 lg:flex-row lg:px-16"
>
<div
class="flex h-fit w-full flex-col items-center justify-center lg:h-[340px] lg:w-1/2 lg:items-end lg:px-10"
>
<h2 class="mb-5 text-center text-3xl font-bold lg:text-right">
{title}
</h2>
<p
class="max-w-lg text-center text-xl text-balance lg:max-w-none lg:text-right"
>
{description}
</p>
<div
class="mt-5 flex w-full flex-row flex-wrap justify-center lg:justify-end"
>
{
tags?.map((tag) => (
<div
class="my-1 mr-1 w-fit rounded-full px-3 py-1 transition-colors duration-300"
style={`
background-color: ${tag.bgColor || "black"};
color: ${tag.textColor || "white"};
`}
>
{tag.text}
</div>
))
}
</div>
</div>
<div class="mb-10 flex items-center justify-center lg:hidden">
<a
href={href}
target="_blank"
class="rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500"
>{label}</a
>
</div>
<div
class="image-container relative mb-5 flex aspect-video w-full [perspective:200px] lg:mr-5 lg:mb-0 lg:ml-auto lg:w-1/2"
>
<Image
src={image}
alt={alt}
class=`absolute max-w-full
top-1/2 left-1/2 [transform:translateX(-48%)_translateY(-48%)_translateZ(-50px)_rotateY(-3deg)] opacity-40
border-2 border-solid border-white rounded-xl`
`
width="700"
/>
<Image
src={image}
alt={alt}
width="700"
class=`absolute max-w-full
top-1/2 left-1/2
[transform:translateX(-50%)_translateY(-50%)_translateZ(-50px)_rotateY(-3deg)] opacity-100
border-2 border-solid border-white rounded-xl`
/>
<div
class="visit-div absolute top-1/2 left-1/2 aspect-video w-[700px] max-w-full [transform:translateX(-50%)_translateY(-50%)] rounded-xl border-2 border-solid border-white bg-[rgba(0,0,0,0.5)] opacity-0"
>
<a
href="https://github.com/liyunze-coding/TwitchPlaysX"
target="_blank"
class="absolute top-1/2 left-1/2 hidden [transform:translateX(-50%)_translateY(-50%)] rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500 lg:block"
>{label}</a
>
</div>
</div>
</div>
<style>
.image-container img {
transition: transform 0.5s ease-in-out;
}
@media (min-width: 1025px) {
.image-container:hover > img {
transform: rotateY(0deg) rotateX(0deg) translateZ(0px)
translateX(-50%) translateY(-50%);
}
.image-container:hover > .visit-div {
opacity: 100%;
transition: opacity 0.3s ease-in-out;
transition-delay: 0.3s;
}
}
</style>

View file

@ -1,9 +1,10 @@
--- ---
import TaskWidget from "./TaskWidget.svelte"; import TaskWidget from "./TaskWidget.svelte";
import { Image } from "astro:assets";
import CoworkingGuide from "../images/projects/coworking-guide.webp"; import CoworkingGuide from "../images/projects/coworking-guide.webp";
import Wnrs from "../images/projects/wnrs.webp"; import Wnrs from "../images/projects/wnrs.webp";
import TwitchPlays from "../images/projects/twitchplays.webp"; import TwitchPlays from "../images/projects/twitchplays.webp";
import ProjectLeft from "./ProjectLeft.astro";
import ProjectRight from "./ProjectRight.astro";
--- ---
<div <div
@ -11,83 +12,31 @@ import TwitchPlays from "../images/projects/twitchplays.webp";
class="flex h-fit flex-col items-center [perspective:1000px]" class="flex h-fit flex-col items-center [perspective:1000px]"
> >
<div class="w-full max-w-[1440px]"> <div class="w-full max-w-[1440px]">
<div <ProjectLeft
class="flex h-fit w-full flex-col justify-center px-10 lg:flex-row lg:px-20" image={CoworkingGuide}
>
<div
class="image-container relative mb-5 flex aspect-video w-full [perspective:200px] lg:mr-5 lg:mb-0 lg:ml-auto lg:w-1/2"
>
<Image
src={CoworkingGuide}
alt="coworking guide" alt="coworking guide"
class=`absolute max-w-full
top-1/2 left-1/2
[transform:rotateY(5deg)_rotateX(0deg)_translateZ(-50px)_translateX(-45%)_translateY(-50%)] opacity-40
border-2 border-solid border-white rounded-xl`
width="700"
/>
<Image
src={CoworkingGuide}
alt="coworking guide"
width="700"
class=`absolute max-w-full
top-1/2 left-1/2
[transform:rotateY(5deg)_rotateX(0deg)_translateZ(-50px)_translateX(-43%)_translateY(-52%)] opacity-100
border-2 border-solid border-white rounded-xl`
/>
<div
class="visit-div absolute top-1/2 left-1/2 aspect-video w-[700px] max-w-full [transform:translateX(-50%)_translateY(-50%)] rounded-xl border-2 border-solid border-white bg-[rgba(0,0,0,0.5)] opacity-0"
>
<a
href="https://coworking-guide.vercel.app/" href="https://coworking-guide.vercel.app/"
target="_blank" title="Coworking Guide"
class="absolute top-1/2 left-1/2 hidden [transform:translateX(-50%)_translateY(-50%)] rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500 lg:block" label="Visit Site"
>Visit site</a description="A guide to coworking streams for streamers, covers wide range of topics from tips on how to get started with setting up stream to how to grow your audience!"
> tags={[
</div> {
</div> text: "Astro",
<div class="mb-10 flex items-center justify-center lg:hidden"> bgColor: "white",
<a textColor: "black",
href="https://coworking-guide.vercel.app/" },
target="_blank" {
class="rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500" text: "TypeScript",
>View repository</a bgColor: "#3178C6",
> textColor: "white",
</div> },
<div {
class="flex h-fit w-full flex-col items-center justify-center lg:h-[340px] lg:w-1/2 lg:items-start lg:px-10" text: "Markdown",
> bgColor: "black",
<h2 class="mb-5 text-center text-3xl font-bold lg:text-left"> textColor: "white",
Coworking Guide },
</h2> ]}
<p />
class="max-w-lg text-center text-xl text-balance lg:max-w-none lg:text-left"
>
A guide to coworking streams for streamers, covers wide
range of topics from tips on how to get started with setting
up stream to how to grow your audience!
</p>
<div
class="mt-5 flex w-full flex-row flex-wrap justify-center lg:justify-start"
>
<div
class="my-1 mr-1 w-fit rounded-full bg-white px-3 py-1 text-black transition-colors duration-300"
>
Astro
</div>
<div
class="my-1 mr-1 w-fit rounded-full bg-[#3178C6] px-3 py-1 text-white transition-colors duration-300"
>
TypeScript
</div>
<div
class="my-1 mr-1 w-fit rounded-full bg-black px-3 py-1 text-white transition-colors duration-300"
>
Markdown
</div>
</div>
</div>
</div>
<div <div
class="mt-10 flex h-fit w-full flex-col-reverse justify-center px-10 lg:flex-row lg:px-16" class="mt-10 flex h-fit w-full flex-col-reverse justify-center px-10 lg:flex-row lg:px-16"
> >
@ -136,154 +85,48 @@ import TwitchPlays from "../images/projects/twitchplays.webp";
<TaskWidget client:visible /> <TaskWidget client:visible />
</div> </div>
<div <ProjectLeft
class="mt-5 flex h-fit w-full flex-col justify-center px-10 lg:mt-0 lg:flex-row lg:px-20" image={Wnrs}
> alt="We're not really strangers"
<div
class="image-container relative mb-5 flex aspect-video w-full [perspective:200px] lg:mr-5 lg:mb-0 lg:ml-auto lg:w-1/2"
>
<Image
src={Wnrs}
alt="Hex Guess"
class=`absolute max-w-full
top-1/2 left-1/2
[transform:rotateY(5deg)_rotateX(0deg)_translateZ(-50px)_translateX(-45%)_translateY(-50%)] opacity-40
border-2 border-solid border-white rounded-xl
aspect-video`
width="700"
/>
<Image
src={Wnrs}
alt="Hex Guess"
width="700"
class=`absolute max-w-full
top-1/2 left-1/2
[transform:rotateY(5deg)_rotateX(0deg)_translateZ(-50px)_translateX(-43%)_translateY(-52%)] opacity-100
border-2 border-solid border-white rounded-xl
aspect-video`
/>
<div
class="visit-div absolute top-1/2 left-1/2 aspect-video w-[700px] max-w-full [transform:translateX(-50%)_translateY(-50%)] rounded-xl border-2 border-solid border-white bg-[rgba(0,0,0,0.5)] opacity-0"
>
<a
href="https://liyunze-coding.github.io/wnrs/" href="https://liyunze-coding.github.io/wnrs/"
target="_blank" label="Visit Site"
class="absolute top-1/2 left-1/2 hidden [transform:translateX(-50%)_translateY(-50%)] rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500 lg:block" title="We're not really strangers"
>Visit site</a description="Otherwise abbreviated as 'WNRS', this is a digitaladaptation of the popular card game designed to foster meaningful connections through engaging questions and prompts."
> tags={[
</div> {
</div> text: "React",
<div class="mb-10 flex items-center justify-center lg:hidden"> bgColor: "var(--color-react)",
<a textColor: "black",
href="https://hex-guess.vercel.app/" },
target="_blank" {
class="rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500" text: "TypeScript",
>View repository</a bgColor: "var(--color-typescript)",
> textColor: "white",
</div> },
<div ]}
class="flex h-fit w-full flex-col items-center justify-center lg:h-[340px] lg:w-1/2 lg:items-start lg:px-10" />
> <ProjectRight
<h2 class="mb-5 text-center text-3xl font-bold"> image={TwitchPlays}
We're Not Really Strangers alt="Twitch Plays X"
</h2> href="https://github.com/liyunze-coding/TwitchPlaysX"
<p title="Twitch Plays X"
class="max-w-lg text-center text-xl text-balance lg:max-w-none lg:text-left" description={`Allow Twitch chatters to play games such as Pokemon!
>
Otherwise abbreviated as "WNRS", this is a digital
adaptation of the popular card game designed to foster
meaningful connections through engaging questions and
prompts.
</p>
<div
class="mt-5 flex w-full flex-row flex-wrap justify-center lg:justify-start"
>
<div
class="bg-react my-1 mr-1 w-fit rounded-full px-3 py-1 text-black transition-colors duration-300"
>
React
</div>
<div
class="bg-typescript my-1 mr-1 w-fit rounded-full px-3 py-1 text-white transition-colors duration-300"
>
Typescript
</div>
</div>
</div>
</div>
<div
class="mt-10 flex h-fit w-full flex-col-reverse justify-center px-10 lg:flex-row lg:px-16"
>
<div
class="flex h-fit w-full flex-col items-center justify-center lg:h-[340px] lg:w-1/2 lg:items-end lg:px-10"
>
<h2 class="mb-5 text-center text-3xl font-bold lg:text-right">
Twitch Plays X
</h2>
<p
class="max-w-lg text-center text-xl text-balance lg:max-w-none lg:text-right"
>
Allow Twitch chatters to play games such as Pokemon!
Chatters can enter messages such as "up up down down left Chatters can enter messages such as "up up down down left
right B A" and the Python program will trigger the right B A" and the Python program will trigger the
corresponding keypresses. corresponding keypresses.`}
</p> tags={[
<div {
class="mt-5 flex w-full flex-row flex-wrap justify-center lg:justify-end" text: "win32API",
> bgColor: "var(--color-win32api)",
<div textColor: "white",
class="bg-python my-1 mr-1 w-fit rounded-full px-3 py-1 text-white transition-colors duration-300" },
> {
Python text: "Python",
</div> bgColor: "var(--color-python)",
<div textColor: "white",
class="bg-win32api my-1 mr-1 w-fit rounded-full px-3 py-1 text-white transition-colors duration-300" },
> ]}
win32API
</div>
</div>
</div>
<div class="mb-10 flex items-center justify-center lg:hidden">
<a
href="https://github.com/liyunze-coding/TwitchPlaysX"
target="_blank"
class="rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500"
>View repository</a
>
</div>
<div
class="image-container relative mb-5 flex aspect-video w-full [perspective:200px] lg:mr-5 lg:mb-0 lg:ml-auto lg:w-1/2"
>
<Image
src={TwitchPlays}
alt="Twitch Plays X"
class=`absolute max-w-full
top-1/2 left-1/2 [transform:translateX(-48%)_translateY(-48%)_translateZ(-50px)_rotateY(-3deg)] opacity-40
border-2 border-solid border-white rounded-xl`
`
width="700"
/> />
<Image
src={TwitchPlays}
alt="Twitch Plays X"
width="700"
class=`absolute max-w-full
top-1/2 left-1/2
[transform:translateX(-50%)_translateY(-50%)_translateZ(-50px)_rotateY(-3deg)] opacity-100
border-2 border-solid border-white rounded-xl`
/>
<div
class="visit-div absolute top-1/2 left-1/2 aspect-video w-[700px] max-w-full [transform:translateX(-50%)_translateY(-50%)] rounded-xl border-2 border-solid border-white bg-[rgba(0,0,0,0.5)] opacity-0"
>
<a
href="https://github.com/liyunze-coding/TwitchPlaysX"
target="_blank"
class="absolute top-1/2 left-1/2 hidden [transform:translateX(-50%)_translateY(-50%)] rounded-xl bg-blue-600 px-5 py-3 font-bold opacity-100 transition-colors duration-300 hover:bg-white hover:text-blue-500 lg:block"
>View repository</a
>
</div>
</div>
</div>
</div> </div>
</div> </div>

View file

@ -1,103 +0,0 @@
---
import Card from "../global/Card.astro";
import Line from "../global/NetworkLine.astro";
---
<div id="Experience" class="h-fit">
<div class="flex flex-col items-center">
<div class="w-[90%] md:w-[600px]">
<Line height="50px" />
<div class="mx-auto w-[90%] md:w-[600px]">
<Card primaryColor="#9D76C1">
<div class="px-8 py-8">
<div class="justify-left flex w-full flex-col">
<h2 class="text-2xl font-bold">Content Creation</h2>
</div>
<hr class="my-3 w-full" />
<p class="text-left">
Since I was little, I loved watching YouTube videos
and the idea of bringing joy and laughter to a wider
audience. Thus, I began my journey in content
creation through YouTube videos and Twitch
streaming. I typically do coworking & study streams
to keep myself accountable and encourage
productivity amongst viewers. I also do software and
game development streams where I showcase my
workflow.
</p>
<div
class="flex w-full flex-row flex-wrap justify-start"
>
<div
class="my-1 mr-1 w-fit cursor-default rounded-full bg-[#141414] px-3 py-1 text-white transition-colors duration-300 hover:bg-[#141414] hover:text-white md:bg-gray-500"
>
OBS
</div>
<div
class="my-1 mr-1 w-fit cursor-default rounded-full bg-gray-50 px-3 py-1 text-black transition-colors duration-300 hover:bg-gray-50 hover:text-black md:bg-gray-500 md:text-white"
>
DaVinci Resolve
</div>
<div
class="my-1 mr-1 w-fit cursor-default rounded-full bg-purple-500 px-3 py-1 text-white transition-colors duration-300 hover:bg-purple-500 md:bg-gray-500"
>
Twitch
</div>
<div
class="my-1 mr-1 w-fit cursor-default rounded-full bg-[#ff0000] px-3 py-1 text-white transition-colors duration-300 hover:bg-[#ff0000] hover:text-white md:bg-gray-500"
>
YouTube
</div>
</div>
</div>
</Card>
</div>
<Line height="50px" />
<div class="mx-auto w-[90%] md:w-[600px]">
<Card primaryColor="#9D76C1">
<div class="px-8 py-8">
<div class="justify-left flex w-full flex-col">
<h2 class="text-2xl font-bold">
Mobile Development
</h2>
</div>
<hr class="my-3 w-full" />
<p class="text-left">
In my Mobile App Development unit in University, I
am tasked to develop Android apps using Android
Studio. The final app project I had developed was a
LLM-powered quiz app with features such as choosing
your own topics, viewing your question attempt
history afterwards, and upgrading your tier with
Google Pay.
</p>
<p class="text-left">
The marking tutor was impressed with my work, and
offered me to join a research lab because I had good
potential.
</p>
<div
class="mt-5 flex w-full flex-row flex-wrap justify-start"
>
<div
class="my-1 mr-1 w-fit cursor-default rounded-full bg-[#106539] px-3 py-1 text-white transition-colors duration-300 hover:bg-[#106539] hover:text-white md:bg-gray-500"
>
Android
</div>
<div
class="my-1 mr-1 w-fit cursor-default rounded-full bg-[#ED8B00] px-3 py-1 text-white transition-colors duration-300 hover:bg-[#ED8B00] md:bg-gray-500"
>
Java
</div>
<div
class="my-1 mr-1 w-fit cursor-default rounded-full bg-[#7F52FF] px-3 py-1 text-white transition-colors duration-300 hover:bg-[#7F52FF] md:bg-gray-500"
>
Kotlin
</div>
</div>
</div>
</Card>
</div>
</div>
</div>
</div>