mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-05 19:24:39 +00:00
feat: switch store carousel to embla
This commit is contained in:
+2
-1
@@ -71,6 +71,8 @@
|
|||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"color": "^4.2.3",
|
"color": "^4.2.3",
|
||||||
"dompurify": "^3.1.6",
|
"dompurify": "^3.1.6",
|
||||||
|
"embla-carousel-autoplay": "^8.3.1",
|
||||||
|
"embla-carousel-svelte": "^8.3.1",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"idb": "^8.0.0",
|
"idb": "^8.0.0",
|
||||||
"kolorist": "^1.8.0",
|
"kolorist": "^1.8.0",
|
||||||
@@ -85,7 +87,6 @@
|
|||||||
"react-dom": "17",
|
"react-dom": "17",
|
||||||
"sortablejs": "^1.15.3",
|
"sortablejs": "^1.15.3",
|
||||||
"svelte": "5.0.0-next.244",
|
"svelte": "5.0.0-next.244",
|
||||||
"swiper": "latest",
|
|
||||||
"tailwindcss": "^3.4.11",
|
"tailwindcss": "^3.4.11",
|
||||||
"typescript": "^5.6.2",
|
"typescript": "^5.6.2",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
|
|||||||
@@ -1,43 +1,59 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
import type { Theme } from '@/interface/types/Theme';
|
import type { Theme } from '@/interface/types/Theme';
|
||||||
import { register, type SwiperContainer } from 'swiper/element/bundle';
|
import emblaCarouselSvelte from 'embla-carousel-svelte';
|
||||||
|
import Autoplay from 'embla-carousel-autoplay';
|
||||||
|
|
||||||
let { coverThemes, setDisplayTheme } = $props<{ coverThemes: Theme[], setDisplayTheme: (theme: Theme) => void }>();
|
let { coverThemes, setDisplayTheme } = $props<{ coverThemes: Theme[], setDisplayTheme: (theme: Theme) => void }>();
|
||||||
let swiperEl = $state<SwiperContainer | undefined>();
|
let emblaApi = $state();
|
||||||
|
|
||||||
|
|
||||||
const slidePrev = () => swiperEl?.swiper.slidePrev();
|
const options = { loop: true };
|
||||||
const slideNext = () => swiperEl?.swiper.slideNext();
|
const plugins = [
|
||||||
|
Autoplay({
|
||||||
|
delay: 5000,
|
||||||
|
stopOnInteraction: false,
|
||||||
|
stopOnMouseEnter: true
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
onMount(() => {
|
function onInit(event: CustomEvent) {
|
||||||
register();
|
emblaApi = event.detail;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const slidePrev = () => emblaApi?.scrollPrev();
|
||||||
|
// @ts-ignore
|
||||||
|
const slideNext = () => emblaApi?.scrollNext();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if coverThemes.length > 0}
|
{#if coverThemes.length > 0}
|
||||||
<div class="relative w-full transition-opacity rounded-xl overflow-clip" transition:fade>
|
<div class="relative w-full transition-opacity rounded-xl overflow-clip" transition:fade>
|
||||||
<swiper-container bind:this={swiperEl} slides-per-view="1" space-between="20" loop="true" autoplay="true" disable-on-interaction="false" pause-on-mouse-enter="true" class="w-full aspect-[8/3]">
|
<div
|
||||||
{#each coverThemes as theme, index (index)}
|
class="w-full aspect-[8/3]"
|
||||||
<swiper-slide
|
use:emblaCarouselSvelte={{ options, plugins }}
|
||||||
onkeydown={(e: any) => { if (e.key === 'Enter') setDisplayTheme(theme) }}
|
onemblaInit={onInit}
|
||||||
onclick={() => setDisplayTheme(theme)}
|
>
|
||||||
role="button"
|
<div class="flex">
|
||||||
tabindex="0"
|
{#each coverThemes as theme}
|
||||||
class="relative cursor-pointer rounded-xl overflow-clip"
|
<div
|
||||||
>
|
class="relative flex-[0_0_100%] cursor-pointer rounded-xl overflow-clip"
|
||||||
<img src={theme.marqueeImage} alt="Theme Preview" class="object-cover w-full h-full" />
|
role="button"
|
||||||
<div class='absolute bottom-0 left-0 p-8 z-[1]'>
|
tabindex="0"
|
||||||
<h2 class='text-4xl font-bold text-white'>{theme.name}</h2>
|
onkeydown={(e) => { if (e.key === 'Enter') setDisplayTheme(theme) }}
|
||||||
<p class='text-lg text-white'>{theme.description}</p>
|
onclick={() => setDisplayTheme(theme)}
|
||||||
|
>
|
||||||
|
<img src={theme.marqueeImage} alt="Theme Preview" class="object-cover w-full h-full" />
|
||||||
|
<div class='absolute bottom-0 left-0 p-8 z-[1]'>
|
||||||
|
<h2 class='text-4xl font-bold text-white'>{theme.name}</h2>
|
||||||
|
<p class='text-lg text-white'>{theme.description}</p>
|
||||||
|
</div>
|
||||||
|
<div class='absolute bottom-0 left-0 w-full h-1/2 bg-gradient-to-t from-black/80 to-transparent'></div>
|
||||||
</div>
|
</div>
|
||||||
<div class='absolute bottom-0 left-0 w-full h-1/2 bg-gradient-to-t from-black/80 to-transparent'></div>
|
{/each}
|
||||||
</swiper-slide>
|
</div>
|
||||||
{/each}
|
</div>
|
||||||
</swiper-container>
|
|
||||||
|
|
||||||
<!-- Pagination buttons -->
|
<!-- Navigation buttons -->
|
||||||
<div class='absolute z-10 flex gap-2 bottom-2 right-2'>
|
<div class='absolute z-10 flex gap-2 bottom-2 right-2'>
|
||||||
<button onclick={slidePrev} class='flex items-center justify-center w-8 h-8 text-white bg-black bg-opacity-50 rounded-full dark:bg-zinc-800 dark:bg-opacity-50'>
|
<button onclick={slidePrev} class='flex items-center justify-center w-8 h-8 text-white bg-black bg-opacity-50 rounded-full dark:bg-zinc-800 dark:bg-opacity-50'>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width={1.5} stroke="currentColor" class="w-6 h-6">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width={1.5} stroke="currentColor" class="w-6 h-6">
|
||||||
|
|||||||
Reference in New Issue
Block a user