feat: add resume.pdf button
All checks were successful
Deploy to SFTP Server / build (push) Successful in 41m27s

This commit is contained in:
max_richter 2024-04-08 14:22:36 +02:00
parent e41ef2fceb
commit d1d6867130
12 changed files with 107 additions and 40 deletions

Binary file not shown.

View File

@ -10,14 +10,15 @@ const t = useTranslations(Astro.url);
---
<Card
classes="googley-eye-target relative rounded-diag-md border border-neutral bg-dark grid xs:grid-cols-[250px_1fr] min-h-[180px] sm:h-[180px] mt-8">
classes="googley-eye-target relative rounded-diag-md border border-neutral bg-dark grid xs:grid-cols-[200px_1fr] sm:grid-cols-[300px_1fr] mt-8">
<div
class="image relative h-[130%] self-end items-end flex overflow-hidden order-last xs:order-first">
<div class="relative inline w-1/2 xs:w-full">
class="relative xs:h-full self-end items-end flex order-last xs:order-first">
<div
class="image xs:absolute inline w-1/2 xs:w-full xs:h-[110%] overflow-hidden">
<Image
src={MaxImg}
alt="its mee"
class="object-bottom h-full object-cover"
class="object-bottom h-full object-contain"
hash={false}
maxWidth={700}
loader={false}
@ -31,9 +32,15 @@ const t = useTranslations(Astro.url);
</div>
</div>
<div class="content flex flex-col p-8 pl-4 gap-2 justify-center">
<div class="content flex flex-col p-8 pl-4 gap-3 justify-center">
<h1 class="text-2xl">{t("home.title")}</h1>
<p>{t("home.subtitle")}</p>
<a
class="bg gradient flex items-center border border-neutral gap-2 w-fit p-2 px-4 rounded-2xl"
href="/max-richter-resume.pdf">
{t("resume").toLowerCase()}.pdf
<span class="i-tabler-download w-4 h-4 dark:opacity-50"></span>
</a>
</div>
</Card>

View File

@ -3,6 +3,7 @@
import { writable } from "svelte/store";
import IconSun from "~icons/tabler/Sun";
import IconMoon from "~icons/tabler/Moon";
import { colors } from "@helpers/colors";
let theme = writable("");
@ -10,8 +11,12 @@
document.documentElement.classList.remove("light", "dark");
document.documentElement.classList.add($theme);
localStorage.setItem("theme", $theme);
// @ts-ignore
window["updateBackgroundColor"]?.();
const background = window.getComputedStyle(document.body);
$colors = {
background: background.backgroundColor,
};
}
function toggleTheme() {

View File

@ -2,38 +2,36 @@
import { onMount } from "svelte";
import createFishes from "./fishes/webgl-fishes";
import { Color } from "ogl";
import { rgbToHex } from "@helpers/colors";
import { colors, rgbToHex } from "@helpers/colors";
let canvasBottom: HTMLCanvasElement;
let speed = 0;
let timeOffset = Math.random() * 100000;
let fishCanvasBack: { resize: any; update: any };
let fishCanvasBack: ReturnType<typeof createFishes>;
let render = true;
const color = new Color("#ffffff");
function updateColor(c: string) {
const d = new Color(rgbToHex(c));
color.set(d.r, d.g, d.b);
fishCanvasBack?.resize();
}
$: if ($colors.background) {
updateColor($colors.background);
}
const handleResize = () => {
fishCanvasBack.resize();
render = window.innerWidth > 500;
};
const updateBackgroundColor = () => {
const background = window.getComputedStyle(document.body);
const d = new Color(rgbToHex(background.backgroundColor));
color.set(d.r, d.g, d.b);
fishCanvasBack.resize();
};
let loaded = false;
onMount(async () => {
const background = window.getComputedStyle(document.body);
const d = new Color(rgbToHex(background.backgroundColor));
color.set(d.r, d.g, d.b);
fishCanvasBack = createFishes(canvasBottom, { amount: 100, color });
fishCanvasBack.resize();
@ -45,8 +43,6 @@
render && fishCanvasBack.update(t, timeOffset);
}
loaded = true;
// @ts-ignore
window["updateBackgroundColor"] = updateBackgroundColor;
});
</script>
@ -69,10 +65,10 @@
left: 0px;
z-index: -1;
opacity: 0;
transition: opacity 0.5s;
transition: opacity 4s;
}
canvas.loaded {
opacity: 0.2;
opacity: 0.8;
}
</style>

View File

@ -3,6 +3,7 @@
import { createLeaves, setRotation } from "./leaves";
import { Color } from "ogl";
import { rgbToHex } from "@helpers/colors";
import { colors } from "@helpers/colors";
let canvas: HTMLCanvasElement;
@ -14,17 +15,17 @@
const color = new Color("#000000");
const updateBackgroundColor = () => {
const background = window.getComputedStyle(document.body);
const d = new Color(rgbToHex(background.backgroundColor));
function updateColor(c: string) {
const d = new Color(rgbToHex(c));
color.set(d.r, d.g, d.b);
};
}
$: if ($colors.background) {
updateColor($colors.background);
}
onMount(() => {
updateBackgroundColor();
createLeaves({ canvas, num: 20, minZ: 0, maxZ: 1, color });
// @ts-ignore
window["updateBackgroundColor"] = updateBackgroundColor;
createLeaves({ canvas, num: 40, minZ: 0, maxZ: 1, color });
setTimeout(() => {
loaded = true;
}, 100);
@ -48,10 +49,10 @@
z-index: -1;
pointer-events: none;
opacity: 0;
transition: opacity 2s;
transition: opacity 4s;
}
.loaded {
opacity: 0.2;
opacity: 0.6;
}
</style>

Binary file not shown.

View File

@ -0,0 +1,3 @@
[ZoneTransfer]
ZoneId=3
HostUrl=about:internet

View File

@ -16,6 +16,8 @@ Plantarium ist die Schnittmenge zwischen zwei Dingen die ich sehr faszinierend f
Es ist eine WebApp die es Nutzern ermöglicht Pflanzen zu erstellen und zu exportieren.
Die User legen dabei über ein Node-System fest wie die Pflanze aussieht und Plantarium generiert daraus ein 3D Modell.
<Image src={plantarium_screenshot} alt="Plantarium Screenshot"/>
# Die Anfänge und Herausforderungen
Der erste Prototyp war innerhalb von zwei Wochen intensiver Arbeit fertig und sah ungefähr so aus:
@ -33,6 +35,7 @@ import screenshot_geometry_nodes from "./images/screenshot-geometry-nodes.jpg"
import screenshot_houdini from "./images/screenshot-houdini.jpg"
import screenshot_unreal from "./images/screenshot-unreal.jpg"
import screenshot_davinci from "./images/screenshot-davinci.jpg"
import plantarium_screenshot from "./images/plantarium-screenshot.png"
import Plantarium from "./images/plantarium.png"
import ImageGallery from "@components/ImageGallery.svelte"
@ -40,6 +43,7 @@ import ImageGallery from "@components/ImageGallery.svelte"
<Leaves client:load/>
<ImageSlider title="Erster Prototyp" client:load>
<Image src={page01_0} alt="Stem Page"/>
<Image src={page01_1} alt="Branches page"/>
@ -83,8 +87,6 @@ In der Beispielgrafik haben wir zwei `input-color` nodes die jeweils eine Farbe
Das coole ist das man dieses System sehr generisch gestalten kann und zum beispiel eine `generate-stem`, `generate-branches` oder eine `add-leaves` node programmieren kann. Aufgrund der
<Image src={Plantarium} alt="Plantariums uses nodes to create plants"/>
<ImageSlider title="Beispiele von Node Systemen" client:load>
<Image src={screenshot_geometry_nodes} alt="Blenders uses nodes to create geometry"/>
<Image src={screenshot_houdini} alt="Houdini uses nodes for vfx/simulations"/>

9
src/env.d.ts vendored
View File

@ -1,3 +1,12 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />
/// <reference types="unplugin-icons/types" />
declare global {
interface Window {
colors: import("svelte/store").Writable<{
background: string;
}>
}
}

View File

@ -1,3 +1,5 @@
import { writable } from "svelte/store";
// function to turn css rgb() strings to hex
export function rgbToHex(rgb: string) {
let hex = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
@ -12,3 +14,7 @@ export function rgbToHex(rgb: string) {
.join("")
);
}
export const colors = writable({
background: "#f0f0f0",
});

View File

@ -23,6 +23,7 @@ export const ui = {
'nav.videos': 'Videos',
'nav.photos': 'Photos',
'toc.title': 'Table of Contents',
"resume": "Resume",
},
de: {
"en": "English",
@ -39,6 +40,7 @@ export const ui = {
'nav.projects': 'Projekte',
'nav.videos': 'Videos',
'nav.photos': 'Fotos',
"resume": "Lebenslauf",
'toc.title': 'Inhaltsverzeichnis',
},
} as const;

View File

@ -74,11 +74,44 @@ import "./global.css";
body {
max-width: 700px;
margin: 0 auto;
position: relative;
}
body > * {
main,
header,
footer {
background: var(--background-dark);
padding: 0.5rem 3rem;
}
body::after {
content: "";
position: fixed;
height: 100vh;
width: 200px;
top: 0;
transform: translateX(-100%);
background: red;
background: linear-gradient(
to left,
var(--background-dark),
transparent
);
}
main::before {
content: "";
position: absolute;
top: -200px;
right: -200px;
bottom: -100px;
width: 200px;
background: linear-gradient(
to right,
var(--background-dark),
transparent
);
}
@media (max-width: 700px) {
body > * {
padding: 0.5rem 1rem;
@ -90,10 +123,10 @@ import "./global.css";
<header class="sticky bottom-0 sm:top-0 z-2 order-last sm:order-first">
<Nav />
</header>
<main id="main-content" class="flex flex-col gap-4">
<main id="main-content" class="relative flex flex-col gap-6">
<slot />
</main>
<footer class="px-4 flex gap-8">
<footer class="mx-8 mb-4 mt-2 flex gap-8">
<LanguagePicker />
<a
href="https://git.max-richter.dev/max/website"