[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 #18 from flo-bit/main

update projects, add depth 3d avatar

authored by

Florian and committed by
GitHub
(Jun 21, 2024, 11:33 PM +0200) 1fe56d8c b0d2baca

+309 -122
+20 -4
src/lib/components/About.svelte
··· 1 1 <script lang="ts"> 2 + import Depth3D from '$lib/3D/Depth3D/Depth3D.svelte'; 3 + 2 4 // @ts-ignore 3 5 import imageMe from '$lib/images/avatar.png?w=1024&format=webp'; 6 + // @ts-ignore 7 + import depthMe from '$lib/images/avatar-depth.png?w=1024&format=webp'; 8 + 4 9 import Resume from './Resume.svelte'; 5 10 </script> 6 11 ··· 9 14 <div id="about" class="py-16 md:py-32 section"> 10 15 <div class="grid grid-cols-1 gap-y-16 lg:grid-cols-2 lg:grid-rows-[auto_1fr] lg:gap-y-12"> 11 16 <div class="lg:pl-20"> 12 - <div class="max-w-xs px-2.5 lg:max-w-none"> 13 - <img 17 + <div class="max-w-sm px-2.5 lg:max-w-none"> 18 + <!-- <img 14 19 src={imageMe} 15 20 alt="this is me" 16 21 loading="lazy" 17 22 sizes="(min-width: 1024px) 32rem, 20rem" 18 23 class="aspect-square rotate-3 rounded-2xl bg-zinc-100 object-cover dark:bg-zinc-800" 19 - /> 24 + /> --> 25 + 26 + <div class="aspect-square rotate-3 -m-10 lg:-m-10"> 27 + <Depth3D 28 + image={{ 29 + image: imageMe, 30 + depth: depthMe 31 + }} 32 + /> 33 + <div class="sr-only">this is me</div> 34 + </div> 20 35 </div> 21 36 </div> 22 37 <div class="lg:order-first lg:row-span-2"> 23 38 <h1 24 39 class="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl" 25 40 > 26 - hey there, i'm florian. i live in berlin, where i create things for the web (and other places). 41 + hey there, i'm florian. i live in berlin, where i create things for the web (and other 42 + places). 27 43 </h1> 28 44 <div class="mt-6 space-y-7 text-base text-zinc-600 dark:text-zinc-400"> 29 45 <p>
+128 -118
src/lib/components/Projects.svelte
··· 1 1 <script lang="ts"> 2 - import Photos from '$lib/components/Photos.svelte'; 2 + import svelteswipecards from '$lib/images/projects-new/svelte-swiper-cards-demo.mp4'; 3 + import fluidtexteffect from '$lib/images/projects-new/text-effect-fluid-demo.mp4'; 4 + import fake3d from '$lib/images/projects-new/fake3dimage-demo.mp4'; 5 + import hyperlumen from '$lib/images/projects-new/hyperlumen-demo.mp4'; 6 + import marblellous from '$lib/images/projects-new/marblellous-demo.mp4'; 7 + import oldcode from '$lib/images/projects-new/old-code-demo.mp4'; 8 + import autostereogramrenderer from '$lib/images/projects-new/autostereogram-renderer-demo.mp4'; 9 + import mandala from '$lib/images/projects-new/mandala-demo.mp4'; 3 10 4 - const projects: { 5 - name: string; 6 - description: string; 7 - link?: { href: string; label: string }; 8 - logo?: string; 9 - }[] = [ 10 - { 11 - name: 'svelte swipe cards', 12 - description: 'a swipeable tinder like card component for svelte.', 13 - link: { href: 'https://github.com/flo-bit/svelte-swiper-cards/', label: 'github.com' } 14 - }, 15 - { 16 - name: 'text effect fluid', 17 - description: "text effect that looks like it's some kind of fluid.", 18 - link: { href: 'https://github.com/flo-bit/text_effect_fluid', label: 'github.com' } 19 - }, 20 - { 21 - name: 'hyperlumen', 22 - description: 23 - "light-up clothes that make you feel like you're in a sci-fi movie. perfect for raves.", 24 - link: { href: 'http://hyperlumen.de', label: 'hyperlumen.de' } 25 - }, 26 - { 27 - name: 'image2fake3d', 28 - description: 29 - 'turns an image into a fake 3d image that you can rotate with your mouse or gyro sensor.', 30 - link: { href: 'https://github.com/flo-bit/image2fake3d', label: 'github.com' } 31 - }, 32 - { 33 - name: 'marblellous', 34 - description: 35 - 'simple 3d browser game made with threlte. inspired by the game "marble blast gold".', 36 - link: { href: 'https://github.com/flo-bit/ball-game', label: 'github.com' } 37 - }, 38 - { 39 - name: 'old coding projects', 40 - description: "Some of my old coding projects. Please don't look at the code.", 41 - link: { href: 'https://github.com/flo-bit/old-code', label: 'github.com' } 42 - } 43 - ]; 44 11 45 - //@ts-ignore 46 - import hyperlumen from '$lib/images/projects/hyperlumen.jpeg?w=1024&format=webp'; 47 - //@ts-ignore 48 - import ballgame from '$lib/images/projects/ball-game.png?w=1024&format=webp'; 49 - //@ts-ignore 50 - import oldprojects from '$lib/images/projects/old-projects.png?w=1024&format=webp'; 51 - 52 - import svelteswipecards from '$lib/images/projects/svelte-swipe-cards-squared.mp4'; 53 - 54 - import fluidtexteffect from '$lib/images/projects/fluid-text-effect-squared.mp4'; 55 - 56 - import fake3d from '$lib/images/projects/fake3d-squared.mp4'; 57 - 58 - let images: { 12 + let projects: { 59 13 src: string; 60 14 href?: string; 61 15 alt: string; 16 + aspect?: string; 17 + name?: string; 18 + description?: string; 19 + code?: string; 62 20 }[] = [ 63 21 { 64 22 src: svelteswipecards, 65 - alt: 'svelte-swipe-cards', 66 - href: 'https://flo-bit.github.io/svelte-swiper-cards/' 23 + alt: 'svelte-swiper-cards', 24 + href: 'https://flo-bit.github.io/svelte-swiper-cards/', 25 + aspect: 'aspect-[9/18]', 26 + name: 'svelte swipable card component', 27 + description: 'a swipeable tinder like card component for svelte.', 28 + code: 'https://github.com/flo-bit/svelte-swiper-cards/' 67 29 }, 68 30 { 69 31 src: fluidtexteffect, 70 32 alt: 'Text Fluid Effect', 71 - href: 'https://flo-bit.github.io/text_effect_fluid/' 33 + href: 'https://flo-bit.github.io/text_effect_fluid/', 34 + aspect: 'aspect-[23/9]', 35 + name: 'fluid text effect', 36 + code: 'https://github.com/flo-bit/text_effect_fluid' 72 37 }, 73 38 { 74 39 src: hyperlumen, 75 40 alt: 'Hyperlumen', 76 - href: 'https://hyperlumen.de' 41 + href: 'https://hyperlumen.de', 42 + aspect: 'aspect-[9/14]', 43 + name: 'hyperlumen', 44 + description: 45 + "light-up clothes that make you feel like you're in a sci-fi movie. perfect for raves." 77 46 }, 78 47 { 79 48 src: fake3d, 80 49 alt: 'Image2Fake3D', 81 - href: 'https://flo-bit.github.io/image2fake3d/' 50 + href: 'https://flo-bit.github.io/image2fake3d/', 51 + aspect: 'aspect-[9/16]', 52 + name: 'image2fake3d', 53 + description: 54 + 'turns an image into a fake 3d image that you can rotate with your mouse or gyro sensor.', 55 + code: 'https://github.com/flo-bit/image2fake3d' 82 56 }, 83 57 { 84 - src: ballgame, 85 - alt: 'Ball Game', 86 - href: 'https://flo-bit.github.io/ball-game/' 58 + src: marblellous, 59 + alt: 'marblellous', 60 + href: 'https://flo-bit.github.io/ball-game/', 61 + aspect: 'aspect-[9/10]', 62 + name: 'marblellous', 63 + description: 64 + 'simple 3d browser game made with threlte. inspired by the game "marble blast gold".', 65 + code: 'https://github.com/flo-bit/ball-game' 87 66 }, 88 67 { 89 - src: oldprojects, 90 - alt: 'Old Projects', 91 - href: 'https://flo-bit.github.io/old-code/' 92 - } 68 + src: oldcode, 69 + alt: 'old projects', 70 + href: 'https://flo-bit.github.io/old-code/', 71 + aspect: 'aspect-[16/11]', 72 + name: 'old coding projects', 73 + code: 'https://github.com/flo-bit/old-code' 74 + }, 75 + // { 76 + // src: mandala, 77 + // alt: 'mandala', 78 + // href: 'https://flo-bit.github.io/mandala/', 79 + // aspect: 'aspect-square', 80 + // name: 'mandala', 81 + // description: 'draw svg mandalas in the browser.' 82 + // }, 83 + // { 84 + // src: autostereogramrenderer, 85 + // alt: 'autostereogram renderer', 86 + // href: 'https://flo-bit.github.io/autostereogram-renderer/', 87 + // aspect: 'aspect-square', 88 + // name: 'autostereogram renderer', 89 + // description: 'rendering a 3d scene as an autostereogram.' 90 + // }, 93 91 ]; 94 92 </script> 95 93 96 94 <div id="projects" class="z-20 py-16 md:py-32 section bg-black relative isolate"> 97 95 <div class="mx-auto max-w-5xl px-6 lg:px-8"> 98 - <div class="max-w-2xl"> 96 + <div class="max-w-2xl mb-8"> 99 97 <h1 class="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl"> 100 98 things i've made 101 99 </h1> ··· 105 103 code and feel free to contribute. 106 104 </p> 107 105 </div> 108 - </div> 109 106 110 - <Photos {images} /> 111 - <div class="mx-auto max-w-5xl px-6 lg:px-8"> 112 - <ul 113 - role="list" 114 - class="mt-20 px-0 sm:px-6 lg:px-0 grid grid-cols-1 gap-x-12 gap-y-16 sm:grid-cols-2 lg:grid-cols-3" 115 - > 116 - {#each projects as project} 117 - <div class="group relative flex flex-col items-start"> 118 - {#if project.logo} 119 - <div 120 - class="relative z-10 flex h-12 w-12 items-center justify-center rounded-full bg-white shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0" 107 + <div class="columns-2 md:columns-4 gap-4"> 108 + {#each projects as project, index} 109 + <div 110 + class="group relative {project.aspect ?? 111 + 'aspect-square'} mb-4 w-full flex-none overflow-hidden rounded-xl ring-1 ring-white/10 bg-zinc-100 dark:bg-zinc-800 sm:rounded-2xl" 112 + > 113 + {#if project.src.endsWith('.mp4')} 114 + <video 115 + autoplay 116 + loop 117 + muted 118 + playsinline 119 + class="absolute inset-0 h-full w-full object-cover rounded-xl" 120 + preload="none" 121 121 > 122 - <img src={project.logo} alt="" class="h-12 w-12 rounded-full" /> 123 - </div> 122 + <source src={project.src} type="video/mp4" /> 123 + </video> 124 + {:else} 125 + <img 126 + src={project.src} 127 + alt={project.alt} 128 + class="absolute inset-0 h-full w-full object-cover rounded-xl" 129 + loading="lazy" 130 + /> 124 131 {/if} 125 - <h2 126 - class="{project.logo 127 - ? 'mt-6' 128 - : ''} text-base font-semibold text-zinc-800 dark:text-zinc-100" 129 - > 130 - {#if project.link} 131 - <a href={project.link.href} target="_blank"> 132 - <div 133 - class="absolute -inset-x-4 -inset-y-6 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 dark:bg-zinc-800/50 sm:-inset-x-6 sm:rounded-2xl" 134 - /> 135 - <span class="absolute -inset-x-4 -inset-y-6 z-20 sm:-inset-x-6 sm:rounded-2xl" /> 136 - <span class="relative z-10">{project.name}</span> 137 - </a> 138 - {:else} 139 - <div 140 - class="absolute -inset-x-4 -inset-y-6 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 dark:bg-zinc-800/50 sm:-inset-x-6 sm:rounded-2xl" 141 - /> 142 - <span class="absolute -inset-x-4 -inset-y-6 z-20 sm:-inset-x-6 sm:rounded-2xl" /> 143 - <span class="relative z-10">{project.name}</span> 144 - {/if} 145 - </h2> 146 - <div class="relative z-10 mt-2 text-sm text-zinc-600 dark:text-zinc-400"> 147 - {project.description} 148 - </div> 149 - {#if project.link} 150 - <p 151 - class="relative z-10 mt-6 flex text-sm font-medium text-zinc-400 transition group-hover:text-cyan-400 dark:text-zinc-200" 132 + {#if project.href} 133 + <div 134 + class="overflow-hidden absolute z-10 pointer-events-none inset-0 w-full h-full flex items-end p-2 md:p-4 tracking-tight leading-6 text-white text-xl font-semibold opacity-80 md:opacity-0 group-hover:opacity-100 transition-opacity duration-200" 152 135 > 153 - <svg viewBox="0 0 24 24" aria-hidden="true" class="h-6 w-6 flex-none"> 154 - <path 155 - d="M15.712 11.823a.75.75 0 1 0 1.06 1.06l-1.06-1.06Zm-4.95 1.768a.75.75 0 0 0 1.06-1.06l-1.06 1.06Zm-2.475-1.414a.75.75 0 1 0-1.06-1.06l1.06 1.06Zm4.95-1.768a.75.75 0 1 0-1.06 1.06l1.06-1.06Zm3.359.53-.884.884 1.06 1.06.885-.883-1.061-1.06Zm-4.95-2.12 1.414-1.415L12 6.344l-1.415 1.413 1.061 1.061Zm0 3.535a2.5 2.5 0 0 1 0-3.536l-1.06-1.06a4 4 0 0 0 0 5.656l1.06-1.06Zm4.95-4.95a2.5 2.5 0 0 1 0 3.535L17.656 12a4 4 0 0 0 0-5.657l-1.06 1.06Zm1.06-1.06a4 4 0 0 0-5.656 0l1.06 1.06a2.5 2.5 0 0 1 3.536 0l1.06-1.06Zm-7.07 7.07.176.177 1.06-1.06-.176-.177-1.06 1.06Zm-3.183-.353.884-.884-1.06-1.06-.884.883 1.06 1.06Zm4.95 2.121-1.414 1.414 1.06 1.06 1.415-1.413-1.06-1.061Zm0-3.536a2.5 2.5 0 0 1 0 3.536l1.06 1.06a4 4 0 0 0 0-5.656l-1.06 1.06Zm-4.95 4.95a2.5 2.5 0 0 1 0-3.535L6.344 12a4 4 0 0 0 0 5.656l1.06-1.06Zm-1.06 1.06a4 4 0 0 0 5.657 0l-1.061-1.06a2.5 2.5 0 0 1-3.535 0l-1.061 1.06Zm7.07-7.07-.176-.177-1.06 1.06.176.178 1.06-1.061Z" 156 - fill="currentColor" 157 - /> 158 - </svg> 159 - <span class="ml-2">{project.link.label}</span> 160 - </p> 136 + <div> 137 + {#if project.code && false} 138 + <a 139 + href={project.code} 140 + target="_blank" 141 + class="pointer-events-auto hover:opacity-60 transition-opacity duration-200" 142 + > 143 + <svg fill="currentColor" viewBox="0 0 24 24" aria-hidden="true" class="size-6"> 144 + <path 145 + fill-rule="evenodd" 146 + d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" 147 + clip-rule="evenodd" 148 + /> 149 + </svg> 150 + </a> 151 + {/if} 152 + <div class="mt-1"> 153 + {project.name} 154 + </div> 155 + 156 + {#if project.description} 157 + <div class="text-sm font-normal mt-2"> 158 + {project.description} 159 + </div> 160 + {/if} 161 + </div> 162 + </div> 163 + 164 + <a href={project.href} target="_blank"> 165 + <div class="sr-only">{project.alt}</div> 166 + <div class="absolute inset-0 rounded-xl"></div> 167 + <div 168 + 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" 169 + ></div> 170 + </a> 161 171 {/if} 162 172 </div> 163 173 {/each} 164 - </ul> 174 + </div> 165 175 </div> 166 176 </div>
src/lib/images/avatar-depth.png

This is a binary file and will not be displayed.

src/lib/images/avatar-no-bg.png

This is a binary file and will not be displayed.

src/lib/images/avatar-no-bg2.png

This is a binary file and will not be displayed.

src/lib/images/avatar2-depth.png

This is a binary file and will not be displayed.

src/lib/images/avatar2.png

This is a binary file and will not be displayed.

+13
src/lib/3D/Depth3D/Depth3D.svelte
··· 1 + <script lang="ts"> 2 + import { Canvas } from '@threlte/core'; 3 + import Scene3D from './Scene3D.svelte'; 4 + 5 + export let image: { 6 + image: string; 7 + depth: string; 8 + }; 9 + </script> 10 + 11 + <Canvas> 12 + <Scene3D {image} {...$$restProps} /> 13 + </Canvas>
+146
src/lib/3D/Depth3D/Scene3D.svelte
··· 1 + <script lang="ts"> 2 + import { T, useTask } from '@threlte/core'; 3 + import { useTexture, Align, OrbitControls } from '@threlte/extras'; 4 + import { spring } from 'svelte/motion'; 5 + 6 + import { Vector2, ShaderMaterial, PlaneGeometry, LinearSRGBColorSpace } from 'three'; 7 + 8 + type DepthImage = { 9 + image: string; 10 + depth: string; 11 + }; 12 + export let image: DepthImage; 13 + 14 + export let rounded = true; 15 + 16 + export let cameraPosition: [number, number, number] = [0, 0, 10]; 17 + 18 + export let rotationScale = 0.2; 19 + export let rotationSpeed = 2; 20 + 21 + export let detail = 1000; 22 + 23 + export let depthScale = 1; 24 + 25 + const map = useTexture(image.image, { 26 + transform: (texture) => { 27 + texture.colorSpace = LinearSRGBColorSpace; 28 + //texture.encoding = LinearEncoding; 29 + return texture; 30 + } 31 + }); 32 + const depthMap = useTexture(image.depth, { 33 + transform: (texture) => { 34 + //texture.encoding = LinearEncoding; 35 + return texture; 36 + } 37 + }); 38 + 39 + const rotation = new Vector2(0.5, 0.5); 40 + 41 + const uniforms = { 42 + uTexture: { type: 't', value: map }, 43 + depthMap: { type: 't', value: depthMap } 44 + }; 45 + const material = new ShaderMaterial({ 46 + uniforms: uniforms, 47 + vertexShader: ` 48 + varying vec2 vUv; 49 + uniform sampler2D depthMap; 50 + 51 + void main() { 52 + vUv = uv; 53 + // move z position based on the depth map 54 + float depth = texture2D(depthMap, vUv).r; 55 + vec3 newPosition = position + vec3(0.0, 0.0, depth * ${depthScale.toFixed(1)}); 56 + gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0); 57 + }`, 58 + fragmentShader: ` 59 + uniform sampler2D uTexture; 60 + varying vec2 vUv; 61 + 62 + float sdRoundedRect(vec2 p, vec2 b, float r) { 63 + vec2 q = abs(p) - b + vec2(r); 64 + return length(max(q, 0.0)) - r; 65 + } 66 + 67 + void main() { 68 + ${ 69 + rounded 70 + ? ` 71 + vec2 uv = (vUv * 2.0) - 1.0; 72 + 73 + // Size of the rectangle (half-size) 74 + vec2 rectSize = vec2(1, 1); 75 + 76 + // Calculate distance to the edge of the rounded rectangle 77 + float d = sdRoundedRect(uv, rectSize, 0.1); 78 + 79 + // Smooth transition for anti-aliasing 80 + float aa = fwidth(d); 81 + float alpha = smoothstep(0.0, aa, -d); 82 + 83 + gl_FragColor = texture2D(uTexture, vUv) * alpha; 84 + ` 85 + : '' 86 + } 87 + 88 + //gl_FragColor = texture2D(uTexture, vUv); 89 + }` 90 + }); 91 + 92 + const geometry = new PlaneGeometry(7, 7, detail, detail); 93 + 94 + 95 + let rotationX = spring(); 96 + let rotationY = spring(); 97 + 98 + export let time = 0; 99 + const { stop, start } = useTask((dt) => { 100 + if (mouseMoved > 0) { 101 + mouseMoved -= dt; 102 + } else { 103 + time += dt * rotationSpeed; 104 + $rotationX = Math.sin(time) * 0.5; 105 + $rotationY = Math.cos(time) * 0.5; 106 + } 107 + }); 108 + 109 + let mouseMoved = -1; 110 + 111 + function onDocumentMouseMove(event: MouseEvent) { 112 + // convert to [-0.5, 0.5] 113 + $rotationX = (event.clientX / window.innerWidth - 0.5) * 2; 114 + $rotationY = (event.clientY / window.innerHeight - 0.5) * 2; 115 + 116 + mouseMoved = 1; 117 + } 118 + 119 + </script> 120 + 121 + <svelte:window on:mousemove={onDocumentMouseMove} /> 122 + 123 + <T.PerspectiveCamera makeDefault position={cameraPosition}> 124 + </T.PerspectiveCamera> 125 + 126 + {#await map then mapValue} 127 + {#await depthMap then depthValue} 128 + <Align> 129 + <T.Mesh 130 + rotation.x={$rotationY * rotationScale} 131 + rotation.y={$rotationX * rotationScale} 132 + scale.x={mapValue.image.width / mapValue.image.height} 133 + > 134 + <T is={geometry} /> 135 + <T 136 + is={material} 137 + uniforms={{ 138 + depthMap: { value: depthValue }, 139 + uTexture: { value: mapValue }, 140 + mouse: { value: rotation } 141 + }} 142 + /> 143 + </T.Mesh> 144 + </Align> 145 + {/await} 146 + {/await}
+2
src/lib/3D/Depth3D/index.ts
··· 1 + export { default as Depth3D } from './Depth3D.svelte'; 2 + export { default } from './Depth3D.svelte';
src/lib/images/projects-new/autostereogram-renderer-demo.mp4

This is a binary file and will not be displayed.

src/lib/images/projects-new/autostereogram-renderer-image.png

This is a binary file and will not be displayed.

src/lib/images/projects-new/fake3dimage-demo.mp4

This is a binary file and will not be displayed.

src/lib/images/projects-new/fake3dimage-image.png

This is a binary file and will not be displayed.

src/lib/images/projects-new/hyperlumen-demo.mp4

This is a binary file and will not be displayed.

src/lib/images/projects-new/hyperlumen-image.png

This is a binary file and will not be displayed.

src/lib/images/projects-new/mandala-demo.mp4

This is a binary file and will not be displayed.

src/lib/images/projects-new/mandala-image.png

This is a binary file and will not be displayed.

src/lib/images/projects-new/marblellous-demo.mp4

This is a binary file and will not be displayed.

src/lib/images/projects-new/marblellous-image.png

This is a binary file and will not be displayed.

src/lib/images/projects-new/old-code-demo.mp4

This is a binary file and will not be displayed.

src/lib/images/projects-new/old-code-image.png

This is a binary file and will not be displayed.

src/lib/images/projects-new/svelte-swiper-cards-demo.mp4

This is a binary file and will not be displayed.

src/lib/images/projects-new/svelte-swiper-cards-image.png

This is a binary file and will not be displayed.

src/lib/images/projects-new/text-effect-fluid-demo.mp4

This is a binary file and will not be displayed.

src/lib/images/projects-new/text-effect-fluid-image.png

This is a binary file and will not be displayed.