[READ-ONLY] Mirror of https://github.com/flo-bit/flo-bit.github.io. my personal website, w/ astro, svelte, tailwind, typescript, threlte flo-bit.dev/
portfolio portfolio-website svelte sveltekit tailwind threejs threlte typescript
0

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #30 from flo-bit/main

deploy

authored by

Florian and committed by
GitHub
(Oct 3, 2024, 1:13 PM +0200) 052d3f1f 30fc05bd

+347 -211
+24 -4
README.md
··· 2 2 3 3 this is my portfolio, created using sveltekit, threlte, threejs and tailwind. wip. 4 4 5 + ## demos 6 + 5 7 [see it live here](https://flo-bit.github.io/) 6 8 7 9 [vr version here](https://flo-bit.github.io/vr) (only tested on quest 3) 8 10 9 - ## demos 10 - 11 11 ![screenshot](/static/image.jpg) 12 12 13 - older demo videos: 13 + demo videos: 14 14 15 - https://github.com/flo-bit/flo-bit.github.io/assets/45694132/481296b2-f36d-466c-9741-4dd5771eb306 15 + https://github.com/user-attachments/assets/757d9b20-2232-4012-8013-68d5997960e6 16 16 17 17 https://github.com/flo-bit/flo-bit.github.io/assets/45694132/a251ab6f-a416-4a2d-905f-8dffb2e36e0f 18 + 19 + ## techstack 20 + 21 + - sveltekit (static build using `@sveltejs/adapter-static`) 22 + - threlte (svelte wrapper for threejs) 23 + - tailwind 24 + - automatic deployment using github actions to github pages 25 + - typescript 26 + 27 + ## development 28 + 29 + clone the repo, install dependencies and run the dev server: 30 + 31 + ```bash 32 + git clone https://github.com/flo-bit/flo-bit.github.io.git 33 + npm install 34 + npm run dev 35 + ``` 36 + 37 + when using it for your own portfolio, please remove the posthog analytics script from `src/app.html` (line 3-6)
+2 -1
todo.md
··· 18 18 - update favicon (dark mode) 19 19 - featured project? 20 20 - autumn planet 21 - - halloween planet 21 + - halloween planet 22 + - accessibility (keyboard navigation, focus styles, check audio version)
+11 -11
src/lib/projects.ts
··· 78 78 { 79 79 src: tinyplanets, 80 80 key: 'tiny-planets', 81 - projectUrl: 'https://flo-bit.github.io/tiny-planets/', 81 + projectUrl: 'https://flo-bit.dev/tiny-planets/', 82 82 aspect: 'aspect-[1]', 83 83 name: 'tiny planets', 84 84 codeUrl: 'https://github.com/flo-bit/tiny-planets', ··· 90 90 { 91 91 src: svelteswipecards, 92 92 key: 'svelte-swiper-cards', 93 - href: 'https://flo-bit.github.io/svelte-swiper-cards/', 93 + href: 'https://flo-bit.dev/svelte-swiper-cards/', 94 94 95 - projectUrl: 'https://flo-bit.github.io/svelte-swiper-cards/', 95 + projectUrl: 'https://flo-bit.dev/svelte-swiper-cards/', 96 96 97 97 aspect: 'aspect-[9/18]', 98 98 name: 'svelte swipable cards', ··· 116 116 { 117 117 src: mandala, 118 118 key: 'svg-mandala', 119 - projectUrl: 'https://flo-bit.github.io/mandala/', 119 + projectUrl: 'https://flo-bit.dev/mandala/', 120 120 aspect: 'aspect-1', 121 121 name: 'svg mandala drawer', 122 122 description: ··· 130 130 { 131 131 src: fluidtexteffect, 132 132 key: 'text-effect-fluid', 133 - projectUrl: 'https://flo-bit.github.io/text_effect_fluid/', 133 + projectUrl: 'https://flo-bit.dev/text_effect_fluid/', 134 134 aspect: 'aspect-[23/9]', 135 135 name: 'fluid text effect', 136 136 codeUrl: 'https://github.com/flo-bit/text_effect_fluid', ··· 165 165 // src: mandala, 166 166 // key: 'svg-mandala', 167 167 // alt: 'svg mandala drawer', 168 - // projectUrl: 'https://flo-bit.github.io/mandala/', 168 + // projectUrl: 'https://flo-bit.dev/mandala/', 169 169 // aspect: 'aspect-1', 170 170 // name: 'svg mandala drawer', 171 171 // description: ··· 178 178 { 179 179 src: shadowshmup, 180 180 key: 'shadow-shmup', 181 - codeUrl: 'https://flo-bit.github.io/shadow-shmup/', 181 + codeUrl: 'https://flo-bit.dev/shadow-shmup/', 182 182 aspect: 'aspect-[13/9]', 183 183 name: 'shadow shmup', 184 184 description: ··· 191 191 { 192 192 src: fake3d, 193 193 key: 'depth3dcomponent', 194 - projectUrl: 'https://flo-bit.github.io/svelte-depth-3d-component/', 194 + projectUrl: 'https://flo-bit.dev/svelte-depth-3d-component/', 195 195 aspect: 'aspect-[9/16]', 196 196 name: 'svelte depth 3d component', 197 197 description: ··· 217 217 { 218 218 src: oldcode, 219 219 key: 'old-code', 220 - projectUrl: 'https://flo-bit.github.io/old-code/', 220 + projectUrl: 'https://flo-bit.dev/old-code/', 221 221 aspect: 'aspect-[16/11]', 222 222 name: 'old coding projects', 223 223 codeUrl: 'https://github.com/flo-bit/old-code', ··· 240 240 { 241 241 src: marblellous, 242 242 key: 'marblellous', 243 - projectUrl: 'https://flo-bit.github.io/ball-game/', 243 + projectUrl: 'https://flo-bit.dev/ball-game/', 244 244 aspect: 'aspect-[9/10]', 245 245 name: 'marblellous', 246 246 description: ··· 252 252 // src: autostereogramrenderer, 253 253 // key: 'autostereogram-renderer', 254 254 // alt: 'autostereogram renderer', 255 - // projectUrl: 'https://flo-bit.github.io/autostereogram-renderer/', 255 + // projectUrl: 'https://flo-bit.dev/autostereogram-renderer/', 256 256 // codeUrl: 'https://github.com/flo-bit/autostereogram-renderer', 257 257 // aspect: 'aspect-1', 258 258 // name: 'autostereogram renderer',
+14 -17
src/lib/components/About.svelte
··· 37 37 </div> 38 38 <div class="lg:order-first lg:row-span-2"> 39 39 <h1 40 - class="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl" 40 + class="text-4xl font-bold tracking-tight text-zinc-800 sm:leading-[3.5rem] dark:text-zinc-100 sm:text-5xl" 41 41 > 42 - hey there, i'm florian. i live in berlin, where i create things for the web. 42 + i'm florian. i live in berlin, where i create things for the web. 43 43 </h1> 44 44 <div class="mt-6 space-y-7 text-base text-zinc-600 dark:text-zinc-400"> 45 45 <p> 46 - i was one of the only kids in my class without a game console, but we did have a computer. 47 - when i was 12, I got a coding book for christmas and started making my own games in C and 48 - opengl. though i never finished any of those early projects, i got hooked on 49 - programming. 46 + i was one of the only kids in my class without a game console, but we did have a 47 + computer. when i was 12, I got a coding book for christmas and started making my own 48 + games in C and opengl. though i never finished any of those early projects, i got 49 + hooked on programming. 50 50 </p> 51 51 <p> 52 - after school, I started studying computer science and started working as a software developer. 53 - i really love the web because it's so accessible — anyone with a device and internet can 54 - access your work instantly. publishing and sharing your work is also pretty simple, 55 - whether as a website, a pwa, or a serverless function/api. 52 + after school, I started studying computer science and started working as a software 53 + developer. i really love the web because it's so accessible — anyone with a device and 54 + internet can access your work instantly. publishing and sharing your work is also 55 + pretty simple, whether as a website, a pwa, or a serverless function/api. 56 56 </p> 57 57 <p> 58 - in my free time, i build lots of web-based projects. i really like the 59 - intersection of design and development. I love learning new things and am always 60 - looking for new cool projects. 61 - If you want to build something together or just want to connect, feel free to <a 62 - href="#contact" 63 - class="text-cyan-400 hover:text-cyan-300 font-semibold" 64 - > 58 + in my free time, i build lots of web-based projects. i really like the intersection of 59 + design and development. I love learning new things and am always looking for new cool 60 + projects. If you want to build something together or just want to connect, feel free 61 + to <a href="#contact" class="text-cyan-400 hover:text-cyan-300 font-semibold"> 65 62 reach out. 66 63 </a> 67 64 </p>
+110
src/lib/components/Bento.svelte
··· 1 + <script> 2 + 3 + import { Depth3D } from "$lib/3D/Depth3D"; 4 + 5 + // @ts-ignore 6 + import imageMe from '$lib/images/me.png?w=512&format=webp'; 7 + // @ts-ignore 8 + import depthMe from '$lib/images/me-depth.png?w=512&format=webp'; 9 + import ResumeContent from "./ResumeContent.svelte"; 10 + 11 + </script> 12 + <div class="relative isolate overflow-hidden bg-background py-16"> 13 + <div class="mx-auto max-w-5xl px-6 lg:px-8"> 14 + 15 + <div class="mt-10 grid grid-cols-1 gap-4 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2"> 16 + <div class="flex p-px lg:col-span-4"> 17 + <div 18 + class="overflow-hidden rounded-lg bg-zinc-950 ring-1 ring-white/15 max-lg:rounded-t-[2rem] lg:rounded-tl-[2rem] flex-grow" 19 + > 20 + <!-- <img 21 + class="h-80 object-cover object-left" 22 + src="https://tailwindui.com/plus/img/component-images/bento-02-releases.png" 23 + alt="" 24 + /> --> 25 + 26 + 27 + <div class="p-10"> 28 + <h3 class="text-sm/4 font-semibold text-zinc-400">Releases</h3> 29 + 30 + <h1 31 + class="text-4xl font-bold tracking-tight text-zinc-800 sm:leading-[3.5rem] dark:text-zinc-100 sm:text-5xl" 32 + > 33 + i'm florian. i live in berlin, where i create things for the web. 34 + </h1> 35 + <p class="mt-2 max-w-lg text-sm/6 text-zinc-400"> 36 + Lorem ipsum dolor sit amet, consectetur adipiscing elit. In gravida justo et nulla 37 + efficitur, maximus egestas sem pellentesque. 38 + </p> 39 + </div> 40 + </div> 41 + </div> 42 + 43 + <div class="flex p-px lg:col-span-2"> 44 + <div 45 + class="overflow-hidden rounded-lg bg-zinc-950 flex-grow ring-1 ring-white/15 lg:rounded-tr-[2rem]" 46 + > 47 + <!-- <img 48 + class="h-80 object-cover object-center" 49 + src="https://tailwindui.com/plus/img/component-images/bento-02-integrations.png" 50 + alt="" 51 + /> --> 52 + <div class="h-80 object-cover object-center"> 53 + <Depth3D 54 + image={{ 55 + image: imageMe, 56 + depth: depthMe 57 + }} 58 + rounded={true} 59 + /> 60 + </div> 61 + <div class="p-10"> 62 + <h3 class="text-sm/4 font-semibold text-accent-400">hello</h3> 63 + <p class="mt-2 text-lg/7 font-medium tracking-tight text-white"> 64 + this is me 65 + </p> 66 + </div> 67 + </div> 68 + </div> 69 + 70 + <div class="flex p-px lg:col-span-3"> 71 + <div 72 + class="overflow-hidden rounded-lg bg-zinc-950 flex-grow ring-1 ring-white/15 lg:rounded-bl-[2rem]" 73 + > 74 + <!-- <img 75 + class="h-80 object-cover object-center" 76 + src="https://tailwindui.com/plus/img/component-images/bento-02-security.png" 77 + alt="" 78 + /> --> 79 + <div class="p-10"> 80 + <ResumeContent /> 81 + </div> 82 + 83 + 84 + </div> 85 + </div> 86 + 87 + <div class="flex p-px lg:col-span-3"> 88 + <div 89 + class="overflow-hidden rounded-lg bg-zinc-950 flex-grow ring-1 ring-white/15 max-lg:rounded-b-[2rem] lg:rounded-br-[2rem]" 90 + > 91 + <!-- <img 92 + class="h-80 object-cover object-left" 93 + src="https://tailwindui.com/plus/img/component-images/bento-02-performance.png" 94 + alt="" 95 + /> --> 96 + <div class="p-10"> 97 + <h3 class="text-sm/4 font-semibold text-zinc-400">Performance</h3> 98 + <p class="mt-2 text-lg/7 font-medium tracking-tight text-white"> 99 + Lightning-fast builds 100 + </p> 101 + <p class="mt-2 max-w-lg text-sm/6 text-zinc-400"> 102 + Sed congue eros non finibus molestie. Vestibulum euismod augue vel commodo vulputate. 103 + Maecenas at augue sed elit dictum vulputate. 104 + </p> 105 + </div> 106 + </div> 107 + </div> 108 + </div> 109 + </div> 110 + </div>
+41 -36
src/lib/components/Projects.svelte
··· 3 3 import { projects } from '$lib/projects'; 4 4 </script> 5 5 6 - <div id="projects" class="z-20 py-16 md:py-32 section bg-background relative isolate"> 6 + <div 7 + id="projects" 8 + class="z-20 py-16 md:py-32 section bg-background relative isolate overflow-hidden" 9 + > 7 10 <div class="mx-auto max-w-5xl px-6 lg:px-8"> 8 11 <div class="max-w-2xl mb-8"> 9 12 <h1 class="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl"> ··· 16 19 </p> 17 20 </div> 18 21 19 - <div class="columns-2 sm:columns-3 lg:columns-3 gap-8 group/projects pointer-events-none"> 22 + <div class="columns-2 sm:columns-3 sm:text-[0] gap-4 group/projects pointer-events-none"> 20 23 {#each projects as project} 21 - <div 22 - class="group relative break-inside-avoid-column {project.aspect ?? 23 - 'aspect-square'} pointer-events-auto group-hover/projects:opacity-30 group-focus/projects:opacity-30 hover:!opacity-100 mb-8 w-full flex-none overflow-hidden rounded-xl ring-1 ring-white/10 focus:ring-accent-500 focus:!opacity-100 sm:rounded-2xl transition-opacity duration-500" 24 - > 25 - {#if project.src.endsWith('.mp4')} 26 - <video 27 - autoplay 28 - loop 29 - muted 30 - playsinline 31 - class="absolute inset-0 h-full w-full object-cover rounded-xl" 32 - preload="none" 33 - > 34 - <source src={project.src} type="video/mp4" /> 35 - </video> 36 - {:else} 37 - <img 38 - src={project.src} 39 - alt="" 40 - class="absolute inset-0 h-full w-full object-cover rounded-xl" 41 - loading="lazy" 42 - /> 43 - {/if} 24 + <div class="w-full mb-4"> 44 25 <div 45 - class="overflow-hidden absolute z-10 pointer-events-none inset-0 w-full h-full flex items-end p-4 md:p-4 tracking-tight leading-6 text-white text-xl font-semibold sm:translate-y-20 group-hover:translate-y-0 transition-translation duration-200" 26 + class="group relative inline-block sm:w-full break-inside-avoid-column {project.aspect ?? 27 + 'aspect-square'} pointer-events-auto group-hover/projects:opacity-30 group-focus/projects:opacity-30 hover:!opacity-100 w-full flex-none border border-white/15 focus:border-accent-500 overflow-hidden rounded-xl focus:!opacity-100 sm:rounded-2xl transition-opacity duration-500" 46 28 > 47 - <div class="mt-1 text-xl"> 48 - {project.name} 49 - </div> 50 - </div> 51 - 52 - <a href={'/projects/' + project.key}> 53 - <div class="absolute inset-0 rounded-xl"></div> 29 + {#if project.src.endsWith('.mp4')} 30 + <video 31 + autoplay 32 + loop 33 + muted 34 + playsinline 35 + class="absolute inset-0 h-full w-full object-cover rounded-xl group-hover:scale-105 transition-transform duration-200" 36 + preload="none" 37 + > 38 + <source src={project.src} type="video/mp4" /> 39 + </video> 40 + {:else} 41 + <img 42 + src={project.src} 43 + alt="" 44 + class="absolute inset-0 h-full w-full object-cover rounded-xl" 45 + loading="lazy" 46 + /> 47 + {/if} 54 48 <div 55 - class="absolute inset-0 w-full h-full opacity-60 md:opacity-0 group-hover:opacity-80 transition-opacity duration-200 bg-gradient-to-t from-black to-transparent" 56 - ></div> 57 - </a> 49 + class="overflow-hidden absolute z-10 pointer-events-none inset-0 w-full h-full flex items-end px-3 py-2 md:p-4 tracking-tight leading-6 text-white text-xl font-semibold sm:translate-y-20 group-hover:translate-y-0 transition-translation duration-200" 50 + > 51 + <div class="mt-1 text-sm sm:text-lg"> 52 + {project.name} 53 + </div> 54 + </div> 55 + 56 + <a href={'/projects/' + project.key}> 57 + <div class="absolute inset-0 rounded-xl"></div> 58 + <div 59 + class="absolute inset-0 w-full h-full opacity-60 md:opacity-0 group-hover:opacity-80 transition-opacity duration-200 bg-gradient-to-t from-black to-transparent" 60 + ></div> 61 + </a> 62 + </div> 58 63 </div> 59 64 {/each} 60 65 </div>
+1 -1
src/lib/components/Resume.svelte
··· 62 62 ]; 63 63 </script> 64 64 65 - <div class="rounded-2xl border p-6 dark:border-white/10 mt-16 bg-white/5"> 65 + <div class="rounded-2xl border p-6 dark:border-white/15 mt-16 bg-zinc-950"> 66 66 <h2 class="flex text-sm font-semibold text-zinc-900 dark:text-zinc-100 items-center"> 67 67 <svg viewBox="0 0 24 24" fill="none" class="h-6 w-6 flex-none" aria-hidden="true"> 68 68 <path
+82
src/lib/components/ResumeContent.svelte
··· 1 + <script lang="ts"> 2 + //@ts-ignore 3 + import enna from '$lib/images/logos/enna.png?w=112&format=webp'; 4 + //@ts-ignore 5 + import puppet from '$lib/images/logos/puppet.png?w=112&format=webp'; 6 + //@ts-ignore 7 + import tub from '$lib/images/logos/tub.png?w=112&format=webp'; 8 + //@ts-ignore 9 + import hyperlumen from '$lib/images/logos/hyperlumen.png?w=112&format=webp'; 10 + 11 + import Role from './Role.svelte'; 12 + let resume: Array<{ 13 + company: string; 14 + title: string; 15 + logo: string | { src: string; rounded?: boolean }; 16 + start: string | { label: string; dateTime: string }; 17 + end: string | { label: string; dateTime: string }; 18 + }> = [ 19 + { 20 + company: 'hyperlumen', 21 + title: 'co-founder', 22 + logo: { 23 + src: hyperlumen, 24 + rounded: true 25 + }, 26 + start: '2023', 27 + end: { 28 + label: 'present', 29 + dateTime: new Date().getFullYear().toString() 30 + } 31 + }, 32 + { 33 + company: 'enna', 34 + title: 'software engineer', 35 + logo: enna, 36 + start: '2022', 37 + end: { 38 + label: 'present', 39 + dateTime: new Date().getFullYear().toString() 40 + } 41 + }, 42 + { 43 + company: 'puppet', 44 + title: 'co-founder', 45 + logo: puppet, 46 + start: '2022', 47 + end: { 48 + label: 'present', 49 + dateTime: new Date().getFullYear().toString() 50 + } 51 + }, 52 + { 53 + company: 'tu berlin', 54 + title: 'computer science', 55 + logo: tub, 56 + start: '2018', 57 + end: { 58 + label: 'present', 59 + dateTime: new Date().getFullYear().toString() 60 + } 61 + } 62 + ]; 63 + </script> 64 + 65 + <h2 class="flex text-sm font-semibold text-zinc-900 dark:text-zinc-100 items-center h-full w-full"> 66 + <svg viewBox="0 0 24 24" fill="none" class="h-6 w-6 flex-none" aria-hidden="true"> 67 + <path 68 + d="M2.75 9.75a3 3 0 0 1 3-3h12.5a3 3 0 0 1 3 3v8.5a3 3 0 0 1-3 3H5.75a3 3 0 0 1-3-3v-8.5Z" 69 + class="fill-zinc-100 stroke-zinc-400 dark:fill-zinc-100/10 dark:stroke-zinc-500" 70 + /> 71 + <path 72 + d="M3 14.25h6.249c.484 0 .952-.002 1.316.319l.777.682a.996.996 0 0 0 1.316 0l.777-.682c.364-.32.832-.319 1.316-.319H21M8.75 6.5V4.75a2 2 0 0 1 2-2h2.5a2 2 0 0 1 2 2V6.5" 73 + class="stroke-zinc-400 dark:stroke-zinc-500" 74 + /> 75 + </svg> 76 + <span class="ml-3">work & education</span> 77 + </h2> 78 + <ol class="mt-6 space-y-4"> 79 + {#each resume as role} 80 + <Role {role} /> 81 + {/each} 82 + </ol>
-95
src/routes/test/+page.svelte
··· 1 - 2 - <div class="h-full w-full flex items-center justify-center p-20"> 3 - <svg 4 - xmlns="http://www.w3.org/2000/svg" 5 - viewBox="197.118 353.993 729.100 91.712" 6 - class="stroke-[6] max-w-3xl" 7 - style="stroke: url(#gradient);" 8 - > 9 - <linearGradient 10 - id="gradient" 11 - x1="197.118" 12 - y1="0" 13 - x2="926.218" 14 - y2="0" 15 - gradientUnits="userSpaceOnUse" 16 - > 17 - <stop offset="0%" stop-color="#06b6d4"/> 18 - <stop offset="50%" stop-color="#4f46e5"/> 19 - <stop offset="100%" stop-color="#e11d48"/> 20 - <!-- <stop offset="0%" stop-color="rgba(255, 0, 0, 1)"/> 21 - <stop offset="10%" stop-color="rgba(255, 154, 0, 1)"/> 22 - <stop offset="20%" stop-color="rgba(208, 222, 33, 1)"/> 23 - <stop offset="30%" stop-color="rgba(79, 220, 74, 1)"/> 24 - <stop offset="40%" stop-color="rgba(63, 218, 216, 1)"/> 25 - <stop offset="50%" stop-color="rgba(47, 201, 226, 1)"/> 26 - <stop offset="60%" stop-color="rgba(28, 127, 238, 1)"/> 27 - <stop offset="70%" stop-color="rgba(95, 21, 242, 1)"/> 28 - <stop offset="80%" stop-color="rgba(186, 12, 248, 1)"/> 29 - <stop offset="90%" stop-color="rgba(251, 7, 217, 1)"/> 30 - <stop offset="100%" stop-color="rgba(255, 0, 0, 1)"/> --> 31 - </linearGradient> 32 - <g class="paths"> 33 - <path 34 - d="M 200.70,365.61 C 200.26 366.92, 199.99 368.69, 200.18 372.13 C 200.37 375.56, 200.92 377.90, 201.64 382.78 C 202.35 387.66, 202.88 391.11, 203.74 396.53 C 204.61 401.95, 205.02 404.88, 205.95 409.87 C 206.88 414.87, 207.51 417.39, 208.38 421.52 C 209.26 425.65, 209.48 427.56, 210.34 430.53 C 211.20 433.49, 211.70 434.62, 212.69 436.34 C 213.67 438.06, 214.22 438.66, 215.27 439.12 C 216.32 439.58, 217.02 439.61, 217.96 438.64 C 218.90 437.68, 219.43 436.69, 219.98 434.31 C 220.53 431.92, 220.34 430.01, 220.71 426.73 C 221.08 423.45, 221.15 421.23, 221.85 417.89 C 222.55 414.55, 223.30 412.71, 224.23 410.05 C 225.15 407.39, 225.67 406.15, 226.49 404.59 C 227.31 403.02, 227.50 402.54, 228.34 402.23 C 229.19 401.92, 229.70 402.21, 230.71 403.04 C 231.73 403.87, 232.12 404.66, 233.42 406.40 C 234.73 408.14, 235.46 409.31, 237.24 411.73 C 239.02 414.16, 240.39 415.82, 242.32 418.52 C 244.26 421.23, 245.08 422.80, 246.92 425.26 C 248.75 427.71, 249.68 428.81, 251.51 430.80 C 253.35 432.79, 254.14 433.78, 256.09 435.19 C 258.03 436.61, 258.98 437.22, 261.26 437.88 C 263.53 438.54, 264.89 438.68, 267.45 438.48 C 270.01 438.28, 271.39 438.08, 274.05 436.88 C 276.70 435.68, 278.08 434.54, 280.73 432.47 C 283.37 430.41, 284.84 429.08, 287.27 426.56 C 289.70 424.05, 291.00 422.62, 292.90 419.89 C 294.80 417.15, 295.82 415.52, 296.78 412.89 C 297.74 410.26, 297.88 408.81, 297.69 406.72 C 297.51 404.62, 297.05 403.67, 295.87 402.42 C 294.70 401.17, 293.72 400.57, 291.82 400.46 C 289.93 400.35, 288.53 400.66, 286.38 401.87 C 284.24 403.07, 282.96 404.25, 281.11 406.48 C 279.26 408.71, 278.35 410.19, 277.14 413.03 C 275.94 415.86, 275.17 417.60, 275.08 420.65 C 274.98 423.69, 275.32 425.58, 276.68 428.25 C 278.03 430.93, 279.26 432.15, 281.85 434.04 C 284.45 435.92, 286.08 436.57, 289.65 437.68 C 293.23 438.78, 295.50 439.27, 299.71 439.57 C 303.93 439.88, 306.26 439.72, 310.73 439.21 C 315.20 438.69, 317.56 438.21, 322.06 437.00 C 326.57 435.79, 329.08 435.12, 333.26 433.17 C 337.45 431.22, 339.52 430.02, 342.99 427.25 C 346.46 424.47, 348.06 422.83, 350.61 419.30 C 353.16 415.78, 354.24 413.78, 355.72 409.62 C 357.20 405.45, 357.61 402.97, 358.02 398.49 C 358.44 394.02, 358.35 391.49, 357.81 387.24 C 357.27 382.98, 356.66 380.80, 355.33 377.22 C 354.00 373.63, 353.02 372.00, 351.17 369.32 C 349.31 366.64, 348.24 365.48, 346.07 363.83 C 343.89 362.18, 342.59 361.50, 340.29 361.09 C 337.99 360.68, 336.66 360.72, 334.56 361.77 C 332.45 362.82, 331.19 363.67, 329.76 366.32 C 328.33 368.97, 327.89 370.99, 327.39 375.01 C 326.90 379.03, 326.81 381.62, 327.27 386.43 C 327.73 391.24, 328.25 394.21, 329.70 399.07 C 331.16 403.92, 332.23 406.52, 334.56 410.71 C 336.90 414.89, 338.41 416.79, 341.39 420.01 C 344.36 423.22, 346.19 424.69, 349.43 426.77 C 352.67 428.86, 354.42 429.60, 357.60 430.42 C 360.77 431.25, 362.43 431.29, 365.29 430.89 C 368.15 430.49, 369.61 430.00, 371.91 428.43 C 374.22 426.86, 375.23 425.63, 376.80 423.05 C 378.37 420.48, 378.95 418.91, 379.75 415.55 C 380.54 412.19, 380.61 410.05, 380.77 406.26 C 380.93 402.48, 380.82 400.40, 380.54 396.63 C 380.26 392.86, 380.02 390.79, 379.38 387.43 C 378.73 384.08, 378.38 382.32, 377.32 379.88 C 376.25 377.43, 375.51 376.42, 374.05 375.23 C 372.59 374.04, 371.49 373.60, 370.04 373.94 C 368.58 374.28, 367.58 375.00, 366.79 376.93 C 366.00 378.85, 365.81 380.46, 366.10 383.56 C 366.39 386.66, 367.15 388.77, 368.22 392.45 C 369.30 396.12, 370.02 398.28, 371.47 401.91 C 372.93 405.55, 373.84 407.38, 375.50 410.64 C 377.15 413.89, 377.93 415.48, 379.75 418.18 C 381.57 420.88, 382.52 422.08, 384.58 424.15 C 386.65 426.22, 387.81 427.09, 390.09 428.53 C 392.38 429.97, 393.65 430.60, 396.01 431.37 C 398.37 432.15, 399.65 432.48, 401.91 432.41 C 404.16 432.34, 406.24 431.65, 407.27 431.00" 35 - /> 36 - <path 37 - style="--delay: 1.1s" 38 - d="M 436.98,404.86 C 436.51 404.37, 435.97 404.10, 434.69 404.03 C 433.42 403.95, 432.36 403.80, 430.61 404.48 C 428.87 405.16, 427.64 405.87, 425.96 407.41 C 424.29 408.96, 423.25 410.06, 422.24 412.22 C 421.22 414.37, 420.87 415.81, 420.90 418.21 C 420.94 420.61, 421.19 422.17, 422.41 424.22 C 423.63 426.27, 424.71 427.14, 427.01 428.47 C 429.31 429.80, 430.91 430.36, 433.91 430.88 C 436.92 431.41, 438.75 431.39, 442.03 431.10 C 445.31 430.82, 447.14 430.41, 450.31 429.48 C 453.48 428.54, 455.20 428.00, 457.88 426.43 C 460.56 424.87, 461.97 423.78, 463.71 421.64 C 465.44 419.50, 466.12 418.14, 466.55 415.73 C 466.98 413.31, 466.79 411.92, 465.85 409.56 C 464.90 407.20, 463.93 405.80, 461.82 403.91 C 459.71 402.01, 457.98 401.13, 455.29 400.07 C 452.60 399.01, 450.78 398.78, 448.39 398.61 C 446.00 398.43, 444.90 398.76, 443.33 399.18 C 441.76 399.60, 441.04 400.16, 440.54 400.70" 39 - /> 40 - <path 41 - style="--delay: 1.4s" 42 - d="M 562.42,400.80 C 562.14 401.49, 562.23 402.08, 562.48 403.60 C 562.73 405.11, 562.90 406.25, 563.66 408.36 C 564.43 410.47, 565.02 411.86, 566.30 414.16 C 567.58 416.47, 568.42 417.97, 570.05 419.90 C 571.68 421.82, 572.62 422.61, 574.45 423.79 C 576.28 424.96, 577.22 425.42, 579.21 425.76 C 581.20 426.10, 582.32 426.17, 584.41 425.48 C 586.49 424.79, 587.67 423.98, 589.64 422.32 C 591.61 420.67, 592.60 419.40, 594.25 417.19 C 595.90 414.98, 596.87 413.47, 597.90 411.28 C 598.93 409.10, 599.11 407.49, 599.39 406.26 C 599.68 405.02, 599.23 404.76, 599.31 405.10 C 599.39 405.44, 599.12 406.36, 599.79 407.95 C 600.46 409.55, 600.91 411.02, 602.65 413.08 C 604.39 415.14, 605.88 416.55, 608.48 418.24 C 611.08 419.93, 612.69 420.54, 615.67 421.54 C 618.65 422.54, 620.32 422.86, 623.39 423.23 C 626.45 423.60, 628.09 423.70, 630.99 423.41 C 633.90 423.12, 635.45 422.82, 637.91 421.77 C 640.37 420.71, 641.45 419.93, 643.32 418.14 C 645.18 416.35, 646.13 415.16, 647.25 412.82 C 648.36 410.48, 648.52 408.84, 648.88 406.42 C 649.23 404.00, 649.23 402.86, 649.01 400.72 C 648.79 398.58, 648.52 397.48, 647.75 395.74 C 646.98 394.00, 646.37 393.15, 645.15 392.01 C 643.93 390.87, 642.96 390.53, 641.65 390.05 C 640.34 389.57, 639.61 389.54, 638.60 389.62 C 637.60 389.69, 637.14 390.06, 636.62 390.41 C 636.10 390.76, 636.05 391.01, 635.98 391.38 " 43 - /> 44 - <path 45 - style="--delay: 1.8s" 46 - d="M 687.05,397.09 C 687.10 396.35, 686.94 395.47, 686.01 394.45 C 685.08 393.43, 684.22 392.59, 682.39 392.00 C 680.55 391.41, 679.16 391.21, 676.83 391.49 C 674.51 391.76, 673.12 392.11, 670.76 393.39 C 668.40 394.67, 667.04 395.80, 665.02 397.86 C 663.01 399.93, 661.87 401.23, 660.68 403.71 C 659.49 406.20, 659.00 407.77, 659.09 410.27 C 659.17 412.77, 659.63 414.10, 661.10 416.21 C 662.58 418.32, 663.95 419.48, 666.48 420.81 C 669.02 422.15, 670.61 422.43, 673.78 422.90 C 676.94 423.37, 678.94 423.31, 682.32 423.15 C 685.69 422.99, 687.65 422.87, 690.65 422.10 C 693.64 421.33, 694.98 420.63, 697.30 419.30 C 699.62 417.97, 700.76 417.20, 702.23 415.45 C 703.70 413.69, 704.29 412.54, 704.64 410.52 C 704.99 408.51, 704.73 407.34, 703.97 405.39 C 703.20 403.43, 702.45 402.32, 700.79 400.75 C 699.14 399.17, 697.93 398.51, 695.69 397.49 " 47 - /> 48 - <path 49 - 50 - style="--delay: 2.0s" 51 - d="M 714.71,395.76 C 714.21 396.26, 713.93 396.81, 713.73 398.19 C 713.54 399.57, 713.51 400.64, 713.75 402.67 C 714.00 404.69, 714.34 406.09, 714.97 408.33 C 715.60 410.56, 716.03 411.90, 716.91 413.84 C 717.78 415.77, 718.36 416.81, 719.36 418.00 C 720.36 419.18, 720.93 419.63, 721.90 419.76 C 722.87 419.90, 723.56 419.60, 724.22 418.67 C 724.89 417.73, 725.10 416.85, 725.21 415.08 C 725.33 413.31, 725.11 411.95, 724.81 409.81 C 724.51 407.67, 724.01 406.34, 723.73 404.39 C 723.45 402.44, 723.28 401.52, 723.43 400.06 C 723.57 398.60, 723.76 398.01, 724.46 397.08 C 725.17 396.15, 725.61 395.95, 726.96 395.41 C 728.31 394.87, 729.21 394.75, 731.21 394.39 C 733.21 394.04, 734.47 393.89, 736.96 393.63 C 739.45 393.37, 740.90 393.26, 743.67 393.09 C 746.43 392.92, 748.16 392.97, 750.81 392.77 " 52 - /> 53 - <path 54 - style="--delay: 2.2s" 55 - d="M 770.66,372.10 C 770.12 372.85, 769.64 373.70, 769.51 375.90 C 769.39 378.09, 769.59 379.78, 770.03 383.07 C 770.48 386.37, 770.92 388.62, 771.74 392.37 C 772.56 396.12, 773.18 398.20, 774.15 401.81 C 775.12 405.43, 775.51 407.42, 776.58 410.47 C 777.65 413.52, 778.32 414.83, 779.49 417.06 C 780.66 419.29, 781.14 420.14, 782.42 421.61 C 783.71 423.07, 784.99 424.04, 785.91 424.39 C 786.84 424.73, 787.28 424.24, 787.07 423.33 " 56 - /> 57 - <path 58 - style="--delay: 2.4s" 59 - d="M 831.93,412.49 C 831.90 411.74, 831.59 410.93, 830.60 409.98 C 829.60 409.03, 828.81 408.41, 826.95 407.74 C 825.09 407.07, 823.74 406.60, 821.31 406.64 C 818.89 406.67, 817.39 407.19, 814.82 407.94 C 812.25 408.69, 810.89 409.21, 808.47 410.39 C 806.04 411.58, 804.61 412.27, 802.71 413.85 C 800.80 415.44, 799.84 416.55, 798.94 418.32 C 798.05 420.10, 797.88 421.05, 798.24 422.74 C 798.59 424.42, 799.20 425.40, 800.72 426.75 C 802.24 428.10, 803.51 428.80, 805.83 429.50 C 808.15 430.20, 809.61 430.32, 812.31 430.24 C 815.01 430.16, 816.61 429.85, 819.31 429.10 C 822.01 428.35, 823.36 427.80, 825.79 426.50 C 828.23 425.20, 829.38 424.52, 831.49 422.60 C 833.60 420.68, 834.72 419.48, 836.35 416.90 C 837.97 414.32, 838.59 412.77, 839.62 409.70 C 840.64 406.63, 840.99 404.87, 841.46 401.56 C 841.93 398.24, 841.96 396.31, 841.98 393.12 C 842.00 389.93, 841.97 388.11, 841.56 385.62 C 841.15 383.13, 840.55 381.90, 839.94 380.67 C 839.32 379.44, 838.85 379.13, 838.50 379.47 C 838.14 379.81, 837.82 380.58, 838.16 382.37 C 838.51 384.15, 838.96 385.55, 840.23 388.41 C 841.49 391.26, 842.74 393.17, 844.47 396.64 C 846.20 400.10, 847.21 402.14, 848.88 405.73 C 850.54 409.32, 851.30 411.24, 852.78 414.59 C 854.27 417.93, 854.95 419.71, 856.30 422.46 C 857.65 425.20, 858.42 426.46, 859.53 428.31 C 860.64 430.17, 861.13 430.78, 861.86 431.73 C 862.59 432.68, 862.79 432.74, 863.19 433.06 C 863.59 433.39, 863.64 433.34, 863.87 433.35 C 864.09 433.37, 864.19 433.31, 864.32 433.13 C 864.45 432.94, 864.51 432.98, 864.51 432.44 " 60 - /> 61 - <path 62 - style="--delay: 2.8s" 63 - d="M 909.81,357.64 C 909.30 358.49, 909.06 359.62, 908.91 361.81 C 908.76 363.99, 908.89 365.66, 909.07 368.58 C 909.25 371.50, 909.51 373.23, 909.80 376.41 C 910.08 379.58, 910.13 381.38, 910.49 384.46 C 910.86 387.54, 911.15 389.05, 911.63 391.81 C 912.11 394.58, 912.41 396.07, 912.91 398.29 C 913.41 400.52, 913.64 401.44, 914.14 402.94 C 914.64 404.44, 914.91 405.27, 915.41 405.80 C 915.92 406.34, 916.34 406.27, 916.66 405.61 " 64 - /> 65 - <path 66 - style="--delay: 2.9s" 67 - d="M 920.82,441.46 C 920.47 441.77, 920.59 442.48, 921.03 442.65 C 921.47 442.81, 922.66 442.60, 923.01 442.29 C 923.37 441.99, 923.24 441.28, 922.80 441.11 C 922.36 440.95, 921.17 441.16, 920.82 441.46" 68 - /> 69 - </g> 70 - </svg> 71 - </div> 72 - 73 - <style> 74 - .paths path { 75 - --line-length: 700; 76 - --delay: 0s; 77 - --animation-speed: 1s; 78 - 79 - stroke-dasharray: var(--line-length); 80 - stroke-dashoffset: var(--line-length); 81 - animation: drawPath var(--animation-speed) linear 1 forwards; 82 - animation-delay: var(--delay); 83 - 84 - stroke-linecap: round; 85 - } 86 - 87 - @keyframes drawPath { 88 - 0% { 89 - stroke-dashoffset: var(--line-length); 90 - } 91 - 100% { 92 - stroke-dashoffset: 0; 93 - } 94 - } 95 - </style>
+1 -1
src/lib/components/project/ProjectTiered.svelte
··· 34 34 : ''} lg:gap-8" 35 35 > 36 36 {#if project.demo == 'swiper'} 37 - <div class="rounded-xl h-[60vh] md:h-[70vh] lg:col-span-2 lg:row-span-2"> 37 + <div class="rounded-xl h-full lg:col-span-2 lg:row-span-2"> 38 38 <Swiper /> 39 39 </div> 40 40 {:else if project.demo == 'autostereogram'}
+59 -43
src/lib/components/project/demos/swiper.svelte
··· 2 2 import { onMount } from 'svelte'; 3 3 import { CardSwiper } from './CardSwiper'; 4 4 5 - //@ts-expect-error - not found 6 - import person1 from './CardSwiper/images/1.jpg?format=webp&w=512'; 7 - //@ts-expect-error - not found 8 - import person2 from './CardSwiper/images/2.jpg?format=webp&w=512'; 9 - //@ts-expect-error - not found 10 - import person3 from './CardSwiper/images/3.jpg?format=webp&w=512'; 11 - //@ts-expect-error - not found 12 - import person4 from './CardSwiper/images/4.jpg?format=webp&w=512'; 13 - //@ts-expect-error - not found 14 - import person5 from './CardSwiper/images/5.jpg?format=webp&w=512'; 15 - //@ts-expect-error - not found 16 - import person6 from './CardSwiper/images/6.jpg?format=webp&w=512'; 17 - //@ts-expect-error - not found 18 - import person7 from './CardSwiper/images/7.jpg?format=webp&w=512'; 19 - //@ts-expect-error - not found 20 - import person8 from './CardSwiper/images/8.jpg?format=webp&w=512'; 21 - //@ts-expect-error - not found 22 - import person9 from './CardSwiper/images/9.jpg?format=webp&w=512'; 5 + //@ts-expect-error - not found 6 + import person1 from './CardSwiper/images/1.jpg?format=webp&w=512'; 7 + //@ts-expect-error - not found 8 + import person2 from './CardSwiper/images/2.jpg?format=webp&w=512'; 9 + //@ts-expect-error - not found 10 + import person3 from './CardSwiper/images/3.jpg?format=webp&w=512'; 11 + //@ts-expect-error - not found 12 + import person4 from './CardSwiper/images/4.jpg?format=webp&w=512'; 13 + //@ts-expect-error - not found 14 + import person5 from './CardSwiper/images/5.jpg?format=webp&w=512'; 15 + //@ts-expect-error - not found 16 + import person6 from './CardSwiper/images/6.jpg?format=webp&w=512'; 17 + //@ts-expect-error - not found 18 + import person7 from './CardSwiper/images/7.jpg?format=webp&w=512'; 19 + //@ts-expect-error - not found 20 + import person8 from './CardSwiper/images/8.jpg?format=webp&w=512'; 21 + //@ts-expect-error - not found 22 + import person9 from './CardSwiper/images/9.jpg?format=webp&w=512'; 23 23 24 - let people = [person1, person2, person3, person4, person5, person6, person7, person8, person9]; 24 + let people = [person1, person2, person3, person4, person5, person6, person7, person8, person9]; 25 25 26 - function getRandomPerson(): { firstName: string; lastName: string; age: number } { 27 - const firstNames = ['John', 'Jane', 'Alice', 'Bob', 'Mary', 'Tom']; 28 - const lastNames = ['Smith', 'Doe', 'Johnson', 'White', 'Brown', 'Davis']; 29 - 30 - const firstNameIndex = Math.floor(Math.random() * firstNames.length); 31 - const lastNameIndex = Math.floor(Math.random() * lastNames.length); 32 - 33 - const age = Math.floor(Math.random() * (60 - 18 + 1)) + 18; 34 - 35 - return { 36 - firstName: firstNames[firstNameIndex], 37 - lastName: lastNames[lastNameIndex], 38 - age: age 39 - }; 40 - } 26 + function getRandomPerson(): { firstName: string; lastName: string; age: number } { 27 + const firstNames = ['John', 'Jane', 'Alice', 'Bob', 'Mary', 'Tom']; 28 + const lastNames = ['Smith', 'Doe', 'Johnson', 'White', 'Brown', 'Davis']; 41 29 30 + const firstNameIndex = Math.floor(Math.random() * firstNames.length); 31 + const lastNameIndex = Math.floor(Math.random() * lastNames.length); 32 + 33 + const age = Math.floor(Math.random() * (60 - 18 + 1)) + 18; 34 + 35 + return { 36 + firstName: firstNames[firstNameIndex], 37 + lastName: lastNames[lastNameIndex], 38 + age: age 39 + }; 40 + } 42 41 43 42 let data = (index: number) => { 44 - let person = getRandomPerson(); 43 + let person = getRandomPerson(); 45 44 return { 46 45 title: `${person.firstName} ${person.lastName}, ${person.age}`, 47 46 description: 'swipe left or right', 48 - image: people[index % people.length] 47 + image: people[index % people.length] 49 48 }; 50 49 }; 51 50 52 - onMount(() => { 53 - // preload images 54 - people.forEach((person) => { 55 - new Image().src = person; 56 - }); 57 - }); 51 + onMount(() => { 52 + // preload images 53 + people.forEach((person) => { 54 + new Image().src = person; 55 + }); 56 + }); 58 57 </script> 59 58 60 - <CardSwiper cardData={data} /> 59 + <div class="mx-auto h-[712px] w-[350px] max-w-full rounded-[60px] bg-cyan-500 relative"> 60 + <div class="absolute top-20 h-8 w-3 bg-cyan-500 -left-0.5 rounded-sm"></div> 61 + <div class="absolute top-[140px] h-14 w-3 bg-cyan-500 -left-[3px] rounded-sm"></div> 62 + <div class="absolute top-[210px] h-14 w-3 bg-cyan-500 -left-[3px] rounded-sm"></div> 63 + <div class="absolute top-[180px] h-20 w-3 bg-cyan-500 -right-[3px] rounded-sm"></div> 64 + 65 + <div class="absolute top-[18px] z-10 flex justify-center w-full"> 66 + <div class="h-7 w-24 bg-black rounded-full"></div> 67 + </div> 68 + 69 + <div class="absolute top-[180px] h-20 w-3 bg-cyan-500 -right-[3px] rounded-sm"></div> 70 + 71 + <div class="absolute inset-0 w-full h-full p-3"> 72 + <div class="bg-cyan-200 w-full h-full rounded-[50px] overflow-hidden relative"> 73 + <CardSwiper cardData={data} /> 74 + </div> 75 + </div> 76 + </div>
+2 -2
src/lib/components/project/demos/CardSwiper/Card.svelte
··· 10 10 </script> 11 11 12 12 <div 13 - class="w-full h-full absolute cursor-grab ease-in-out rounded-xl touch-none select-none border border-white/20 bg-black {color}" 13 + class="w-full h-full absolute cursor-grab ease-in-out rounded-xl touch-none select-none {color}" 14 14 bind:this={element} 15 15 > 16 16 {#key image} ··· 19 19 {/if} 20 20 {/key} 21 21 <div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/0 rounded-b-xl"></div> 22 - <div class="p-4 absolute bottom-0 w-full flex justify-center text-white"> 22 + <div class="p-4 absolute bottom-4 w-full flex justify-center text-white"> 23 23 <div class="flex items-center flex-col"> 24 24 <h3 class="text-3xl font-semibold pb-4">{title}</h3> 25 25 <p>{description}</p>