Compare commits

..

46 commits
list ... main

Author SHA1 Message Date
d3e11c32e6 fixed header not hiding when wanting to print
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 20s
2025-05-25 00:15:40 +02:00
0c2ab8d93f I think i forgot to include this file lol
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 22s
2025-05-24 23:45:49 +02:00
0925af468e changed source code link
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 20s
2025-05-24 05:17:51 +02:00
e65b6c97c6 removed the scroll thing, because i'm too lazy to continue for a while
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 21s
2025-05-24 05:12:04 +02:00
e3f015d4b3 source code location updated. and something else but too drunk lol
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 21s
2025-05-13 01:41:41 +02:00
f1a8ccd319 updated embed
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 22s
2025-05-13 01:39:34 +02:00
983813020e scroll thingy good. now animation
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 23s
2025-05-13 00:43:47 +02:00
50c08b6b67 progress on scrolling thing
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 17s
2025-05-12 20:44:22 +02:00
71ad89b197 Fixed hamburger and slight layout improvement
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 17s
2025-05-12 20:18:00 +02:00
4bd2b48590 Started on something
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 17s
2025-05-12 20:08:09 +02:00
eaf10d4475 Added deprived theme
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 19s
2025-05-12 19:01:19 +02:00
93b7c5e7c7 slightly better bloat loading
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 17s
2025-05-10 20:53:02 +02:00
d6501f0b3a Hello mr. Would you like some bloat?
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 18s
2025-05-10 20:29:57 +02:00
2291cf927b workflow for signalling rebuild
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 14s
2025-05-04 23:48:32 +02:00
1249e30ec7 get branch name
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 14s
2025-05-04 23:46:55 +02:00
c90e8555da test workflow
All checks were successful
Test / test_service (push) Successful in 0s
2025-05-04 18:20:00 +02:00
abf264544f Zylvester is 2d and 3d artist 2025-04-06 17:46:51 +02:00
18a49a3165 Added zylvester's linkedin 2025-04-06 17:41:18 +02:00
efbaaef915 snorre 2025-04-06 06:23:06 +02:00
062e883afb theme switch button and tooltip 2025-04-06 06:14:24 +02:00
e3f43f86f1 Theme switcher 2025-04-06 06:07:17 +02:00
162158340b faster theme load 2025-04-06 05:32:18 +02:00
68ebf556c4 Loading last theme selected 2025-04-06 05:29:49 +02:00
4b933b7b0e better mobile again 2025-04-06 05:26:39 +02:00
a3daf3cfd5 randomized theme 2025-04-06 05:18:02 +02:00
BOT Alex
a0eaeb15fd All in cozette font 2025-04-06 01:36:50 +02:00
BOT Alex
33b291f3bf Mobile is better now 2025-04-06 01:26:19 +02:00
BOT Alex
2408174b8b Improved main page 2025-04-06 01:21:16 +02:00
BOT Alex
b56ef35802 Added text specifing timezone 2025-04-06 00:37:12 +02:00
BOT Alex
1fe30148f7 Added build timestamp 2025-04-06 00:35:42 +02:00
BOT Alex
379577cc5c Removed ALL errors 2025-04-06 00:17:55 +02:00
BOT Alex
f64ae9f991 deleted vibe coded file 2025-04-05 22:49:57 +02:00
BOT Alex
49c6816d07 Fixed inconsistent navbar 2025-04-05 22:30:16 +02:00
BOT Alex
4fa68a8e7f Migrated to daisyui 5 2025-04-05 22:28:32 +02:00
BOT Alex
2fa0e4ee8e Removed svelte parallax 2025-04-05 21:43:05 +02:00
BOT Alex
2558592d9c Update source code location url 2025-04-05 21:36:02 +02:00
BOT Alex
a5fdd78d4e Svelte 5 update? 2025-04-05 21:35:02 +02:00
2b5da73712 use main branch for build 2025-03-17 01:46:21 +01:00
62f7199a76 Added a WIP disclaimer to website 2025-03-17 01:39:15 +01:00
f27dbcee8c progress on mcus 2025-03-03 11:32:49 +01:00
b1c92296a6 removed about us 2025-03-03 03:31:50 +01:00
f45fc592b8 sync 2025-02-28 09:24:37 +01:00
22cabd41ac Now changes tab tittle on load 2025-02-28 08:38:35 +01:00
fe120609fb Merge branch 'WeGoingBasic' of https://gitea.deprived.dev/Sveskejuice/deprived-main-website into WeGoingBasic 2025-02-27 18:46:39 +01:00
01865b473b Update +page.svelte 2025-02-27 18:46:38 +01:00
Your Name
d025b2432b Update buildscript 2025-02-25 16:04:15 +01:00
357 changed files with 4885 additions and 3008 deletions

View file

@ -0,0 +1,23 @@
name: Rebuild signaller for deprived.dev to rebuild site
on: [push]
jobs:
test_service:
runs-on: native
steps:
- name: Get branch
run: echo "BRANCH=$(echo "${{ gitea.ref }}" | cut -d'/' -f3)" >> $GITHUB_ENV
- name: Signal deprived.dev for rebuild
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
run: |
sshkey=$(mktemp)
trap "rm -rf $sshkey" exit
echo -e $SSH_PRIVATE_KEY > $sshkey
service="build-deprived-website-$BRANCH"
sshargs="-o LogLevel=ERROR -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
echo "Starting systemd oneshot service: $service"
ssh -i $sshkey -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no deprivedbuilder@deprived.dev -t "sudo /run/current-system/sw/bin/systemctl start $service"
echo "Build Log: $(ssh -i $sshkey $sshargs deprivedbuilder@deprived.dev "cat ~/latest_build.log")"

View file

@ -1,66 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Carousel Example</title>
<!-- Include Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<div id="carouselExample" class="carousel slide" data-bs-ride="carousel">
<!-- Indicators -->
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExample" data-bs-slide-to="0" class="active"
aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExample" data-bs-slide-to="1"
aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselExample" data-bs-slide-to="2"
aria-label="Slide 3"></button>
</div>
<!-- Carousel Items -->
<div class="carousel-inner">
<div class="carousel-item active">
<img src="https://via.placeholder.com/800x400" class="d-block w-100" alt="Slide 1">
<div class="carousel-caption d-none d-md-block">
<h5>First Slide</h5>
<p>Description for the first slide.</p>
</div>
</div>
<div class="carousel-item">
<img src="https://via.placeholder.com/800x400" class="d-block w-100" alt="Slide 2">
<div class="carousel-caption d-none d-md-block">
<h5>Second Slide</h5>
<p>Description for the second slide.</p>
</div>
</div>
<div class="carousel-item">
<img src="https://via.placeholder.com/800x400" class="d-block w-100" alt="Slide 3">
<div class="carousel-caption d-none d-md-block">
<h5>Third Slide</h5>
<p>Description for the third slide.</p>
</div>
</div>
</div>
<!-- Controls -->
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExample" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExample" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
<!-- Include Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

22
build.sh Executable file → Normal file
View file

@ -4,28 +4,10 @@
# NODE_ENV is set to production, npm won't install anything # NODE_ENV is set to production, npm won't install anything
unset NODE_ENV unset NODE_ENV
echo "Rebuilding deprived main site"
echo "cwd: ${pwd}"
#rm -rf deprived-main-website
#git clone https://gitea.deprived.dev/Sveskejuice/deprived-main-website.git
git restore .
git clean -fd
git pull git pull
git checkout WeGoingBasic git reset --hard main
echo "Project files up to date. Proceeding to install deps" npm ci
echo "npm config list:"
npm config list
npm cache clean --force
npm i
npm i @sveltejs/adapter-static
npm i @sveltejs/kit
npm i @zerodevx/svelte-img
npm tailwind init
echo "Ready to build, building..." echo "Ready to build, building..."

View file

@ -10,7 +10,12 @@
"sourceMap": true, "sourceMap": true,
"strict": true, "strict": true,
"moduleResolution": "bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true "allowImportingTsExtensions": true,
"paths": {
"@images/*": ["./src/images/*"],
"@src/*": ["./src/*"],
"@static/*": ["./static/*"]
}
} }
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files
// //

2122
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,33 +6,33 @@
"dev": "vite dev", "dev": "vite dev",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --compiler-warnings \"css-unused-selector:ignore,unused-export-let:ignore\" --threshold error",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch" "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch --threshold error"
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-static": "^3.0.1", "@sveltejs/adapter-static": "^3.0.1",
"@sveltejs/kit": "^2.0.0", "@sveltejs/kit": "^2.20.4",
"@sveltejs/vite-plugin-svelte": "^3.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"daisyui": "^4.12.12", "daisyui": "^5.0.12",
"postcss": "^8.4.47",
"sass": "^1.77.4", "sass": "^1.77.4",
"svelte": "^4.2.7", "svelte": "^5.25.7",
"svelte-check": "^3.6.0", "svelte-check": "^3.8.6",
"svelte-highlight": "^7.6.0", "svelte-highlight": "^7.6.0",
"tailwindcss": "^3.4.13", "tailwindcss": "^4.1.3",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"vite": "^5.0.3", "vite": "^5.0.3",
"vite-plugin-svgr": "^4.2.0" "vite-plugin-svgr": "^4.2.0"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@lucide/svelte": "^0.487.0",
"@tailwindcss/vite": "^4.1.3",
"lucide-svelte": "^0.475.0", "lucide-svelte": "^0.475.0",
"svelte-katex": "^0.1.2", "svelte-katex": "^0.1.2",
"svelte-media-queries": "^1.6.2", "svelte-media-queries": "^1.6.2",
"svelte-parallax": "^0.6.0",
"theme-change": "^2.5.0" "theme-change": "^2.5.0"
} }
} }

2502
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

222
src/app.css Normal file
View file

@ -0,0 +1,222 @@
@import "tailwindcss";
@plugin "daisyui";
@plugin "daisyui/theme" {
name: "Deprived";
default: true;
prefersdark: true;
--color-base-100: oklch(14% 0 0);
--color-base-200: oklch(20% 0 0);
--color-base-300: oklch(26% 0 0);
--color-base-content: oklch(97% 0 0);
--color-primary: oklch(72% 0.219 149.579);
--color-primary-content: oklch(98% 0.018 155.826);
--color-secondary: oklch(58% 0.233 277.117);
--color-secondary-content: oklch(96% 0.018 272.314);
--color-accent: oklch(60% 0.25 292.717);
--color-accent-content: oklch(96% 0.016 293.756);
--color-neutral: oklch(20% 0 0);
--color-neutral-content: oklch(98% 0 0);
--color-info: oklch(58% 0.158 241.966);
--color-info-content: oklch(97% 0.013 236.62);
--color-success: oklch(64% 0.2 131.684);
--color-success-content: oklch(98% 0.031 120.757);
--color-warning: oklch(68% 0.162 75.834);
--color-warning-content: oklch(98% 0.026 102.212);
--color-error: oklch(57% 0.245 27.325);
--color-error-content: oklch(97% 0.013 17.38);
--radius-selector: 1rem;
--radius-field: 0.5rem;
--radius-box: 1rem;
--size-selector: 0.25rem;
--size-field: 0.25rem;
--border: 1px;
--depth: 0;
--noise: 0;
}
@plugin "daisyui/theme" {
name: "dark";
color-scheme: "dark";
--color-base-100: oklch(14% 0 0);
--color-base-200: oklch(20% 0 0);
--color-base-300: oklch(26% 0 0);
--color-base-content: oklch(97% 0 0);
--color-primary: oklch(90% 0.182 98.111);
--color-primary-content: oklch(28% 0.066 53.813);
--color-secondary: oklch(84% 0.143 164.978);
--color-secondary-content: oklch(26% 0.051 172.552);
--color-accent: oklch(87% 0.01 258.338);
--color-accent-content: oklch(13% 0.028 261.692);
--color-neutral: oklch(26% 0 0);
--color-neutral-content: oklch(98% 0 0);
--color-info: oklch(71% 0.143 215.221);
--color-info-content: oklch(98% 0.019 200.873);
--color-success: oklch(76% 0.233 130.85);
--color-success-content: oklch(98% 0.031 120.757);
--color-warning: oklch(70% 0.213 47.604);
--color-warning-content: oklch(98% 0.016 73.684);
--color-error: oklch(65% 0.241 354.308);
--color-error-content: oklch(97% 0.014 343.198);
--radius-selector: 0rem;
--radius-field: 0.5rem;
--radius-box: 1rem;
--size-selector: 0.25rem;
--size-field: 0.25rem;
--border: 1px;
--depth: 0;
--noise: 1;
}
@plugin "daisyui/theme" {
name: "pink";
color-scheme: "light";
--color-base-100: oklch(96% 0.015 12.422);
--color-base-200: oklch(94% 0.03 12.58);
--color-base-300: oklch(89% 0.058 10.001);
--color-base-content: oklch(41% 0.159 10.272);
--color-primary: oklch(86% 0.127 207.078);
--color-primary-content: oklch(30% 0.056 229.695);
--color-secondary: oklch(0% 0 0);
--color-secondary-content: oklch(100% 0 0);
--color-accent: oklch(87% 0.169 91.605);
--color-accent-content: oklch(27% 0.077 45.635);
--color-neutral: oklch(51% 0.222 16.935);
--color-neutral-content: oklch(96% 0.015 12.422);
--color-info: oklch(74% 0.16 232.661);
--color-info-content: oklch(29% 0.066 243.157);
--color-success: oklch(77% 0.152 181.912);
--color-success-content: oklch(27% 0.046 192.524);
--color-warning: oklch(75% 0.183 55.934);
--color-warning-content: oklch(26% 0.079 36.259);
--color-error: oklch(70% 0.191 22.216);
--color-error-content: oklch(25% 0.092 26.042);
--radius-selector: 0.25rem;
--radius-field: 0.25rem;
--radius-box: 0.25rem;
--size-selector: 0.25rem;
--size-field: 0.25rem;
--border: 1px;
--depth: 1;
--noise: 0;
}
@plugin "daisyui/theme" {
name: "netherrack";
color-scheme: "dark";
--color-base-100: oklch(25% 0.092 26.042);
--color-base-200: oklch(39% 0.141 25.723);
--color-base-300: oklch(44% 0.177 26.899);
--color-base-content: oklch(93% 0.032 17.717);
--color-primary: oklch(83% 0.128 66.29);
--color-primary-content: oklch(26% 0.079 36.259);
--color-secondary: oklch(82% 0.111 230.318);
--color-secondary-content: oklch(29% 0.066 243.157);
--color-accent: oklch(78% 0.115 274.713);
--color-accent-content: oklch(25% 0.09 281.288);
--color-neutral: oklch(57% 0.245 27.325);
--color-neutral-content: oklch(97% 0.013 17.38);
--color-info: oklch(71% 0.143 215.221);
--color-info-content: oklch(98% 0.019 200.873);
--color-success: oklch(72% 0.219 149.579);
--color-success-content: oklch(98% 0.018 155.826);
--color-warning: oklch(76% 0.188 70.08);
--color-warning-content: oklch(98% 0.022 95.277);
--color-error: oklch(63% 0.237 25.331);
--color-error-content: oklch(97% 0.013 17.38);
--radius-selector: 2rem;
--radius-field: 2rem;
--radius-box: 2rem;
--size-selector: 0.25rem;
--size-field: 0.25rem;
--border: 1px;
--depth: 1;
--noise: 1;
}
@plugin "daisyui/theme" {
name: "green";
color-scheme: "dark";
--color-base-100: oklch(26% 0.065 152.934);
--color-base-200: oklch(39% 0.095 152.535);
--color-base-300: oklch(44% 0.119 151.328);
--color-base-content: oklch(96% 0.044 156.743);
--color-primary: oklch(80% 0.105 251.813);
--color-primary-content: oklch(28% 0.091 267.935);
--color-secondary: oklch(80% 0.105 251.813);
--color-secondary-content: oklch(28% 0.091 267.935);
--color-accent: oklch(89% 0.196 126.665);
--color-accent-content: oklch(27% 0.072 132.109);
--color-neutral: oklch(52% 0.154 150.069);
--color-neutral-content: oklch(98% 0.018 155.826);
--color-info: oklch(78% 0.154 211.53);
--color-info-content: oklch(30% 0.056 229.695);
--color-success: oklch(79% 0.209 151.711);
--color-success-content: oklch(26% 0.065 152.934);
--color-warning: oklch(85% 0.199 91.936);
--color-warning-content: oklch(28% 0.066 53.813);
--color-error: oklch(71% 0.202 349.761);
--color-error-content: oklch(28% 0.109 3.907);
--radius-selector: 0.25rem;
--radius-field: 0.5rem;
--radius-box: 1rem;
--size-selector: 0.25rem;
--size-field: 0.25rem;
--border: 1px;
--depth: 0;
--noise: 1;
}
.bg-grid-100 {
background:
linear-gradient(-90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px),
linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px), #f2f2f2;
background-size:
4px 4px,
4px 4px,
80px 80px,
80px 80px,
80px 80px,
80px 80px,
80px 80px,
80px 80px;
background-color: var(--color-base-100);
}
.bg-grid-200 {
background:
linear-gradient(-90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px),
linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px), #f2f2f2;
background-size:
4px 4px,
4px 4px,
80px 80px,
80px 80px,
80px 80px,
80px 80px,
80px 80px,
80px 80px;
background-color: var(--color-base-200);
}
.bg-grid-300 {
background:
linear-gradient(-90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px),
linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px), #f2f2f2;
background-size:
4px 4px,
4px 4px,
80px 80px,
80px 80px,
80px 80px,
80px 80px,
80px 80px,
80px 80px;
background-color: var(--color-base-300);
}
@media print {
.hide-on-print {
display: none !important;
}
}

View file

@ -1,5 +1,5 @@
<!doctype html> <!doctype html>
<html lang="en" data-theme="Synthwave" style="overflow-x: hidden;"> <html lang="en" data-theme="Deprived" style="overflow-x: hidden;">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="description" content=" <meta name="description" content="
@ -8,11 +8,35 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Change theme for site here --> <!-- Change theme for site here -->
<link rel="stylesheet" href="/stylesheets/main-theme.css" />
<link rel="stylesheet" href="/stylesheets/global.css" /> <link rel="stylesheet" href="/stylesheets/global.css" />
%sveltekit.head% %sveltekit.head%
<script>
let theme = null;
if (typeof localStorage !== 'undefined') {
theme = localStorage.getItem('theme');
}
window.AvailableThemes = ["green", "netherrack", "dark", "pink"];
if (!theme) {
const randomNumber = Math.floor(Math.random() * 4);
console.log("Slecting: " + AvailableThemes[randomNumber]);
document.documentElement.setAttribute('data-theme', AvailableThemes[randomNumber]);
localStorage.setItem('theme', AvailableThemes[randomNumber]);
}
//else {
// console.log("Slecting: " + theme);
// document.documentElement.setAttribute('data-theme', theme);
//}
</script>
</head> </head>
<body style="display: contents">%sveltekit.body%</div> <body style="display: contents">
<div class="inline relative w-full h-full">
%sveltekit.body%
</div>
</body>
</html> </html>

View file

@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

File diff suppressed because one or more lines are too long

View file

@ -11,9 +11,7 @@
version="1.1" version="1.1"
viewBox="0 0 28 20" viewBox="0 0 28 20"
width="28" width="28"
xml:space="preserve" xml:space="preserve"><defs
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><path id="defs1" /><path
d="M 2,4 H 26 C 27.104,4 28,3.104 28,2 28,0.896 27.104,0 26,0 H 2 C 0.896,0 0,0.896 0,2 0,3.104 0.896,4 2,4 Z M 26,8 H 2 c -1.104,0 -2,0.896 -2,2 0,1.104 0.896,2 2,2 h 24 c 1.104,0 2,-0.896 2,-2 0,-1.104 -0.896,-2 -2,-2 z m 0,8 H 2 c -1.104,0 -2,0.896 -2,2 0,1.104 0.896,2 2,2 h 24 c 1.104,0 2,-0.896 2,-2 0,-1.104 -0.896,-2 -2,-2 z" d="M 2,4 H 26 C 27.104,4 28,3.104 28,2 28,0.896 27.104,0 26,0 H 2 C 0.896,0 0,0.896 0,2 0,3.104 0.896,4 2,4 Z M 26,8 H 2 c -1.104,0 -2,0.896 -2,2 0,1.104 0.896,2 2,2 h 24 c 1.104,0 2,-0.896 2,-2 0,-1.104 -0.896,-2 -2,-2 z m 0,8 H 2 c -1.104,0 -2,0.896 -2,2 0,1.104 0.896,2 2,2 h 24 c 1.104,0 2,-0.896 2,-2 0,-1.104 -0.896,-2 -2,-2 z"
id="path1" id="path1"

View file

@ -1,296 +1,313 @@
<!-- If url contains "hideOnPrint" param, then detect if start printing then hide elements --> <!-- If url contains "hideOnPrint" param, then detect if start printing then hide elements -->
<script lang="ts"> <script lang="ts">
import "$lib/app.css"; import "../app.css";
import { fly } from "svelte/transition";
import MediaQuery from "svelte-media-queries";
import { Dices } from "@lucide/svelte";
let hideOnPrint: boolean = $state(false);
import { fly } from 'svelte/transition'; let { children } = $props();
import MediaQuery from 'svelte-media-queries';
export let hideOnPrint: boolean;
import DeprivedLogo from "$lib/images/DeprivedLogo.svelte"; import DeprivedLogo from "$lib/images/DeprivedLogo.svelte";
import HamburgerMenuIcon from "$lib/images/HamburgerMenuIcon.svelte"; import HamburgerMenuIcon from "$lib/images/HamburgerMenuIcon.svelte";
import svelteLogo from "$lib/svelteLogos/svelte-logo.png" const footerCollapseThreshold: string = "1000px";
const headerCollapseThreshold: string = "1000px";
let footerCollapse: boolean;
let isMobile: boolean = $state(false);
const footerCollapseThreshold : string = '1000px'; let navbarHidden: boolean = $state(true);
const headerCollapseThreshold : string = '1000px';
let footerCollapse : boolean;
let isMobile : boolean;
let navbarHidden : boolean = true; function resetNavBar() {
navbarHidden = true;
}
function resetNavBar() { import { afterNavigate } from "$app/navigation";
navbarHidden = true; afterNavigate(() => {
const params = new URLSearchParams(window.location.search);
hideOnPrint = params.get("hideOnPrint") === "1";
console.log(hideOnPrint);
});
import { onMount } from "svelte";
import Zooter from "./comps/Zooter.svelte";
onMount(async () => {
const lock = document.createElement("meta");
lock.name = "darkreader-lock";
document.head.appendChild(lock);
});
function nextTheme() {
let theme: string | null = null;
if (typeof localStorage !== "undefined") {
theme = localStorage.getItem("theme");
} }
import { afterNavigate } from '$app/navigation'; const themesArr = (window as any).AvailableThemes;
afterNavigate(() => { let nextTheme = "dark";
const params = new URLSearchParams(window.location.search); if (
hideOnPrint = params.get('hideOnPrint') === '1'; theme == "null" ||
//console.log(hideOnPrint); theme == "undefined" ||
}); theme == undefined ||
theme == null
) {
} else {
nextTheme = themesArr[(1 - -themesArr.indexOf(theme)) % themesArr.length];
}
import { onMount } from 'svelte'; console.log("Slecting: " + nextTheme);
import { themeChange } from 'theme-change' document.documentElement.setAttribute("data-theme", nextTheme);
onMount(() => { localStorage.setItem("theme", nextTheme);
const lock = document.createElement('meta'); }
lock.name = 'darkreader-lock';
document.head.appendChild(lock);
themeChange(false) // false parameter is required for svelte
});
</script> </script>
{#snippet SwitchThemeButton()}
<div
class="tooltip tooltip-bottom grid place-content-center"
data-tip="Switch theme"
>
<button class="cursor-pointer" onclick={nextTheme}> <Dices /></button>
</div>
{/snippet}
<!-- Detect mobile --> <!-- Detect mobile -->
<MediaQuery query='(max-width: {footerCollapseThreshold})' bind:matches={footerCollapse} /> <MediaQuery
<MediaQuery query='(max-width: {headerCollapseThreshold})' bind:matches={isMobile} /> query="(max-width: {footerCollapseThreshold})"
bind:matches={footerCollapse}
/>
<MediaQuery
query="(max-width: {headerCollapseThreshold})"
bind:matches={isMobile}
/>
<!-- Nav bar --> <!-- Nav bar -->
<div class="bg-base-200 p-0"> <div class=" bg-base-200 p-0">
<header class="{hideOnPrint ? 'hide-on-print' : ''}"> <header class="{hideOnPrint ? 'hide-on-print' : ''} bg-base-300">
<div class="nav-bar pr-4 bg-base-200"> <div class="nav-bar pr-4">
{#if !isMobile} {#if !isMobile}
<div class="desktop"> <div class="desktop">
<a href="/" class="nav-head"> <a href="/" class="nav-head">
<DeprivedLogo Class="fill-base-content p-2" Style="width: 3.5rem; height: auto;"/> <DeprivedLogo
<!-- <h3 id="logo-text">The Deprived Devs</h3> --> Class="fill-base-content p-2"
</a> Style="width: 3.5rem; height: auto;"
<div class="nav-spacer" /> />
<!-- <h3 id="logo-text">The Deprived Devs</h3> -->
</a>
<div class="nav-spacer" />
<!-- <a href="/">Home</a> --> <!-- <a href="/">Home</a> -->
<!-- <a href="/zhen/notes/physics/1?hideOnPrint=1" target="_blank" style="width: 7.5rem;">Notes</a> --> <!-- <a href="/zhen/notes/physics/1?hideOnPrint=1" target="_blank" style="width: 7.5rem;">Notes</a> -->
<a href="/zhen/cv/rev2?hideOnPrint=1" target="_blank" style="width: 7.5rem;">Zhen CV</a>
<a href="/tools" style="width: 7.5rem;">Tools</a> {@render SwitchThemeButton()}
<a href="https://botalex.itch.io/" target="_blank">Games</a>
<!-- <a href="/posts">Blog</a> <a
href="/zhen/cv/rev2?hideOnPrint=1"
target="_blank"
style="width: 7.5rem;">Zhen CV</a
>
<a href="/tools" style="width: 7.5rem;">Tools</a>
<a href="https://botalex.itch.io/" target="_blank">Games</a>
<!-- <a href="/posts">Blog</a>
<a href="/about">About</a> --> <a href="/about">About</a> -->
</div>
{:else}
<div class="collapsed">
<a on:click={resetNavBar} href="/" class="nav-head">
<DeprivedLogo Class="fill-base-content p-2" Style="width: 3.5rem; height: auto;"/>
<!-- <h3 id="logo-text">The Deprived Devs</h3> -->
</a>
<div class="nav-spacer" />
<button id="toggle-nav" on:click={() => navbarHidden = !navbarHidden}>
<HamburgerMenuIcon Class="fill-base-content"/>
</button>
</div>
{#if !navbarHidden}
<div class="nav-list" transition:fly={{ y: -25, duration: 350 }}>
<!-- <a on:click={resetNavBar} href="/">Home</a> -->
<a on:click={resetNavBar} href="https://botalex.itch.io/" target="_blank">Games</a>
<a href="/zhen/cv/rev2?hideOnPrint=1" target="_blank">Zhen's CV</a>
<!-- <a on:click={resetNavBar} href="/posts">Blog</a>
<a on:click={resetNavBar} href="/about">About</a> -->
</div>
{/if}
{/if}
</div> </div>
</header> {:else}
<div class="collapsed shadow-xl">
<!-- Page content --> <a onclick={resetNavBar} href="/" class="nav-head">
<slot /> <DeprivedLogo
Class="fill-base-content p-2"
<!-- About footer --> Style="width: 3.5rem; height: auto;"
<footer class="{hideOnPrint ? 'hide-on-print' : ''}"> />
<div class="about-container"> <!-- <h3 id="logo-text">The Deprived Devs</h3> -->
<div class="credits"> </a>
<span>© 2023-2024</span> <div class="nav-spacer" />
<br> {@render SwitchThemeButton()}
<span>Benjamin Dreyer</span> <div class="px-1"></div>
<br> <button
<span>Oliver Schwenger</span> id="toggle-nav"
<br> onclick={() => {
<span>Sylvester Junge</span> navbarHidden = !navbarHidden;
<br> console.log(navbarHidden);
<span>Snorre Ettrup Altschul</span> }}
<br> >
<span>Zhentao Wei</span> <HamburgerMenuIcon Class="fill-base-content" />
</div> </button>
<div>
<h3><b>About this website</b></h3>
<!-- <a href="/" target="_blank">Recursion</a> -->
<div class="flex justify-center">
This website was made using <a class="grid place-content-center" target="_blank" href="https://kit.svelte.dev/">
<img class="pl-2" src={svelteLogo} style="height: 2rem;" alt="SvelteKit logo"/></a>
</div>
<span>Website <a href="https://gitea.deprived.dev/Sveskejuice/deprived-main-website/src/branch/WeGoingBasic" target="_blank">source code</a></span>
</div>
<div class="contact">
<h3><b>Contact</b></h3>
<a href="mailto:zhen@deprived.dev">zhen@deprived.dev</a>
<div class="mt-2"></div>
<a href="https://discord.gg/awatEEqc3M" target="_blank" class="social">
<!-- <span>Discord</span> -->
<img src="/images/icons/discord.svg" alt="Discord"/>
</a>
</div>
</div> </div>
</footer> {#if !navbarHidden}
<div class="nav-list" transition:fly={{ y: -25, duration: 350 }}>
<!-- <a onclick={resetNavBar} href="/">Home</a> -->
<a
onclick={resetNavBar}
href="https://botalex.itch.io/"
target="_blank">Games</a
>
<a href="/zhen/cv/rev2?hideOnPrint=1" target="_blank">Zhen's CV</a>
<!-- <a onclick={resetNavBar} href="/posts">Blog</a>
<a onclick={resetNavBar} href="/about">About</a> -->
</div>
{/if}
{/if}
</div>
</header>
<!-- Page content -->
{@render children?.()}
<Zooter bind:hideOnPrint />
</div> </div>
<style lang="scss">
/* Nav bar. */
header {
display: flex;
justify-content: center;
}
header a {
text-decoration: none;
}
.nav-bar {
width: 100%;
max-width: 1400px;
}
.desktop {
width: 100%;
display: flex;
gap: 30px;
}
.collapsed {
width: 100%;
display: flex;
}
#toggle-nav {
background: transparent;
border: none;
}
.nav-list {
display: flex;
flex-direction: column;
gap: 10px;
align-items: center;
}
.nav-head {
display: flex;
align-items: center;
gap: 10px;
}
#logo-link {
width: 64px;
aspect-ratio: 1 / 1;
}
#logo-text {
font-size: 24px;
color: oklch(var(--bc));
font-family: var(--title-font);
margin: 0;
min-width: 200px;
}
.nav-spacer {
width: 100%;
}
header a {
display: flex;
align-items: center;
font-size: 22px;
font-family: var(--title-font);
// Text color
color: oklch(var(--bc));
}
/* Footer. */
footer {
margin-top: 50px;
padding: 25px 0;
background-color: oklch(var(--b3));
height: 100%;
display: flex;
justify-content: center;
}
.about-container {
width: 80%;
height: 100%;
color: oklch(var(--bc));
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
& h3 {
font-size: larger;
}
}
.about-container > div {
align-items: center;
text-align: center;
}
.credits {
line-height: 2;
}
.contact {
display: flex;
flex-direction: column;
}
.social {
display: flex;
align-content: center;
gap: 10px;
}
.social > img {
width: 24px;
}
footer h3 {
margin-top: 0px;
color: var(--text2);
}
footer a {
color: var(--text2);
text-decoration-line: underline;
}
a:hover {
filter: brightness(130%);
}
@media print {
.hide-on-print {
display: none;
}
}
</style>
{#if footerCollapse} {#if footerCollapse}
<style> <style>
.about-container { .about-container {
flex-direction: column; flex-direction: column;
justify-content: center !important; justify-content: center !important;
gap: 25px; gap: 25px;
} }
</style> </style>
{/if} {/if}
{#if isMobile} {#if isMobile}
<style> <style>
</style>
</style>
{/if} {/if}
<style lang="scss">
/* Nav bar. */
header {
display: flex;
justify-content: center;
}
header a {
text-decoration: none;
}
.nav-bar {
width: 100%;
max-width: 1400px;
}
.desktop {
width: 100%;
display: flex;
gap: 30px;
}
.collapsed {
width: 100%;
display: flex;
}
#toggle-nav {
background: transparent;
border: none;
}
.nav-list {
display: flex;
flex-direction: column;
gap: 10px;
align-items: center;
}
.nav-head {
display: flex;
align-items: center;
gap: 10px;
}
#logo-link {
width: 64px;
aspect-ratio: 1 / 1;
}
#logo-text {
font-size: 24px;
color: oklch(var(--bc));
font-family: var(--title-font);
margin: 0;
min-width: 200px;
}
.nav-spacer {
width: 100%;
}
header a {
display: flex;
align-items: center;
font-size: 22px;
font-family: var(--title-font);
// Text color
color: oklch(var(--bc));
}
/* Footer. */
footer {
margin-top: 50px;
padding: 25px 0;
background-color: oklch(var(--b3));
height: 100%;
display: flex;
justify-content: center;
}
.about-container {
width: 80%;
height: 100%;
color: oklch(var(--bc));
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
& h3 {
font-size: larger;
}
}
.about-container > div {
align-items: center;
text-align: center;
}
.credits {
line-height: 2;
}
.contact {
display: flex;
flex-direction: column;
}
.social {
display: flex;
align-content: center;
gap: 10px;
}
.social > img {
width: 24px;
}
footer h3 {
margin-top: 0px;
color: var(--text2);
}
footer a {
color: var(--text2);
text-decoration-line: underline;
}
a:hover {
filter: brightness(130%);
}
</style>

View file

@ -6,8 +6,7 @@
import Button from '$lib/IO/Button.svelte'; import Button from '$lib/IO/Button.svelte';
import { ButtonType } from '$lib/IO/ButtonType.ts'; import { ButtonType } from '$lib/IO/ButtonType.ts';
import Timeline from '../comps/timeline/timeline.svelte'; import Timeline from '../comps/timeline/timeline.svelte';
import { Parallax, ParallaxLayer, StickyLayer } from "svelte-parallax"; import { onMount, tick } from 'svelte'
import { tick } from 'svelte'
import PreviewDeprivedLogo from "$lib/images/DeprivedLogo-NoBackground.png"; import PreviewDeprivedLogo from "$lib/images/DeprivedLogo-NoBackground.png";
@ -35,22 +34,28 @@
const mobileThreshold : string = '600px'; // was 1000px. zhen testing const mobileThreshold : string = '600px'; // was 1000px. zhen testing
let mobile : boolean; let mobile : boolean;
onMount(()=> {
let tabTittleElement = window.document.getElementById("TabTittle");
if (tabTittleElement) // Not null
tabTittleElement.innerHTML = "Deprived devs";
});
</script> </script>
<!-- Detect mobile --> <!-- Detect mobile -->
<MediaQuery query='(max-width: {mobileThreshold})' bind:matches={mobile} /> <MediaQuery query='(max-width: {mobileThreshold})' bind:matches={mobile} />
<title>We are the DEPRIVED DEVS</title> <title id="TabTittle">We are the DEPRIVED DEVS</title>
<meta content="We are the deprived devs" property="og:title" /> <meta content="We are the deprived devs" property="og:title" />
<meta content="We collaborate to create game, and hopefully more in the future! Wanna join? Hit us up." property="og:description" /> <meta content="We make everything frontend, backend, games, websites, machine learning, whatever. We're just abunch of nerds, and we love it!" property="og:description" />
<meta content={PreviewDeprivedLogo} property="og:image" /> <meta content={PreviewDeprivedLogo} property="og:image" />
<meta content="#bdd6ee" data-react-helmet="true" name="theme-color" /> <meta content="#bdd6ee" data-react-helmet="true" name="theme-color" />
<div class="pointer-events-auto" style="position: relative; width: 100%; height: 100%; overflow: hidden;"> <div class="pointer-events-auto" style="position: relative; width: 100%; height: 100%; overflow: hidden;">
<img id="backgroundGif" src="{BackgroundVideo}" alt="Background video"/> <img id="backgroundGif" src="{BackgroundVideo}" alt="Background video"/>
<div class="main-title m-auto" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; justify-content: center; align-items: center; gap: 2rem; color: white; padding: 1rem;"> <div class="main-title m-auto cozette" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; justify-content: center; align-items: center; gap: 2rem; color: white; padding: 1rem;">
<h1 style="font-size: {!mobile ? 5 : 3}rem; text-shadow: 0.2rem 0.2rem 1rem rgba(0, 0, 0, 0.9); z-index: 100;"> <h1 style="font-size: {!mobile ? 5 : 3}rem; text-shadow: 0.2rem 0.2rem 1rem rgba(0, 0, 0, 0.9);">
{#if !mobile} {#if !mobile}
Deprived Devs Deprived Devs
{:else} {:else}
@ -67,75 +72,67 @@
</div> </div>
</div> </div>
<div class="flex justify-center w-full px-8 py-4"> <div class="cozette flex flex-col justify-center items-center w-full md:px-8 pt-4">
<div class="grid space-y-5" style="width: 100%; max-width: 21cm;"> <h2 class="text-center" style="font-size: {!mobile ? 3 : 2}rem;">
<h2 class="prose main-title" style="font-size: {!mobile ? 3 : 2}rem;"> Developers
Developers </h2>
</h2> <div class="">
<div class="grid max-lg:grid-cols-1 sm:grid-cols-2 gap-4 p-4 max-lg:px-0 w-full">
<Profile name="Zhen / Alex" tags={["Programmer", "3D artist", "UX Designer"]} isMobile={mobile}> <Profile name="Zhen / Alex" tags={["Programmer", "3D artist", "UX Designer"]} isMobile={mobile}>
<span> <span>
<p>Hi, I am Alex/Zhen, {@html !mobile ? "" : "<br/>"} I'm that chinese guy.</p> <p>Hi, I am Alex/Zhen, {@html !mobile ? "" : "<br/>"} I'm that chinese guy.</p>
<p>Here's my CV: <a href="/zhen/cv/rev2?hideOnPrint=1" style="color:lightblue;">pdf</a></p> <p>Here's my CV: <a href="/zhen/cv/rev2?hideOnPrint=1" style="color:lightblue;">pdf</a></p>
</span> </span>
</Profile> </Profile>
<ProfileSpacer/> <Profile name="Sveske / Benjamin" tags={["Programmer", "Back-end Admin"]} isMobile={mobile}>
<Profile name="Sveske / Benjamin" tags={["Programmer", "Back-end Admin"]} isMobile={mobile}> <span>
<span> <p><span class="inline line-through">Hi, I use Arch, btw. </span> I use NixOS now</p>
<p>Hi, I use Arch, btw.</p> <p><a href="https://www.linkedin.com/in/benjamin-dreyer/" target="_blank" style="color:lightblue;">Linked-in</a></p>
<p><a href="https://www.linkedin.com/in/benjamin-dreyer/" target="_blank" style="color:lightblue;">Linked-in</a></p> </span>
</span> </Profile>
</Profile>
<ProfileSpacer/> <Profile isSnorre={true} tags={["Programmer"]} isMobile={mobile}/>
<Profile isSnorre={true} tags={["Programmer"]} isMobile={mobile}/>
<ProfileSpacer/> <Profile name="Oliver" tags={["Sound/Story","2D Artist", "Programmer"]} isMobile={mobile}>
<Profile name="Oliver" tags={["Sound designer", "Story designer","2D Artist", "Programmer"]} isMobile={mobile}> <span>
<span> <p>Snorre does not get paid.</p>
<p>Snorre does not get paid.</p> <p><a href="https://www.linkedin.com/in/oliver-schwenger-291944278/" target="_blank" style="color:lightblue;">Linked-in</a></p>
<p><a href="https://www.linkedin.com/in/oliver-schwenger-291944278/" target="_blank" style="color:lightblue;">Linked-in</a></p> </span>
</span> </Profile>
</Profile>
<ProfileSpacer/> <Profile name="Kim" tags={["Cinemachine", "3D Artist", "Programmer"]} isMobile={mobile}>
<Profile name="Kim" tags={["Cinemachine", "3D Artist", "Programmer"]} isMobile={mobile}> <span>
<span> <p>Abla espaniol</p>
<p>Abla espaniol</p> <p><a href="https://www.linkedin.com/in/kim-rex-de-dios-408860299/" target="_blank" style="color:lightblue;">Linked-in</a></p>
<p><a href="https://www.linkedin.com/in/kim-rex-de-dios-408860299/" target="_blank" style="color:lightblue;">Linked-in</a></p> </span>
</span> </Profile>
</Profile>
<ProfileSpacer/> <Profile name="Zylvester" tags={["Sound/Story", "2D/3D artist"]} isMobile={mobile}>
<Profile name="Zylvester" tags={["2D/3D Artist", "Sound designer", "Story designer"]} isMobile={mobile}> <span>
<span> <p>Closeted omega weeb</p>
<p>Hi, I am [insert text here]</p> <p><a href="https://www.linkedin.com/in/sylvester-junge-0b2a73196/" target="_blank" style="color:lightblue;">Linked-in</a>, <a href="https://www.youtube.com/watch?v=xvFZjo5PgG0" style="color:lightblue;">Funny link</a></p>
<p>Here's a joke about recursion: <a href="/" target="_blank" style="color:lightblue;">recursion</a></p> </span>
</span> </Profile>
</Profile> </div>
</div> </div>
</div> </div>
<!-- space --> <div class="py-4"></div>
<div class="py-8 flex justify-center">
<div style="width: 50%;">
<ProfileSpacer/>
</div>
</div>
<div class="grid place-content-center place-items-center min-h-screen pointer-events-auto font-mono"> <div class="grid place-content-center place-items-center pointer-events-auto font-mono">
<article class="pt-16 prose overflow-hidden {mobile ? "px-8" : ""}"> <!-- <article class="pt-16 prose overflow-hidden {mobile ? "px-8" : ""}">
<h2 class="main-title {!mobile ? "text-center m-auto" : "m-0"}" style="font-size: {!mobile ? 3 : 3}rem; ">About us</h2> <h2 class="main-title {!mobile ? "text-center m-auto" : "m-0"}" style="font-size: {!mobile ? 3 : 3}rem; ">About us</h2>
<p>We are a small group of developers and artists who started out as classmates, united by our passion for all things technology.</p> <p>We are a small group of developers and artists who started out as classmates, united by our passion for all things technology.</p>
</article> </article> -->
<!-- Spacer --> <!-- Spacer -->
<div style="width: 50%;" class="{!mobile ? "py-16" : "py-4"}"> <!-- <div style="width: 50%;" class="{!mobile ? "py-16" : "py-4"}">
<ProfileSpacer/> <ProfileSpacer/>
</div> </div> -->
<article class="pt-16 prose {mobile ? "px-8" : ""}"> <article class="prose {mobile ? "px-8" : ""}">
<h2 class="main-title {!mobile ? "text-center m-auto" : "m-0"}" style="font-size: {!mobile ? 3 : 3}rem; ">Games</h2> <h2 class="main-title {!mobile ? "text-center m-auto" : "m-0"}" style="font-size: {!mobile ? 3 : 3}rem; ">Games</h2>
<p>Here are some of our games from various gamejams from the past. <br/>(<span class="font-bold">ONLY</span> 48 hours per game)</p> <p>Here are some of our games from various gamejams from the past. <br/>(<span class="font-bold">ONLY</span> 48 hours per game)</p>
</article> </article>
@ -161,7 +158,7 @@
<br/> <br/>
<p>This was made during <a href="https://itch.io/jam/nordic-game-jam-2024/rate/2659665" class="underline">Nordic gamejam 2024</a></p> <p>This was made during <a href="https://itch.io/jam/nordic-game-jam-2024/rate/2659665" class="underline">Nordic gamejam 2024</a></p>
<div class="card-actions justify-end"> <div class="card-actions justify-end">
<a href="https://botalex.itch.io/corrobot-rebounce" target="_blank" class="btn btn-primary">View on itch.io</a> <a href="https://botalex.itch.io/corrobot-rebounce" target="_blank" class="btn btn-primary text-primary-content">View on itch.io</a>
</div> </div>
</div> </div>
</div> </div>
@ -183,7 +180,7 @@
<br/> <br/>
<p>This was made during <a href="https://itch.io/jam/future-game-makers-jam-2024" class="underline">Future Game Makers</a>, and of course our team won the competition.</p> <p>This was made during <a href="https://itch.io/jam/future-game-makers-jam-2024" class="underline">Future Game Makers</a>, and of course our team won the competition.</p>
<div class="card-actions justify-end"> <div class="card-actions justify-end">
<a href="https://botalex.itch.io/mop-of-the-dead" target="_blank" class="btn btn-primary">View on itch.io</a> <a href="https://botalex.itch.io/mop-of-the-dead" target="_blank" class="btn btn-primary text-primary-content">View on itch.io</a>
</div> </div>
</div> </div>
</div> </div>
@ -205,7 +202,7 @@
<br/> <br/>
<p>This was made during <a href="https://itch.io/jam/dmspiljam-november-2021" class="underline">Denmark Masters jam</a>. This jam has youths allover Denmark to compete, and of course our team won the competition again.</p> <p>This was made during <a href="https://itch.io/jam/dmspiljam-november-2021" class="underline">Denmark Masters jam</a>. This jam has youths allover Denmark to compete, and of course our team won the competition again.</p>
<div class="card-actions justify-end"> <div class="card-actions justify-end">
<a href="https://botalex.itch.io/one-more-time" target="_blank" class="btn btn-primary">View on itch.io</a> <a href="https://botalex.itch.io/one-more-time" target="_blank" class="btn btn-primary text-primary-content">View on itch.io</a>
</div> </div>
</div> </div>
</div> </div>
@ -213,7 +210,9 @@
<div class="games card bg-base-100 w-96 shadow-xl"> <div class="games card bg-base-100 w-96 shadow-xl">
<figure class="skeleton rounded-b-none" style="height: 15em;"></figure> <figure class="rounded-b-none" style="height: 15em;">
<div class="bg-grid-100 flex w-full h-full"></div>
</figure>
<div class="card-body"> <div class="card-body">
<h2 class="card-title">What's next?</h2> <h2 class="card-title">What's next?</h2>
<div class="skeleton mt-1 h-4 w-28"></div> <div class="skeleton mt-1 h-4 w-28"></div>
@ -223,7 +222,7 @@
<div class="skeleton h-4 w-full"></div> <div class="skeleton h-4 w-full"></div>
<div class="flex grow"/> <div class="flex grow"/>
<div class="card-actions justify-end"> <div class="card-actions justify-end">
<a href="/" target="_blank" class="btn btn-primary">RECURSION!</a> <a href="/" target="_blank" class="btn btn-primary text-primary-content text-primary-content">RECURSION!</a>
</div> </div>
</div> </div>
</div> </div>
@ -232,11 +231,6 @@
<style> <style>
.main-title {
width: 80%;
font-family: var(--title-font);
}
#backgroundGif{ #backgroundGif{
width: 100%; width: 100%;
height: 100%; height: 100%;

View file

@ -0,0 +1,64 @@
<script lang="ts">
import { onMount } from "svelte";
let scrollY = 0;
const animateInterval = 16;
const startMove = 64;
const numFrames = 312;
let framesLoaded = 1;
let ballsLoaded = 0;
let frameLoader: HTMLImageElement;
let frameLoader2: HTMLImageElement;
let frameLoader3: HTMLImageElement;
let frameLoader4: HTMLImageElement;
onMount(()=>{
// Force load once
ballsLoaded = 4;
onLoaded();
});
function onLoaded (){
ballsLoaded++;
if (ballsLoaded > 3) {
frameLoader.src = "/images/spinning_cat/untitled_" + framesLoaded.toString().padStart(5, '0') + ".png";
framesLoaded++;
frameLoader2.src = "/images/spinning_cat/untitled_" + framesLoaded.toString().padStart(5, '0') + ".png";
framesLoaded++;
frameLoader3.src = "/images/spinning_cat/untitled_" + framesLoaded.toString().padStart(5, '0') + ".png";
framesLoaded++;
frameLoader4.src = "/images/spinning_cat/untitled_" + framesLoaded.toString().padStart(5, '0') + ".png";
framesLoaded++;
ballsLoaded = 0;
}
}
let frameIndex = 0;
$: frameIndex = Math.min(Math.floor(Math.max(scrollY-startMove, 0) / animateInterval+1), numFrames);
</script>
<svelte:window bind:scrollY />
<div class="w-full flex justify-center" style="height: 5000px;">
<!-- Image Loader -->
<img on:load={()=>{onLoaded()}} bind:this={frameLoader} style="height: 0.01px; width: 0.01px;" class="" src="/images/spinning_cat/untitled_00001.png" alt="">
<img on:load={()=>{onLoaded()}} bind:this={frameLoader2} style="height: 0.01px; width: 0.01px;" class="" src="/images/spinning_cat/untitled_00001.png" alt="">
<img on:load={()=>{onLoaded()}} bind:this={frameLoader3} style="height: 0.01px; width: 0.01px;" class="" src="/images/spinning_cat/untitled_00001.png" alt="">
<img on:load={()=>{onLoaded()}} bind:this={frameLoader4} style="height: 0.01px; width: 0.01px;" class="" src="/images/spinning_cat/untitled_00001.png" alt="">
<!-- add "top-0" so it sticks at the top -->
<div class="sticky top-0" style="width: 200px; height: 200px;">
<div class="flex justify-center items-center" style="width: 200px; height: 200px;">
<img src="/images/spinning_cat/untitled_{frameIndex.toString().padStart(5, '0')}.png" class="object-contain w-full h-full" alt="">
</div>
<div>{frameIndex}</div>
</div>
</div>
<div class="h-[1000px] bg-amber-700 w-full">
</div>

View file

@ -11,14 +11,15 @@
</script> </script>
<div class="bg-grid-100 border-2 border-base-100 pl-1 pr-4 rounded-md cozette max-lg:pb-2">
{#if !isSnorre} {#if !isSnorre}
<div class="developersProfile {isSnorre ? "isSnorre" : ""} pl-4 font-mono"> <div class="developersProfile {isSnorre ? "isSnorre" : ""} pl-1 font-mono">
<NameAndTag name={name} tags={tags} isMobile={isMobile}/> <NameAndTag name={name} tags={tags} isMobile={isMobile}/>
<slot/> <slot/>
<MobileTags tags={tags} isMobile={isMobile}/> <MobileTags tags={tags} isMobile={isMobile}/>
</div> </div>
{:else} {:else}
<div class="w-full"> <div class="w-full pl-1">
<div class="developersProfile absolute snorre pl-4 font-mono pointer-events-none select-none"> <div class="developersProfile absolute snorre pl-4 font-mono pointer-events-none select-none">
<pre style="font-size: {!isMobile ? 1.5 : 1.5}rem;"> </pre> <pre style="font-size: {!isMobile ? 1.5 : 1.5}rem;"> </pre>
<span> <span>
@ -29,35 +30,38 @@
<pre> </pre> <pre> </pre>
{/if} {/if}
</div> </div>
<div class="developersProfile snorre-overlay relative pl-4 font-mono"> <div class="developersProfile snorre-overlay relative pl-1 font-mono">
<NameAndTag name="Snorre" tags={tags} isMobile={isMobile}/> <NameAndTag name="Snorre" tags={tags} isMobile={isMobile}/>
<span> <span>
<p>I'm the diversity hire. (Gay)</p> <p>I'm the diversity hire. <span class="border-b" style="border-image: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet); border-image-slice: 1;">(Gay)</span></p>
<p><a href="https://www.linkedin.com/in/snorrealtschul/" target="_blank" style="color:lightblue;">Linked-in</a></p> <!-- <p><a href="https://www.linkedin.com/in/snorrealtschul/" target="_blank" style="color:lightblue;">My website</a></p> -->
<p><a href="https://spoodythe.one/" target="_blank" style="color:lightblue;">My website</a></p>
</span> </span>
<MobileTags tags={tags} isMobile={isMobile}/> <MobileTags tags={tags} isMobile={isMobile}/>
</div> </div>
</div> </div>
{/if} {/if}
</div>
<style> <style>
.developersProfile:not(.snorre):not(.snorre-overlay){ .developersProfile:not(.snorre):not(.snorre-overlay){
background-image: linear-gradient(oklch(var(--p)) 33%, rgba(255,255,255,0) 0%); /* background-image: linear-gradient(var(--color-neutral) 33%, rgba(255,255,255,0) 0%); */
/* background-image: linear-gradient(var(--color-neutral) 100%);
background-position: left; background-position: left;
background-size: 0.1rem 0.5rem; background-size: 0.1rem 0.5rem;
background-repeat: repeat-y; background-repeat: repeat-y; */
} }
.snorre { .snorre {
border-left: dashed transparent 0.1rem; /* border-left: dashed transparent 0.1rem;
border-image: linear-gradient(to bottom, red, orange, yellow, green, blue, indigo, violet); border-image: linear-gradient(to bottom, red, orange, yellow, green, blue, indigo, violet);
border-image-slice: 1; border-image-slice: 1; */
} }
.snorre-overlay { .snorre-overlay {
background-image: linear-gradient(rgba(255,255,255,0) 0%, rgba(255,255,255,0) 40%, oklch(var(--b1)) 40%); /* background-image: linear-gradient(rgba(255,255,255,0) 0%, rgba(255,255,255,0) 40%, var(--color-base-200) 40%); */
background-position: left; /* background-position: left;
background-size: 0.1rem 0.5rem; background-size: 0.1rem 0.5rem;
background-repeat: repeat-y; background-repeat: repeat-y; */
} }
</style> </style>

View file

@ -1,8 +1,6 @@
<script lang="ts"> <script lang="ts">
import { onMount } from "svelte"; import { onMount } from "svelte";
import { Vector2 } from "./../zhen/Utils/Vector2"; import { Vector2 } from "../zhen/Utils/Vector2";
import { Parallax, ParallaxLayer, StickyLayer } from "svelte-parallax";
// Params // Params
let mouseMoveScale: number = 0.25; let mouseMoveScale: number = 0.25;

View file

@ -1,38 +1,77 @@
<script lang="ts"> <script lang="ts">
export let Tags= ["null"]; export let Tags = ["null"];
export let isMobile = false; export let isMobile = false;
type ColorType = string | { color1: string; color2: string; rotation: string; offset: string };
let colors: { [String: string]: ColorType} = {
"programmer": "#0CC27F",
"uxdesigner": "#027893",
"3dartist": "#F4881C",
"2dartist": "#F1EAC0",
"2d/3dartist": {"color1":"#F1EAC0", "color2":"#F4881C","rotation": "-65deg", "offset": "71.5%"},
"sounddesigner": "#F3EC2A",
"storydesigner": "#EEC12A",
"back-endadmin": "#3236a8",
};
// Define an interface for our detailed color object.
interface ColorObject {
color1: string;
color2: string;
rotation: string;
offset: string;
}
// ColorType can be a simple string or a ColorObject.
type ColorType = string | ColorObject;
// Create an interface for the color mapping.
interface ColorsMapping {
[key: string]: ColorType;
}
// Define a class to manage the colors.
class ColorManager {
private colors: ColorsMapping;
constructor() {
this.colors = {
"programmer": "#0CC27F",
"uxdesigner": "#027893",
"3dartist": "#F4881C",
"2dartist": "#F1EAC0",
"2d/3dartist": { color1: "#F1EAC0", color2: "#F4881C", rotation: "-65deg", offset: "71.5%" },
"sound/story": { color1: "#F3EC2A", color2: "#EEC12A", rotation: "-65deg", offset: "50%" },
"sounddesigner": "#F3EC2A",
"storydesigner": "#EEC12A",
"back-endadmin": "#3236a8",
};
}
// Return the color for the given key or a default value.
getColor(key: string): ColorType {
return this.colors[key] || "#ccc";
}
}
// Create an instance of ColorManager.
const colorManager = new ColorManager();
</script> </script>
<div class="flex gap-2" style='font-size: {!isMobile ? "0.875rem" : "2vw"};'> <div class="flex gap-2" style="font-size: { !isMobile ? '0.875rem' : '2vw' };">
{#each Tags as tag} {#each Tags as tag}
{@const key = tag.replaceAll(" ", "").toLowerCase()} {@const key = tag.replaceAll(" ", "").toLowerCase()}
{@const color = colorManager.getColor(key)}
{#if key.indexOf("/") < 0} {#if key.indexOf("/") < 0}
<div class="badge2 text-primary-content cozette" style="background-color: {colors[key] || "#ccc"};">{tag}</div> <!-- Single Color Badge -->
{:else} <div class="badge2" style="background-color: {typeof color === 'string' ? color : '#ccc'};">
<!-- Gradient Badge --> <span class="invert">
{#if typeof colors[key] === 'object' && colors[key] !== null}
<div
class="badge2 text-primary-content cozette"
style="background: linear-gradient({colors[key].rotation}, {colors[key].color2} {colors[key].offset}, {colors[key].color1} {colors[key].offset});">
{tag} {tag}
</span>
</div>
{:else}
<!-- Gradient Badge -->
{#if typeof color === 'object' && color !== null}
<div
class="badge2 cozette"
style="background: linear-gradient({color.rotation}, {color.color2} {color.offset}, {color.color1} {color.offset});">
<span class="invert">
{tag}
</span>
</div> </div>
{:else} {:else}
<div <div class="badge2 cozette" style="background-color: #ccc;">
class="badge2 text-primary-content cozette" <span class="invert">
style="background-color: #ccc;"> {tag}
{tag} </span>
</div> </div>
{/if} {/if}
{/if} {/if}
@ -44,12 +83,11 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: 1.25rem /* 20px */; height: 1.25rem; /* 20px */
line-height: 1.25rem /* 20px */; line-height: 1.25rem; /* 20px */
width: fit-content; width: fit-content;
padding-left: 0.563rem /* 9.008px */; padding-left: 0.563rem; /* 9.008px */
padding-right: 0.563rem /* 9.008px */; padding-right: 0.563rem; /* 9.008px */
border-radius: var(--rounded-badge, 1.9rem /* 30.4px */); border-radius: var(--rounded-badge, 1.9rem); /* 30.4px */
} }
</style> </style>

View file

@ -0,0 +1,258 @@
<script lang="ts">
import svelteLogo from "$lib/svelteLogos/svelte-logo.png";
import { browser } from "$app/environment";
import { onDestroy, onMount } from "svelte";
import { ArrowBigDown } from "lucide-svelte";
import { fly } from "svelte/transition";
const buildTime = __BUILD_TIME__;
let scrollY = 0;
const unscrollSpeed = 100;
let unscrollScrollDiv: HTMLDivElement;
let totalScroll = 0;
let unscrollInterval: number | undefined = undefined;
let lastScrollTime = 0; // Used to have delay before unscrolling
let isBeingTouched = false; // Phone support
const unscrollDelay = 100;
let isLeavingAnimating = false;
// prevent direct scroll
let notFirstScroll = false;
let tranisitionOverlay: HTMLElement;
// Function with more scroll control, by chatgpt
function smoothScrollTo(targetY: number, duration: number = 500): void {
const startY: number = window.scrollY;
const diff: number = targetY - startY;
if (duration <= 0) {
window.scrollTo(0, targetY);
return;
}
let startTime: number | null = null;
function step(timestamp: number): void {
if (startTime === null) startTime = timestamp;
const time = timestamp - startTime;
const percent = Math.min(time / duration, 1);
// easeInOutQuad easing
const ease =
percent < 0.5
? 2 * percent * percent
: -1 + (4 - 2 * percent) * percent;
window.scrollTo(0, startY + diff * ease);
if (time < duration) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}
// Out animation:
function flyInFromTop(
node: HTMLElement,
{
y = -window.innerHeight,
duration = 400,
opacity = 0,
}: { y?: number; duration?: number; opacity?: number } = {},
) {
const {
delay = 0,
duration: d,
easing = (t) => t,
css,
} = fly(node, { y, duration: d, opacity });
let start: number;
function step(now: number) {
if (!start) start = now;
const elapsed = now - start - delay;
if (elapsed < 0) return requestAnimationFrame(step);
const t = Math.min(elapsed / d, 1);
if (css) node.style.cssText = css(easing(t), 1 - easing(t));
if (elapsed < d) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
onMount(() => {
return; // Fuck this, I'm too lazy to fix this atm
totalScroll = document.documentElement.scrollHeight - window.innerHeight;
unscrollInterval = setInterval(() => {
// Prevents scroll to bottom on first try
if (
!notFirstScroll &&
scrollY > totalScroll - unscrollScrollDiv.scrollHeight
) {
smoothScrollTo(totalScroll - unscrollScrollDiv.scrollHeight * 1.1, 0);
// Allow further scroll after delay
setTimeout(() => {
notFirstScroll = true;
}, 1000);
}
// console.log("Time with delay: " + (Date.now() - -unscrollDelay) + " Other " + lastScrollTime);
// console.log(isBeingTouched);
if (
!notFirstScroll ||
isBeingTouched ||
Date.now() < lastScrollTime - -unscrollDelay
) {
// console.log("nah");
return;
}
if (totalScroll - unscrollScrollDiv.scrollHeight < scrollY) {
smoothScrollTo(totalScroll - unscrollScrollDiv.scrollHeight, 200);
}
if (totalScroll <= scrollY) {
console.log("Hit!");
// isLeavingAnimating = true;
flyInFromTop(tranisitionOverlay, { duration: 800 });
}
}, 10);
});
function onScroll() {
lastScrollTime = Date.now();
// console.log("scroll");
}
function onResize() {
totalScroll = document.documentElement.scrollHeight - window.innerHeight;
}
onDestroy(() => {
clearInterval(unscrollInterval);
});
export let hideOnPrint: boolean;
</script>
<svelte:window
bind:scrollY
on:scroll={() => {
onScroll();
}}
on:touchstart={() => {
isBeingTouched = true;
}}
on:touchend={() => {
isBeingTouched = false;
}}
on:resize={onResize}
/>
<div class="{hideOnPrint ? 'hide-on-print' : ''} w-full">
<!-- Keep scrolling thing -->
<div class="hidden h-64 w-full flex flex-col justify-center items-center">
<div>Keep scrolling to veiw Zhen's portfolio site!</div>
<div class="flex justify-center">
<ArrowBigDown />
<ArrowBigDown />
<ArrowBigDown />
<ArrowBigDown />
</div>
</div>
<div
class="hidden h-64 w-full flex flex-col justify-end items-center"
bind:this={unscrollScrollDiv}
>
<img
src="/images/memes/WhatDaDog.png"
class="w-32 h-32 object-contain"
alt="da dog"
/>
</div>
<!-- About footer -->
<div
class="sticky bottom-0 flex flex-col justify-center pt-8 bg-base-300 mt-8"
>
<div class="flex justify-center">
<div class="grid gap-8 sm:grid-cols-3 items-center w-full">
<div class="flex flex-col items-center">
<span class="font-bold">© 2023-2025</span>
<br />
<span>Benjamin Dreyer</span>
<br />
<span>Oliver Schwenger</span>
<br />
<span>Sylvester Junge</span>
<br />
<span>Snorre Ettrup Altschul</span>
<br />
<span>Zhentao Wei</span>
</div>
<div class="flex flex-col items-center">
<h3><b>About this website</b></h3>
<!-- <a href="/" target="_blank">Recursion</a> -->
<div class="flex justify-center">
This website was made using <a
class="grid place-content-center"
target="_blank"
href="https://kit.svelte.dev/"
>
<img
class="pl-2"
src={svelteLogo}
style="height: 1.5rem;"
alt="SvelteKit logo"
/></a
>
</div>
<span
>Website <a
href="https://git.deprived.dev/DeprivedDevs/deprived-main-website"
target="_blank">source code</a
></span
>
</div>
<div class="flex flex-col items-center">
<h3><b>Contact</b></h3>
<a href="mailto:zhen@deprived.dev">zhen@deprived.dev</a>
<div class="mt-2"></div>
<a
href="https://discord.gg/awatEEqc3M"
target="_blank"
class="social"
>
<!-- <span>Discord</span> -->
<img
src="/images/icons/discord.svg"
class="w-8 h-8 object-contain"
alt="Discord"
/>
</a>
</div>
</div>
</div>
<div
class="flex w-full justify-center border-t border-base-100 border-dashed"
>
Last build: {buildTime} (+2 UTC)
</div>
</div>
</div>
<div
bind:this={tranisitionOverlay}
class="{isLeavingAnimating
? ''
: 'hidden'} fixed top-0 left-0 w-screen h-screen bg-base-200"
></div>
<!-- {#if isLeavingAnimating}
{/if} -->

View file

@ -1,7 +1,7 @@
<script> <script>
import A4 from "../zhen/notes/physics/sharedComps/A4.svelte"; import A4 from "../zhen/notes/physics/sharedComps/A4.svelte";
import ToolButton from "./comps/ToolButton.svelte"; import ToolButton from "./comps/ToolButton.svelte";
import { BatteryMedium } from 'lucide-svelte'; import { BatteryMedium } from '@lucide/svelte';
</script> </script>
<div class="flex justify-center pt-10"> <div class="flex justify-center pt-10">
@ -11,7 +11,7 @@
class="cozette text-base-content h-full" class="cozette text-base-content h-full"
> >
<div class="p-4 flex flex-col h-full"> <div class="p-4 flex flex-col h-full">
<h1 class="text-5xl font-bold">Tools</h1> <h1 class="text-5xl font-bold">Tools (NOT FINISHED. come back in the future.)</h1>
<span class="w-full text-xl" <span class="w-full text-xl"
>These are the tools collected from different places of the >These are the tools collected from different places of the
internet</span internet</span
@ -28,19 +28,19 @@
title="Sleeping battery life" title="Sleeping battery life"
desc="Calculates the battery life depending on sleep and non-sleep power usage." desc="Calculates the battery life depending on sleep and non-sleep power usage."
btnText="To calculator" btnText="To calculator"
icon={BatteryMedium} toolIcon={BatteryMedium}
/> />
<!-- <ToolButton <!-- <ToolButton
title="Sleeping battery life" title="Sleeping battery life"
desc="Calculates the battery life depending on sleep and non-sleep power usage." desc="Calculates the battery life depending on sleep and non-sleep power usage."
btnText="To calculator" btnText="To calculator"
icon={BatteryMedium} toolIcon={BatteryMedium}
/> />
<ToolButton <ToolButton
title="Sleeping battery life" title="Sleeping battery life"
desc="Calculates the battery life depending on sleep and non-sleep power usage." desc="Calculates the battery life depending on sleep and non-sleep power usage."
btnText="To calculator" btnText="To calculator"
icon={BatteryMedium} toolIcon={BatteryMedium}
/> --> /> -->
</div> </div>
</div> </div>

View file

@ -1,16 +1,18 @@
<script lang="ts"> <script lang="ts">
import A4 from "../../zhen/notes/physics/sharedComps/A4.svelte"; import A4 from "../../zhen/notes/physics/sharedComps/A4.svelte";
import { BatteryLifeCalculator } from "./pageSrc/BatteryCalc"; import { BatteryLifeCalculator } from "./pageSrc/BatteryCalc";
import { getMCU, type MCU_Type } from "./pageSrc/MCU_defs";
let mathMachine = new BatteryLifeCalculator(); // let mathMachine = new BatteryLifeCalculator();
let useCustom: boolean = false; let useCustom: boolean = false;
let selectedText: string = ""; let selectedText: string = "";
let selectedMcu: MCU_Type | undefined = undefined;
$: selectedMcu = getMCU(selectedText)
const options = ["esp32-s3", "esp32-s3"];
const options = ["esp32-s3", "Text Two", "Text Three"];
</script> </script>
<div class="flex justify-center pt-10"> <div class="flex justify-center pt-10">
@ -82,21 +84,28 @@
</div> </div>
{#if !useCustom} {#if !useCustom}
<select <div>
bind:value={selectedText} <select
class="select select-sm select-bordered w-56 max-w-xs" bind:value={selectedText}
> class="select select-sm select-bordered w-56 max-w-xs"
<option disabled value="">Select a text</option> >
{#each options as option} <option disabled value="">Select a text</option>
<option value={option}>{option}</option> {#each options as option}
{/each} <option value={option}>{option}</option>
</select> {/each}
</select>
{#if selectedText} {#if selectedMcu != undefined && selectedMcu?.wifi != undefined}
<p class="mt-4 text-lg"> <p class="mt-4 text-lg">
You selected: {selectedText} wifi
</p> </p>
{/if} {/if}
{#if selectedMcu != undefined && selectedMcu?.wifi != undefined}
<p class="mt-4 text-lg">
ble
</p>
{/if}
</div>
{:else} {:else}
<div class="form-control"> <div class="form-control">
<span class="text-sm text-slate-300 text-opacity-60" <span class="text-sm text-slate-300 text-opacity-60"

View file

@ -1,108 +0,0 @@
export class BatteryLifeCalculator {
constructor(
timeRunSeconds,
timeSleepSeconds,
consumptionActiveMilliAmpHours,
consumptionSleepMilliAmpHours,
powerBatteryTotalMilliAmpHours,
powerBatteryBufferBeforeEmptyPercent = 20) {
this.timeRunSeconds = timeRunSeconds
this.timeSleepSeconds = timeSleepSeconds
this.consumptionActiveMilliAmpHours = consumptionActiveMilliAmpHours
this.consumptionSleepMilliAmpHours = consumptionSleepMilliAmpHours
this.powerBatteryTotalMilliAmpHours = powerBatteryTotalMilliAmpHours
this.powerBatteryBufferBeforeEmptyPercent = powerBatteryBufferBeforeEmptyPercent
console.log("The source of this battery calc is here: https://github.com/simonneutert/batterylife-calculator\nI was too lazy to make the math myself.");
}
// public API
milliAmpToMicroAmp(milliAmps) {
return milliAmps * 1000
}
microAmpToMilliAmp(milliAmps) {
return milliAmps * 0.001
}
calculate() {
return {
powerAveragePerHour: this.powerEstimatedHourly(),
runtimeHoursEstimated: this.runtimeHoursEstimated(),
runtimeDaysEstimated: this.runtimeDaysEstimated(),
runtimeDaysRemainingHoursEstimated: this.runtimeDaysRemainingHoursEstimated()
}
}
powerEstimatedHourly() {
return this.calcPowerEst(
this.powerRun(),
this.consumptionActiveMilliAmpHours,
this.powerSleep(),
this.consumptionSleepMilliAmpHours
)
}
runtimeHoursEstimated() {
return parseInt(this.powerLipo() / this.powerEstimatedHourly())
}
runtimeDaysEstimated() {
return parseInt(this.runtimeHoursEstimated() / 24)
}
runtimeDaysRemainingHoursEstimated() {
return parseInt(this.runtimeHoursEstimated() % 24)
}
// private
roundOff(x) {
return Math.round(x * 100.0) / 100.0
}
calcPowerLipo(x, y) {
return parseFloat((x * (100 - y)) / 100)
}
calcRuns(x, y) {
return parseFloat(60 / (x + y))
}
calcRunsHour(x, y) {
return parseFloat(3600 / (x + y))
}
calcPowerRun(x, y) {
return parseFloat((x / (x + y)) * 3600)
}
calcPowerSleep(x, y) {
return parseFloat((y / (x + y)) * 3600)
}
powerLipo() {
return this.calcPowerLipo(this.powerBatteryTotalMilliAmpHours, this.powerBatteryBufferBeforeEmptyPercent)
}
runs() {
return this.calcRuns(this.timeRunSeconds, this.timeSleepSeconds)
}
runsHour() {
return this.calcRunsHour(this.timeRunSeconds, this.timeSleepSeconds)
}
powerRun() {
return this.calcPowerRun(this.timeRunSeconds, this.timeSleepSeconds)
}
powerSleep() {
return this.calcPowerSleep(this.timeRunSeconds, this.timeSleepSeconds)
}
calcPowerEst(a, b, c, d) {
return parseFloat((a / 3600) * b + (c / 3600) * d)
}
}

View file

@ -0,0 +1,123 @@
export class BatteryLifeCalculator {
timeRunSeconds: number;
timeSleepSeconds: number;
consumptionActiveMilliAmpHours: number;
consumptionSleepMilliAmpHours: number;
powerBatteryTotalMilliAmpHours: number;
powerBatteryBufferBeforeEmptyPercent: number;
constructor(
timeRunSeconds: number,
timeSleepSeconds: number,
consumptionActiveMilliAmpHours: number,
consumptionSleepMilliAmpHours: number,
powerBatteryTotalMilliAmpHours: number,
powerBatteryBufferBeforeEmptyPercent: number = 20
) {
this.timeRunSeconds = timeRunSeconds;
this.timeSleepSeconds = timeSleepSeconds;
this.consumptionActiveMilliAmpHours = consumptionActiveMilliAmpHours;
this.consumptionSleepMilliAmpHours = consumptionSleepMilliAmpHours;
this.powerBatteryTotalMilliAmpHours = powerBatteryTotalMilliAmpHours;
this.powerBatteryBufferBeforeEmptyPercent = powerBatteryBufferBeforeEmptyPercent;
console.log(
"The source of this battery calc is here: https://github.com/simonneutert/batterylife-calculator\nI was too lazy to make the math myself."
);
}
// public API
milliAmpToMicroAmp(milliAmps: number): number {
return milliAmps * 1000;
}
microAmpToMilliAmp(milliAmps: number): number {
return milliAmps * 0.001;
}
calculate(): {
powerAveragePerHour: number;
runtimeHoursEstimated: number;
runtimeDaysEstimated: number;
runtimeDaysRemainingHoursEstimated: number;
} {
return {
powerAveragePerHour: this.powerEstimatedHourly(),
runtimeHoursEstimated: this.runtimeHoursEstimated(),
runtimeDaysEstimated: this.runtimeDaysEstimated(),
runtimeDaysRemainingHoursEstimated: this.runtimeDaysRemainingHoursEstimated(),
};
}
powerEstimatedHourly(): number {
return this.calcPowerEst(
this.powerRun(),
this.consumptionActiveMilliAmpHours,
this.powerSleep(),
this.consumptionSleepMilliAmpHours
);
}
runtimeHoursEstimated(): number {
return parseInt((this.powerLipo() / this.powerEstimatedHourly()).toString(), 10);
}
runtimeDaysEstimated(): number {
return parseInt((this.runtimeHoursEstimated() / 24).toString(), 10);
}
runtimeDaysRemainingHoursEstimated(): number {
return parseInt((this.runtimeHoursEstimated() % 24).toString(), 10);
}
// private methods
private roundOff(x: number): number {
return Math.round(x * 100.0) / 100.0;
}
private calcPowerLipo(x: number, y: number): number {
return parseFloat(((x * (100 - y)) / 100).toString());
}
private calcRuns(x: number, y: number): number {
return parseFloat((60 / (x + y)).toString());
}
private calcRunsHour(x: number, y: number): number {
return parseFloat((3600 / (x + y)).toString());
}
private calcPowerRun(x: number, y: number): number {
return parseFloat(((x / (x + y)) * 3600).toString());
}
private calcPowerSleep(x: number, y: number): number {
return parseFloat(((y / (x + y)) * 3600).toString());
}
powerLipo(): number {
return this.calcPowerLipo(this.powerBatteryTotalMilliAmpHours, this.powerBatteryBufferBeforeEmptyPercent);
}
runs(): number {
return this.calcRuns(this.timeRunSeconds, this.timeSleepSeconds);
}
runsHour(): number {
return this.calcRunsHour(this.timeRunSeconds, this.timeSleepSeconds);
}
powerRun(): number {
return this.calcPowerRun(this.timeRunSeconds, this.timeSleepSeconds);
}
powerSleep(): number {
return this.calcPowerSleep(this.timeRunSeconds, this.timeSleepSeconds);
}
private calcPowerEst(a: number, b: number, c: number, d: number): number {
return parseFloat(((a / 3600) * b + (c / 3600) * d).toString());
}
}

View file

@ -6,9 +6,9 @@ export interface MCU_Type {
bluetooth?: { [key: string]: Number }; bluetooth?: { [key: string]: Number };
} }
export const MCUs: MCU_Type[] = [ const MCUs: MCU_Type[] = [
{ {
name: "ESP32-S3", name: "esp32-s3",
cpu: { // mili amps cpu: { // mili amps
single_core_40MHz: 21.8, single_core_40MHz: 21.8,
dual_core_40MHz: 24.4, dual_core_40MHz: 24.4,
@ -33,10 +33,10 @@ export const MCUs: MCU_Type[] = [
}, },
{ {
name: "ESP32-C3", name: "esp32-c3",
cpu: { cpu: {
active: 130, single_core_80MHz: 22,
sleep: 15 single_core_160MHz: 54.6,
}, },
sleep: { sleep: {
@ -51,3 +51,13 @@ export const MCUs: MCU_Type[] = [
} }
} }
]; ];
export function getMCU(name: string): MCU_Type | undefined{
for (let i = 0; i < MCUs.length; i++) {
const element = MCUs[i];
if (element.name == name)
return element
}
return undefined;
}

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import type { SvelteComponent } from "svelte"; import type { Component } from 'svelte';
export let icon: typeof SvelteComponent | undefined = undefined; export let toolIcon: Component | undefined = undefined;
export let title: string = "Sleeping battery life"; export let title: string = "Sleeping battery life";
export let desc: string = "Calculates the battery life depending on sleep and non-sleep power usage."; export let desc: string = "Calculates the battery life depending on sleep and non-sleep power usage.";
@ -18,8 +18,8 @@
<div class="text-sm">{desc}</div> <div class="text-sm">{desc}</div>
<div class="flex pt-4"> <div class="flex pt-4">
{#if icon != undefined} {#if toolIcon != undefined}
<svelte:component this={icon}/> <svelte:component this={toolIcon}/>
{/if} {/if}
<a href="{btnHref}" class="btn ml-auto btn-primary btn-sm">{btnText}</a> <a href="{btnHref}" class="btn ml-auto btn-primary btn-sm">{btnText}</a>
</div> </div>

View file

@ -1,17 +0,0 @@
<script lang="ts">
import TopAnimatedBackground from "./Comps/TopAnimatedBackground.svelte";
import { Parallax, ParallaxLayer, StickyLayer } from "svelte-parallax";
import ZhenInformatikTimeline from "./Comps/ZhenInformatikTimeline.svelte"
import AboutMe from "./Comps/AboutMe.svelte"
</script>
<Parallax sections={3} config={{ stiffness: 0.1, damping: 0.3 }}>
<TopAnimatedBackground/>
<ParallaxLayer rate={0.5} offset={0.5} style="background-color: var(--background);">
<AboutMe/>
</ParallaxLayer>
<ParallaxLayer rate={0.5} offset={0.8} style="background-color: var(--background);">
<ZhenInformatikTimeline/>
</ParallaxLayer>
</Parallax>

View file

@ -1,229 +0,0 @@
<script lang="ts">
import { onMount } from "svelte";
import { Vector2 } from "./../Utils/Vector2";
import TopNameTextPlate from "./TopNameTextPlate.svelte";
//import { throttle } from "./../Utils/Throttle";
import { Parallax, ParallaxLayer, StickyLayer } from "svelte-parallax";
// Params
let mouseMoveScale: number = 0.25;
let targetTextLenght: number = 100;
// Site variables
let mousePos: Vector2;
// Element binded variables
let mouseRelativeScaled: Vector2 = new Vector2(0, 0);
let windowWidth = 0;
let windowHeight = 0;
let screenCenter: Vector2;
let StartPageAnimated: Element | null;
let windowRef: Window;
function onMouseMoved(event: MouseEvent) {
mousePos = new Vector2(event.clientX, event.clientY);
updateAnimation(mousePos);
}
function updateAnimation(mousePos: Vector2) {
let mouseRelativePos = mousePos.Sub(screenCenter);
mouseRelativeScaled = mouseRelativePos.Scale(mouseMoveScale);
//console.log(mouseRelativePos.x+"\n"+mouseRelativePos.y);
}
onMount(() => {
windowRef = window;
const updateDimensions = () => {
windowWidth = windowRef.innerWidth;
windowHeight = windowRef.innerHeight;
screenCenter = new Vector2(windowWidth / 2, windowHeight / 2);
//console.log("Window size changed: (" + windowWidth + ", " + windowHeight + ")");
};
updateDimensions(); // On first pass
windowRef.addEventListener("resize", updateDimensions);
const RevertToOrigin = () => {
if (
navigator.userAgent.search(/gecko/i) > 0 &&
StartPageAnimated !== null
) {
StartPageAnimated.classList.add("FirefoxSmoothTranition");
}
updateAnimation(new Vector2(windowWidth / 2, windowHeight / 2));
};
document.documentElement.addEventListener("mouseleave", RevertToOrigin);
const RemoveFirefoxSmoothTranition = () => {
if (
navigator.userAgent.search(/gecko/i) > 0 &&
StartPageAnimated !== null
) {
StartPageAnimated.classList.remove("FirefoxSmoothTranition");
}
};
document.documentElement.addEventListener(
"mouseenter",
RemoveFirefoxSmoothTranition,
);
return () => {
windowRef.removeEventListener("resize", updateDimensions);
};
});
const programmingLanguages: string[] = [
"C++",
"C#",
"ARDUINO",
"PYTHON",
"JAVA",
"JAVASCRIPT",
"TYPESCRIPT",
"HTML",
"CSS",
];
function getRandomInt(max: number) {
return Math.floor(Math.random() * max);
}
function GrabRandomString() {
let outString: string = "";
while (outString.length < targetTextLenght) {
outString +=
programmingLanguages[
getRandomInt(programmingLanguages.length)
] + " ";
}
return outString; // At about target size
}
</script>
<svelte:window on:mousemove={onMouseMoved} />
<ParallaxLayer class="StartPageContainer" rate={0.25} offset={0} span={0}>
<div
class="StartPageAnimated"
bind:this={StartPageAnimated}
style="transform: translate({mouseRelativeScaled.x}px, {mouseRelativeScaled.y}px) translateZ(0) rotate(0.001deg);"
>
{#each { length: 100 } as _, i}
<span class="rotate45 SkillsText">
{GrabRandomString()}
</span>
{/each}
</div>
</ParallaxLayer>
<ParallaxLayer rate={0} offset={0.25} span={0}>
<TopNameTextPlate />
</ParallaxLayer>
<!-- <div class="StartPageContainer">
<div class="TopOverlay">
<TopNameTextPlate/>
</div>
<div
class="StartPageAnimated"
id="StartPageAnimated"
bind:this={StartPageAnimated}
style="transform: translate({mouseRelativeScaled.x}px, {mouseRelativeScaled.y}px) translateZ(0) rotate(0.001deg);"
>
{#each {length: 100} as _, i}
<span
class="rotate45 SkillsText"
>
{GrabRandomString()}
</span
>
{/each}
</div>
</div> -->
<div id="DummyDiv" class="FirefoxSmoothTranition StartPageContainer TopOverlay" style="display: none !important;" />
<style>
.StartPageContainer {
/* height: 40vh; */
background-color: burlywood;
overflow: hidden;
position: relative;
justify-content: center;
align-items: center;
display: flex;
padding: 0;
}
.StartPageAnimated {
/* background: url("https://i1.adis.ws/i/canon/future_of_forests_header_16x9_dc14bbe1e35040f79bf566eedaf5c8f7?$hero-header-half-16by9-dt$"); */
background-color: #131313;
position: absolute;
height: 150vh;
width: 150vw;
padding: 0;
transition: transform 1000ms cubic-bezier(0.16, 1.63, 0.01, 0.99);
-moz-transition: none;
left: -25vw;
top: -50vh;
justify-content: center;
vertical-align: middle;
display: flex;
pointer-events: none;
}
.FirefoxSmoothTranition {
transition: transform 1000ms cubic-bezier(0.16, 1.63, 0.01, 0.99);
-moz-transition: transform 1000ms cubic-bezier(0.16, 1.63, 0.01, 0.99) !important;
}
.SkillsText {
font-family: "CozetteVector";
text-align: start;
font-size: x-large;
display: flex;
justify-content: center;
align-items: center;
white-space: nowrap;
width: 2rem;
color: rgb(66, 66, 66);
}
.TopOverlay {
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
padding: 0;
}
.rotate45 {
transform: rotate(-45deg); /* Rotate the element by 45 degrees */
}
</style>

View file

@ -11,7 +11,7 @@
<p class="NickNameText">Alex</p> <p class="NickNameText">Alex</p>
</span> </span>
</div> </div>
<div style="flex-grow: 2;" /> <div style="flex-grow: 2;" />
</div> </div>
<style> <style>

View file

@ -1,21 +0,0 @@
export function throttle(callback, wait) {
let timeoutId = null;
let lastExecutedTime = 0;
return function (...args) {
const currentTime = Date.now();
const execute = () => {
lastExecutedTime = currentTime;
callback.apply(this, args);
};
if (currentTime - lastExecutedTime >= wait) {
execute();
} else {
clearTimeout(timeoutId);
timeoutId = setTimeout(execute, wait - (currentTime - lastExecutedTime));
}
};
}

View file

@ -7,15 +7,15 @@ export class Vector2 {
this.y = y; this.y = y;
} }
Add(vec2: Vector2){ Add(vec2: Vector2) {
return new Vector2(this.x + vec2.x, this.y + vec2.y); return new Vector2(this.x + vec2.x, this.y + vec2.y);
} }
Sub(vec2: Vector2){ Sub(vec2: Vector2) {
return new Vector2(this.x - vec2.x, this.y - vec2.y); return new Vector2(this.x - vec2.x, this.y - vec2.y);
} }
Scale(mult: number){ Scale(mult: number) {
return new Vector2(this.x * mult, this.y * mult);; return new Vector2(this.x * mult, this.y * mult);;
} }
} }

View file

@ -3,7 +3,6 @@
</script> </script>
<div class="container" style="{Style}"> <div class="container" style="{Style}">
<div/>
<div> <div>
<div> <div>
Thank you! ❤ Thank you! ❤

View file

@ -53,11 +53,4 @@
width: 100%; width: 100%;
} }
} }
.imagesContainer {
> img {
border-radius: 5mm;
filter: drop-shadow(1mm 1mm 1mm #0000009d);
}
}
</style> </style>

View file

@ -74,7 +74,7 @@
<LinkedInQR/> <LinkedInQR/>
</div> </div>
</div> </div>
<div id="leftSectionSeperator"><div/></div> <div id="leftSectionSeperator"></div>
<div id="right-section"> <div id="right-section">
<AlexWatermark/> <AlexWatermark/>
<div id="TopRightSkillsText"> <div id="TopRightSkillsText">

View file

@ -74,7 +74,7 @@
<LinkedInQR/> <LinkedInQR/>
</div> </div>
</div> </div>
<div id="leftSectionSeperator"><div/></div> <div id="leftSectionSeperator"></div>
<div id="right-section"> <div id="right-section">
<AlexWatermark/> <AlexWatermark/>
<div id="TopRightSkillsText"> <div id="TopRightSkillsText">

View file

@ -1,243 +1,254 @@
<script lang="ts"> <script lang="ts">
// Left side // Left side
import NameAndImage from "../CompsRev2/NameAndImage.svelte"; import NameAndImage from "../CompsRev2/NameAndImage.svelte";
import ShortProfile from "../CompsRev2/ShortProfile.svelte" import ShortProfile from "../CompsRev2/ShortProfile.svelte";
import CombinedContacts from "../CompsRev2/CombinedContacts.svelte" import CombinedContacts from "../CompsRev2/CombinedContacts.svelte";
import LinkedInQR from "../CompsRev2/LinkedInQR.svelte"; import LinkedInQR from "../CompsRev2/LinkedInQR.svelte";
// Right side // Right side
import Profile from "../CompsRev2/Profile.svelte"; import Profile from "../CompsRev2/Profile.svelte";
import Education from "../CompsRev2/Education.svelte"; import Education from "../CompsRev2/Education.svelte";
import Experience from "../CompsRev2/Experience.svelte"; import Experience from "../CompsRev2/Experience.svelte";
import BiggestFlex from "../CompsRev2/BiggestFlex.svelte"; import BiggestFlex from "../CompsRev2/BiggestFlex.svelte";
import TableOfProjects from "../CompsRev2/TableOfProjects.svelte"; import TableOfProjects from "../CompsRev2/TableOfProjects.svelte";
// Decorations // Decorations
import LeftTopDecor from "../CompsRev2/LeftTopDecor.svelte"; import LeftTopDecor from "../CompsRev2/LeftTopDecor.svelte";
import BottomRightDecor from "../CompsRev2/BottomRightDecor.svelte"; import BottomRightDecor from "../CompsRev2/BottomRightDecor.svelte";
import AlexWatermark from "../CompsRev2/AlexWatermark.svelte"; import AlexWatermark from "../CompsRev2/AlexWatermark.svelte";
import RepeatedSkills from "../CompsRev2/RepeatedSkills.svelte"; import RepeatedSkills from "../CompsRev2/RepeatedSkills.svelte";
// Cedit // Cedit
import LinkToSource from "../CompsRev2/LinkToSource.svelte"; import LinkToSource from "../CompsRev2/LinkToSource.svelte";
// Discord embed // Discord embed
import preveiwImage from "$lib/zhen/cv-comps/EposCvPreveiw.png" import preveiwImage from "$lib/zhen/cv-comps/EposCvPreveiw.png";
// Print detection setup // Print detection setup
import { onMount } from "svelte"; import { onMount } from "svelte";
onMount(() => { onMount(() => {
// Check if the query parameter exists in the URL // Check if the query parameter exists in the URL
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const hideOnPrintParam = urlParams.get('hideOnPrint'); const hideOnPrintParam = urlParams.get("hideOnPrint");
// If the query parameter is not detected, reload the page with the parameter added // If the query parameter is not detected, reload the page with the parameter added
if (!hideOnPrintParam) { if (!hideOnPrintParam) {
window.location.href = `${window.location.href}?hideOnPrint=1`; window.location.href = `${window.location.href}?hideOnPrint=1`;
}
});
function getFormattedDate(): string {
const date = new Date();
const day = String(date.getDate()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, '0');
const year = date.getFullYear();
return `${day}-${month}-${year}`;
} }
});
function getFormattedDate(): string {
const date = new Date();
const day = String(date.getDate()).padStart(2, "0");
const month = String(date.getMonth() + 1).padStart(2, "0");
const year = date.getFullYear();
return `${day}-${month}-${year}`;
}
</script> </script>
<title>Zhentao Wei's CV {getFormattedDate()}</title> <title>Zhentao Wei's CV {getFormattedDate()}</title>
<meta content="Zhentao Wei's Epos CV" property="og:title" /> <meta content="Zhentao Wei's CV" property="og:title" />
<meta content="This CV is made completely with html + css + js" property="og:description" /> <meta
content="This CV is made completely with svelte + html + css + js"
property="og:description"
/>
<meta content={preveiwImage} property="og:image" /> <meta content={preveiwImage} property="og:image" />
<meta content="#bdd6ee" data-react-helmet="true" name="theme-color" /> <meta content="#bdd6ee" data-react-helmet="true" name="theme-color" />
<div class="cv-info-container hide-on-print"> <div class="cv-info-container hide-on-print">
<div> <div>
Under here is my CV rev1 for an application made entirely in HTML and CSS. The page is designed to be saved as PDF. Under here is my CV rev1 for an application made entirely in HTML and CSS.
This can be done by pressing <div class="keyboard-key">P</div> + <div class="keyboard-key">CTRL</div>, then set scaling to 100% and no margins. Lastly, select save to PDF or print. The page is designed to be saved as PDF. This can be done by pressing <div
<br/> class="keyboard-key"
<br/> >
I have to sadly recommend chrome for this process. Firefox somehow messes with the quality of the PDF :( P
</div> </div>
+
<div class="keyboard-key">CTRL</div>
, then set scaling to 100% and no margins. Lastly, select save to PDF or print.
<br />
<br />
I have to sadly recommend chrome for this process. Firefox somehow messes with
the quality of the PDF :(
</div>
</div> </div>
<div class="cv-container-container include-in-print"> <div class="cv-container-container include-in-print">
<div class="cv-container sections decorations"> <div class="cv-container sections decorations">
<div id="left-section"> <div id="left-section">
<LeftTopDecor Style="pointer-events: none;"/> <LeftTopDecor Style="pointer-events: none;" />
<BottomRightDecor Style="pointer-events: none;"/> <BottomRightDecor Style="pointer-events: none;" />
<div> <div>
<NameAndImage/> <NameAndImage />
<ShortProfile/> <ShortProfile />
<CombinedContacts/> <CombinedContacts />
<LinkedInQR/> <LinkedInQR />
</div> </div>
</div>
<div id="leftSectionSeperator"><div/></div>
<div id="right-section">
<AlexWatermark Style="pointer-events: none;"/>
<div id="TopRightSkillsText">
<RepeatedSkills targetTextHeight={30} targetTextWidth={75}/>
</div>
<div id="Credit">
<LinkToSource/>
</div>
<div>
<Profile/>
<BiggestFlex/>
<TableOfProjects/>
<Experience/>
<Education/>
</div>
</div>
</div> </div>
<div id="leftSectionSeperator"></div>
<div id="right-section">
<AlexWatermark Style="pointer-events: none;" />
<div id="TopRightSkillsText">
<RepeatedSkills targetTextHeight={30} targetTextWidth={75} />
</div>
<div id="Credit">
<LinkToSource />
</div>
<div>
<Profile />
<BiggestFlex />
<TableOfProjects />
<Experience />
<Education />
</div>
</div>
</div>
</div> </div>
<style lang="scss"> <style lang="scss">
.cv-info-container { .cv-info-container {
height: 40mm; height: 40mm;
background-color: #2b2a2a; background-color: #2b2a2a;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
.keyboard-key { .keyboard-key {
display: inline; display: inline;
padding-left: 1mm; padding-left: 1mm;
padding-right: 1mm; padding-right: 1mm;
border-radius: 2mm; border-radius: 2mm;
background-color: #3e3d3d; background-color: #3e3d3d;
}
> div {
width: 80%;
height: 60%;
}
} }
.cv-container-container{ > div {
width: 80%;
height: 60%;
}
}
.cv-container-container {
width: 100%;
height: 100%;
display: grid;
place-items: center;
}
.cv-container-container * {
color: black; // Set all text black
}
.cv-container {
width: 210mm;
height: 297mm;
background-color: #eeeeee;
overflow: visible;
display: flex;
padding: auto;
}
.sections {
// Shared between sections
> div {
display: grid;
z-index: 0;
// Needed to cuttoff the extra decoration
position: relative;
overflow: hidden;
}
#left-section {
background-color: #bdd6ee;
width: calc(100% / 3 * 1);
> div:last-child {
z-index: 1;
width: 100%; width: 100%;
height: 100%;
left: 0;
display: grid; display: grid;
place-items: center; place-items: center;
}
.cv-container-container * { padding-top: 30mm;
color: black; // Set all text black padding-bottom: 30mm;
}
.cv-container {
width: 210mm;
height: 297mm;
background-color: #eeeeee;
overflow: visible;
display: flex;
padding: auto;
}
.sections {
// Shared between sections
> div {
display: grid;
z-index: 0;
// Needed to cuttoff the extra decoration
position: relative;
overflow: hidden;
}
#left-section{
background-color: #bdd6ee;
width: calc(100% / 3 * 1);
> div:last-child {
z-index: 1;
width: 100%;
left: 0;
display: grid;
place-items: center;
padding-top: 30mm;
padding-bottom: 30mm;
}
}
#right-section{
width: calc(100% / 3 * 2);
> div:last-child {
z-index: 1;
width: 100%;
left: 0;
display: grid;
place-items: center;
row-gap: 6mm;
padding-top: 45mm;
padding-bottom: 30mm;
// Disable interactivity for padding
pointer-events:none;
}
}
}
.decorations {
#leftSectionSeperator{
position: relative;
height: 100%;
width: 0%;
z-index: 1;
overflow: visible;
> div {
position: absolute;
height: 100%;
width: 5mm;
z-index: 1;
background: linear-gradient(90deg, #3636364f, #00000000);
}
}
> div {
#TopRightSkillsText {
position: absolute;
z-index: 0;
display: grid;
place-items: center;
vertical-align: top;
width: 100%;
place-content: center;
padding: 0;
height: 50mm;
mask-image: linear-gradient(180deg, #000 0%, transparent 110%);
color: rgb(190, 190, 190);
font-family: 'CozetteVector';
font-size: x-large;
}
#Credit {
position: absolute;
z-index: 0;
display: flex;
align-self: flex-end;
}
} }
} }
#right-section {
width: calc(100% / 3 * 2);
> div:last-child {
z-index: 1;
width: 100%;
left: 0;
display: grid;
place-items: center;
row-gap: 6mm;
padding-top: 45mm;
padding-bottom: 30mm;
// Disable interactivity for padding
pointer-events: none;
}
}
}
.decorations {
#leftSectionSeperator {
position: relative;
height: 100%;
width: 0%;
z-index: 1;
overflow: visible;
> div {
position: absolute;
height: 100%;
width: 5mm;
z-index: 1;
background: linear-gradient(90deg, #3636364f, #00000000);
}
}
> div {
#TopRightSkillsText {
position: absolute;
z-index: 0;
display: grid;
place-items: center;
vertical-align: top;
width: 100%;
place-content: center;
padding: 0;
height: 50mm;
mask-image: linear-gradient(180deg, #000 0%, transparent 110%);
color: rgb(190, 190, 190);
font-family: "CozetteVector";
font-size: x-large;
}
#Credit {
position: absolute;
z-index: 0;
display: flex;
align-self: flex-end;
}
}
}
</style> </style>

View file

@ -1,117 +0,0 @@
<script lang="ts">
import RepeatedSkills from "../../cv/Comps/RepeatedSkills.svelte";
// Discord embed
import preveiwImage from "$lib/zhen/cv-comps/EposCvPreveiw.png"
// Print detection setup
import { onMount } from "svelte";
onMount(() => {
// Check if the query parameter exists in the URL
const urlParams = new URLSearchParams(window.location.search);
const hideOnPrintParam = urlParams.get('hideOnPrint');
// If the query parameter is not detected, reload the page with the parameter added
if (!hideOnPrintParam) {
window.location.href = `${window.location.href}?hideOnPrint=1`;
}
});
function getFormattedDate(): string {
const date = new Date();
const day = String(date.getDate()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, '0');
const year = date.getFullYear();
return `${day}-${month}-${year}`;
}
</script>
<title>Zhentao Wei's LinkedIn banner {getFormattedDate()}</title>
<meta content="Zhentao Wei's LinkedIn banner" property="og:title" />
<meta content="This Linkedin banner is made completely with html + css + js" property="og:description" />
<meta content={preveiwImage} property="og:image" />
<meta content="#bdd6ee" data-react-helmet="true" name="theme-color" />
<div class="cv-info-container hide-on-print">
<div>
Under here is my Linkedin banner. This page has been able to be saved as PDF, and the banner can be extracted as an image fro mthe pdf.
This can be done by pressing <div class="keyboard-key">P</div> + <div class="keyboard-key">CTRL</div>, then set scaling to 100% and no margins. Lastly, select save to PDF or print.
<br/>
<br/>
I have to sadly recommend chrome for this process. Firefox somehow messes with the quality of the PDF :(
</div>
</div>
<div class="container include-in-print">
<div>
<RepeatedSkills targetTextHeight={70} targetTextWidth={175}/>
</div>
<div/>
</div>
<style lang="scss">
.cv-info-container {
height: 40mm;
background-color: #2b2a2a;
display: flex;
justify-content: center;
align-items: center;
.keyboard-key {
display: inline;
padding-left: 1mm;
padding-right: 1mm;
border-radius: 2mm;
background-color: #3e3d3d;
}
> div {
width: 80%;
height: 60%;
}
}
@media print {
.hide-on-print {
display: none;
}
}
.include-in-print { &, & * {
-webkit-print-color-adjust:exact !important;
print-color-adjust:exact !important;
}}
.container {
width: 100%;
height: 100%;
display: grid;
place-items: center;
> div:nth-child(1) {
width: 419.1mm;
height: 104.775mm;
background-color: #383636;
overflow: hidden;
display: grid;
place-content: center;
font-size: 10mm;
font-family: cozetteVector;
color: #d4d4d4;
filter: blur(0); // Force save as image
}
> div:nth-child(2){
height: 0;
}
}
</style>

View file

@ -1,72 +0,0 @@
<script lang="ts">
import A4 from "../sharedComps/A4.svelte";
</script>
<svelte:head>
<script>
MathJax = {
tex: {
inlineMath: [
["$", "$"],
["\\(", "\\)"],
],
},
};
</script>
<script
id="MathJax-script"
async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"
></script>
</svelte:head>
<div class="flex justify-center m-auto text-slate-900">
<div class="flex flex-col">
<A4>
<!-- <div>$$v_f = v_i + at$$</div>
<div>$$\Delta x = v_i t + \frac{1}{2} a t^2$$</div>
<div>$$v_f^2 = v_i^2 + 2a\Delta x$$</div>
<div>$$v_{\text{avg} = \frac{v_i + v_f}{2}$$</div>
<div>$$\Delta x = v_{\text{avg}} t$$</div> -->
<div class="overflow-x-auto">
<table class="table">
<!-- head -->
<thead>
<tr>
<th>Symbol</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>$v_i$</td>
<td>Initial velo</td>
</tr>
<tr>
<td>$v_f$</td>
<td>Final velo</td>
</tr>
<tr>
<td>$a$</td>
<td>Accel</td>
</tr>
<tr>
<td>$\Delta x$</td>
<td>The amount of change.</td>
</tr>
<tr>
<td>$t$</td>
<td>You're on your own on this one</td>
</tr>
</tbody>
</table>
</div>
</A4>
<A4>
{#each { length: 3 } as _, i}
<div>test {i}</div>
{/each}
</A4>
</div>
</div>

55
static/images/cropper.py Normal file
View file

@ -0,0 +1,55 @@
import os
import glob
from PIL import Image
from concurrent.futures import ProcessPoolExecutor, as_completed
# Directories
input_dir = 'spinning_cat'
output_dir = 'spinning_cat_cropped'
# Ensure output directory exists
def ensure_output_dir():
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Process a single image: crop transparent borders and save
def process_image(filepath):
try:
img = Image.open(filepath)
if img.mode != 'RGBA':
img = img.convert('RGBA')
alpha = img.split()[-1]
bbox = alpha.getbbox()
cropped = img.crop(bbox) if bbox else img
filename = os.path.basename(filepath)
out_path = os.path.join(output_dir, filename)
cropped.save(out_path)
return out_path, None
except Exception as e:
return filepath, e
# Main execution: parallel processing
def main():
ensure_output_dir()
pattern = os.path.join(input_dir, 'untitled_*.png')
files = sorted(glob.glob(pattern))
if not files:
print(f"No files found in '{input_dir}' with pattern 'untitled_*.png'.")
return
with ProcessPoolExecutor() as executor:
futures = {executor.submit(process_image, fp): fp for fp in files}
for future in as_completed(futures):
fp = futures[future]
out_path, error = future.result()
if error:
print(f"Error processing {fp}: {error}")
else:
print(f"Cropped and saved: {out_path}")
print("Processing complete.")
if __name__ == '__main__':
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Some files were not shown because too many files have changed in this diff Show more