refactor: imagefade component refactored as carousel

This commit is contained in:
Bart van der Braak 2024-01-22 12:26:26 +01:00
parent fe2a5d00f9
commit ae62f93735
4 changed files with 68 additions and 37 deletions

View file

@ -0,0 +1,57 @@
<script lang="ts">
import { onMount } from 'svelte';
export let images: { src: string; alt: string; style?: string }[] = [];
let index = 0;
/* global NodeJS */
let interval: string | number | NodeJS.Timeout | undefined;
const start = () => (interval = setInterval(() => (index = (index + 1) % images.length), 8000));
const stop = () => clearInterval(interval);
onMount(() => {
start();
return () => stop();
});
function handleMarkerClick(i: number) {
stop();
index = i;
}
</script>
<div class="relative h-[500px]">
{#each images as img, i}
<enhanced:img
src={img.src}
alt={img.alt}
class:current-img={index === i}
class="absolute inset-0 h-full w-full rounded-xl object-cover opacity-0 transition-opacity duration-1000 ease-out {img.style}"
/>
{/each}
<div class="absolute bottom-[5%] left-[50%] grid translate-x-[-50%] grid-flow-col gap-2">
{#each images as _, i (_.src)}
<button on:click={() => handleMarkerClick(i)}>
<svg height="20" width="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<circle
cx="8"
cy="8"
r="8"
class:current-marker={index === i}
class="transition-fill fill-gray-500 duration-500 ease-out"
/>
</svg>
</button>
{/each}
</div>
</div>
<style>
.current-img {
opacity: 1;
}
.current-marker {
fill: white;
}
</style>

View file

@ -1,33 +0,0 @@
<script>
import { onMount } from 'svelte';
import catImg from '$lib/assets/root-cat.jpg?enhanced';
import meImg from '$lib/assets/root-me.jpg?enhanced';
const images = [
{ src: meImg, alt: 'Portrait of Bart van der Braak', style: 'object-[50%_10%]' },
{ src: catImg, alt: 'Noire yawning cat and a bottle of whiskey with glass', style: '' }
];
let currentIndex = 0;
let currentImage = images[currentIndex];
onMount(() => {
const interval = setInterval(() => {
currentIndex = (currentIndex + 1) % images.length;
currentImage = images[currentIndex];
}, 15000);
return () => clearInterval(interval);
});
</script>
<div class="relative h-full min-h-96 w-full md:min-h-44">
{#each images as image}
<enhanced:img
src={image.src}
alt={image.alt}
class="absolute left-0 top-0 h-full w-full rounded-xl object-cover transition-opacity duration-1000 {image.style}"
style:opacity={image === currentImage ? 1 : 0}
/>
{/each}
</div>

View file

@ -4,7 +4,7 @@ export { default as SiteNavBar } from './site-navbar.svelte';
export { default as SiteHeader } from './site-header.svelte'; export { default as SiteHeader } from './site-header.svelte';
export { default as TailwindIndicator } from './tailwind-indicator.svelte'; export { default as TailwindIndicator } from './tailwind-indicator.svelte';
export { default as ModeToggle } from './mode-toggle.svelte'; export { default as ModeToggle } from './mode-toggle.svelte';
export { default as ImageFade } from './image-fade.svelte'; export { default as ImageFadeCarousel } from './image-fade-carousel.svelte';
export { default as OgImage } from './opengraph-image.svelte'; export { default as OgImage } from './opengraph-image.svelte';
export * from './icons'; export * from './icons';

View file

@ -1,11 +1,18 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/stores'; import { page } from '$app/stores';
import { Icons, ImageFade } from '$lib/components/site'; import { Icons, ImageFadeCarousel, SiteHeader } from '$lib/components/site';
import { SiteHeader } from '$lib/components/site';
import { buttonVariants } from '$lib/components/ui/button'; import { buttonVariants } from '$lib/components/ui/button';
import { siteConfig } from '$lib/config/site'; import { siteConfig } from '$lib/config/site';
import { cn } from '$lib/utils'; import { cn } from '$lib/utils';
import catImg from '$lib/assets/root-cat.jpg?enhanced';
import meImg from '$lib/assets/root-me.jpg?enhanced';
const images = [
{ src: meImg, alt: 'Portrait of Bart van der Braak', style: 'object-[50%_10%]' },
{ src: catImg, alt: 'Noire yawning cat and a bottle of whiskey with glass', style: '' }
];
$: title = $page.data.title; $: title = $page.data.title;
$: subTitle = $page.data.subTitle; $: subTitle = $page.data.subTitle;
</script> </script>
@ -71,7 +78,7 @@
</div> </div>
<div class="flex-1"> <div class="flex-1">
<ImageFade /> <ImageFadeCarousel {images} />
</div> </div>
</div> </div>
</div> </div>