mirror of
https://github.com/liyunze-coding/RythonDev.git
synced 2026-09-22 07:44:26 +00:00
updated projects component
This commit is contained in:
parent
09c4c24d77
commit
abbed1d6b4
4 changed files with 146 additions and 139 deletions
|
|
@ -26,6 +26,35 @@ const {
|
|||
} = Astro.props;
|
||||
|
||||
const leftProject = position == "left";
|
||||
const side = leftProject ? "left" : "right";
|
||||
const layers = ["background", "frontfacing"] as const;
|
||||
|
||||
const renderLayer = (
|
||||
src: ImageMetadata,
|
||||
theme: "dark" | "light",
|
||||
layer: (typeof layers)[number],
|
||||
) => {
|
||||
const isBackground = layer === "background";
|
||||
const isLight = theme === "light";
|
||||
|
||||
return {
|
||||
src,
|
||||
class: [
|
||||
"absolute top-1/2 left-1/2 aspect-video max-w-full rounded-xl border-2 border-solid",
|
||||
isLight
|
||||
? "project-image-light hidden border-gray-300"
|
||||
: "project-image-dark border-gray-800",
|
||||
isBackground ? "background-img opacity-40" : "frontfacing-img opacity-100",
|
||||
isBackground && isLight ? "brightness-75" : "",
|
||||
side,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" "),
|
||||
classList: {
|
||||
"has-light-image": !isLight && Boolean(image_light),
|
||||
},
|
||||
};
|
||||
};
|
||||
---
|
||||
|
||||
<div
|
||||
|
|
@ -37,48 +66,34 @@ const leftProject = position == "left";
|
|||
>
|
||||
<slot />
|
||||
{
|
||||
image && alt && (
|
||||
<>
|
||||
image &&
|
||||
layers.map((layer) => {
|
||||
const layerProps = renderLayer(image, "dark", layer);
|
||||
return (
|
||||
<Image
|
||||
src={image}
|
||||
alt={alt}
|
||||
class="project-image-dark background-img absolute top-1/2 left-1/2 aspect-video max-w-full rounded-xl border-2 border-solid border-gray-800 opacity-40"
|
||||
class:list={[
|
||||
leftProject ? "left" : "right",
|
||||
{ "has-light-image": Boolean(image_light) },
|
||||
]}
|
||||
src={layerProps.src}
|
||||
alt={alt ?? ""}
|
||||
width={700}
|
||||
class={layerProps.class}
|
||||
class:list={layerProps.classList}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
{
|
||||
image_light &&
|
||||
layers.map((layer) => {
|
||||
const layerProps = renderLayer(image_light, "light", layer);
|
||||
return (
|
||||
<Image
|
||||
src={image}
|
||||
alt={alt}
|
||||
src={layerProps.src}
|
||||
alt={alt ?? ""}
|
||||
width={700}
|
||||
class="project-image-dark frontfacing-img absolute top-1/2 left-1/2 aspect-video max-w-full rounded-xl border-2 border-solid border-gray-800 opacity-100"
|
||||
class:list={[
|
||||
leftProject ? "left" : "right",
|
||||
{ "has-light-image": Boolean(image_light) },
|
||||
]}
|
||||
class={layerProps.class}
|
||||
class:list={layerProps.classList}
|
||||
/>
|
||||
{image_light && (
|
||||
<>
|
||||
<Image
|
||||
src={image_light}
|
||||
alt={alt}
|
||||
class="project-image-light background-img absolute top-1/2 left-1/2 hidden aspect-video max-w-full rounded-xl border-2 border-solid border-gray-300 opacity-40"
|
||||
class:list={leftProject ? "left" : "right"}
|
||||
width={700}
|
||||
/>
|
||||
<Image
|
||||
src={image_light}
|
||||
alt={alt}
|
||||
width={700}
|
||||
class="project-image-light frontfacing-img absolute top-1/2 left-1/2 hidden aspect-video max-w-full rounded-xl border-2 border-solid border-gray-300 opacity-100"
|
||||
class:list={leftProject ? "left" : "right"}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -62,26 +62,7 @@ import Project from "./Project.astro";
|
|||
endless!`}
|
||||
tags={["HTML", "CSS", "Javascript", "C#"]}
|
||||
>
|
||||
<TaskWidget
|
||||
classList={`
|
||||
widget h-full
|
||||
[perspective:200px] absolute
|
||||
w-full
|
||||
opacity-10
|
||||
top-1/2 left-1/2
|
||||
background-widget right
|
||||
`}
|
||||
client:visible
|
||||
/>
|
||||
<TaskWidget
|
||||
classList={`
|
||||
widget h-full
|
||||
[perspective:200px] absolute
|
||||
frontfacing-widget right
|
||||
top-1/2 left-1/2
|
||||
w-full`}
|
||||
client:visible
|
||||
/>
|
||||
<TaskWidget position="right" client:visible />
|
||||
</Project>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -135,15 +135,20 @@
|
|||
];
|
||||
|
||||
interface Props {
|
||||
classList: string;
|
||||
position?: "left" | "right";
|
||||
}
|
||||
|
||||
let { classList }: Props = $props();
|
||||
let { position = "right" }: Props = $props();
|
||||
const side = $derived(position === "left" ? "left" : "right");
|
||||
</script>
|
||||
|
||||
<div class={`${classList} overflow-hidden`}>
|
||||
<!-- task bot -->
|
||||
<div class="task-widget absolute flex h-full min-h-[50vh] w-full flex-col">
|
||||
{#snippet widgetLayer(layerClass: string, extraClass: string)}
|
||||
<div
|
||||
class={`widget absolute top-1/2 left-1/2 h-full w-full overflow-hidden [perspective:200px] ${layerClass} ${side} ${extraClass}`}
|
||||
>
|
||||
<div
|
||||
class="task-widget absolute flex h-full min-h-[50vh] w-full flex-col"
|
||||
>
|
||||
<div
|
||||
class="task-widget-header flex w-full flex-row items-center justify-between
|
||||
rounded-md
|
||||
|
|
@ -202,7 +207,11 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
{@render widgetLayer("background-widget", "opacity-40 brightness-75")}
|
||||
{@render widgetLayer("frontfacing-widget", "opacity-100")}
|
||||
|
||||
<style>
|
||||
:global(html[data-theme="light"]) .task-widget-header {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
tags = [],
|
||||
}: Props = $props();
|
||||
|
||||
const positionLeft: boolean = (() => position == "left")();
|
||||
const positionLeft = $derived(position === "left");
|
||||
const side = $derived(positionLeft ? "left" : "right");
|
||||
|
||||
onMount(() => {
|
||||
const videos = document.querySelectorAll<HTMLVideoElement>(".playable");
|
||||
|
|
@ -63,30 +64,31 @@
|
|||
<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"
|
||||
>
|
||||
{#snippet renderLayer(
|
||||
kind: "image" | "video",
|
||||
layerClass: string,
|
||||
extraClass: string,
|
||||
)}
|
||||
{#if kind === "image"}
|
||||
<img
|
||||
src={image_src}
|
||||
alt={image_alt}
|
||||
class="project-media background-img absolute
|
||||
top-1/2
|
||||
left-1/2 max-w-full rounded-xl border-2
|
||||
border-solid border-gray-800
|
||||
opacity-40
|
||||
{positionLeft ? 'left' : 'right'}"
|
||||
class="project-media absolute top-1/2 left-1/2 max-w-full rounded-xl border-2 border-solid border-gray-800 {layerClass} {extraClass} {side}"
|
||||
width="700"
|
||||
/>
|
||||
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y_media_has_caption -->
|
||||
<video
|
||||
width="700"
|
||||
class="project-media playable frontfacing-vid absolute
|
||||
top-1/2 left-1/2 max-w-full rounded-xl
|
||||
border-2
|
||||
border-solid border-gray-800
|
||||
opacity-100
|
||||
{positionLeft ? 'left' : 'right'}"
|
||||
class="project-media playable absolute top-1/2 left-1/2 max-w-full rounded-xl border-2 border-solid border-gray-800 {layerClass} {extraClass} {side}"
|
||||
>
|
||||
<source src={video_src} type="video/webm" />
|
||||
</video>
|
||||
{/if}
|
||||
{/snippet}
|
||||
|
||||
{@render renderLayer("image", "background-img", "opacity-40 brightness-75")}
|
||||
{@render renderLayer("video", "frontfacing-vid", "opacity-100")}
|
||||
</div>
|
||||
<div
|
||||
class="flex h-fit w-full flex-col items-center justify-center lg:h-[340px] lg:w-1/2 lg:px-10
|
||||
|
|
|
|||
Loading…
Reference in a new issue