+
{#if showDebugInfo && lottiePlayer}
{/if}
@@ -521,13 +386,15 @@
bind:this={canvas}
bind:clientWidth={canvasWidth}
bind:clientHeight={canvasHeight}
+ onmouseenter={handleMouseEnter}
+ onmouseleave={handleMouseLeave}
>
{#if children}
- {@render children?.()}
+ {@render children()}
{/if}
-
+
diff --git a/src/components/ScrollerLottie/data/defaultLottie.lottie b/src/components/Lottie/lottie/demo.lottie
similarity index 100%
rename from src/components/ScrollerLottie/data/defaultLottie.lottie
rename to src/components/Lottie/lottie/demo.lottie
diff --git a/src/components/ScrollerLottie/data/dotlottie-player.wasm b/src/components/Lottie/lottie/dotlottie-player.wasm
similarity index 100%
rename from src/components/ScrollerLottie/data/dotlottie-player.wasm
rename to src/components/Lottie/lottie/dotlottie-player.wasm
diff --git a/src/components/ScrollerLottie/data/foregroundSample.lottie b/src/components/Lottie/lottie/foregroundSample.lottie
similarity index 100%
rename from src/components/ScrollerLottie/data/foregroundSample.lottie
rename to src/components/Lottie/lottie/foregroundSample.lottie
diff --git a/src/components/ScrollerLottie/data/markerSample.lottie b/src/components/Lottie/lottie/markerSample.lottie
similarity index 100%
rename from src/components/ScrollerLottie/data/markerSample.lottie
rename to src/components/Lottie/lottie/markerSample.lottie
diff --git a/src/components/ScrollerLottie/data/themesLottie.lottie b/src/components/Lottie/lottie/themesLottie.lottie
similarity index 100%
rename from src/components/ScrollerLottie/data/themesLottie.lottie
rename to src/components/Lottie/lottie/themesLottie.lottie
diff --git a/src/components/ScrollerLottie/ts/lottieState.svelte.ts b/src/components/Lottie/ts/lottieState.svelte.ts
similarity index 100%
rename from src/components/ScrollerLottie/ts/lottieState.svelte.ts
rename to src/components/Lottie/ts/lottieState.svelte.ts
diff --git a/src/components/Lottie/ts/types.ts b/src/components/Lottie/ts/types.ts
new file mode 100644
index 00000000..64f17a8e
--- /dev/null
+++ b/src/components/Lottie/ts/types.ts
@@ -0,0 +1,44 @@
+
+// Types
+import type { Snippet } from 'svelte';
+import {
+ type Config,
+ type DotLottie as DotLottieType,
+} from '@lottiefiles/dotlottie-web';
+import { type LottieState } from './lottieState.svelte';
+
+type DotlottieProps = {
+ autoplay?: Config['autoplay'];
+ backgroundColor?: Config['backgroundColor'];
+ data?: Config['data'];
+ loop?: Config['loop'];
+ mode?: Config['mode'];
+ renderConfig?: Config['renderConfig'];
+ segment?: Config['segment'];
+ speed?: Config['speed'];
+ src: Config['src'];
+ useFrameInterpolation?: Config['useFrameInterpolation'];
+ marker?: Config['marker'] | undefined;
+ layout?: Config['layout'];
+ animationId?: Config['animationId'];
+ themeId?: Config['themeId'];
+ playOnHover?: boolean;
+ themeData?: string;
+ dotLottieRefCallback?: (dotLottie: DotLottieType) => void;
+ onLoad?: () => void;
+ onRender?: () => void;
+ onComplete?: () => void;
+};
+
+export type Props = DotlottieProps & {
+ // Additional properties can be added here if needed
+ lottiePlayer?: DotLottieType | undefined;
+ showDebugInfo?: boolean;
+ height?: string;
+ lottieState?: LottieState;
+ progress?: number;
+ tweenDuration?: number;
+ easing?: (t: number) => number;
+ /** Children render function */
+ children?: Snippet;
+};
diff --git a/src/components/Lottie/ts/utils.ts b/src/components/Lottie/ts/utils.ts
new file mode 100644
index 00000000..e2ebe277
--- /dev/null
+++ b/src/components/Lottie/ts/utils.ts
@@ -0,0 +1,111 @@
+import type { DotLottie } from '@lottiefiles/dotlottie-web';
+import type { LottieState } from './lottieState.svelte';
+
+function constrain(n: number, low: number, high: number) {
+ return Math.max(Math.min(n, high), low);
+}
+
+export function map(
+ n: number,
+ start1: number,
+ stop1: number,
+ start2: number,
+ stop2: number,
+ withinBounds: boolean = true
+) {
+ const newval = ((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
+ if (!withinBounds) {
+ return newval;
+ }
+ if (start2 < stop2) {
+ return constrain(newval, start2, stop2);
+ } else {
+ return constrain(newval, stop2, start2);
+ }
+}
+
+/**
+ * Syncs the lottie player state with the component's lottie state
+ */
+export function syncLottieState(
+ lottiePlayer: DotLottie,
+ lottieState: LottieState
+) {
+ lottieState.currentFrame = lottiePlayer.currentFrame;
+ lottieState.totalFrames = lottiePlayer.totalFrames;
+ lottieState.duration = lottiePlayer.duration;
+ lottieState.loop = lottiePlayer.loop;
+ lottieState.speed = lottiePlayer.speed;
+ lottieState.loopCount = lottiePlayer.loopCount;
+ lottieState.mode = lottiePlayer.mode;
+ lottieState.isPaused = lottiePlayer.isPaused;
+ lottieState.isPlaying = lottiePlayer.isPlaying;
+ lottieState.isStopped = lottiePlayer.isStopped;
+ lottieState.isLoaded = lottiePlayer.isLoaded;
+ lottieState.isFrozen = lottiePlayer.isFrozen;
+ lottieState.segment = lottiePlayer.segment ?? null;
+ lottieState.autoplay = lottiePlayer.autoplay ?? false;
+ lottieState.layout = lottiePlayer.layout ?? null;
+ lottieState.activeThemeId = lottiePlayer.activeThemeId ?? null;
+ lottieState.marker = lottiePlayer.marker ?? undefined;
+}
+
+/**
+ * Gets marker info by name
+ */
+export function getMarkerByName(lottiePlayer: DotLottie, markerName: string) {
+ return lottiePlayer.markers().find((m) => m.name === markerName);
+}
+
+/**
+ * Gets the start and end frames for a marker
+ */
+export function getMarkerRange(
+ lottiePlayer: DotLottie,
+ markerName: string
+): [number, number] {
+ const marker = getMarkerByName(lottiePlayer, markerName);
+ const start = marker?.time ?? 0;
+ const end = start + (marker?.duration ?? 0);
+ return [start, end];
+}
+
+/**
+ * Calculates target frame based on progress and mode
+ */
+export function calculateTargetFrame(
+ progress: number,
+ mode: string,
+ start: number,
+ end: number
+): number {
+ const adjustedProgress =
+ mode === 'reverse' || mode === 'reverse-bounce' ? 1 - progress : progress;
+ return map(adjustedProgress, 0, 1, start, end);
+}
+
+/**
+ * Determines if mode is reverse
+ */
+export function isReverseMode(mode: string): boolean {
+ return mode === 'reverse' || mode === 'reverse-bounce';
+}
+
+/**
+ * Creates render config with optimized defaults
+ */
+export function createRenderConfig() {
+ return {
+ autoResize: true,
+ devicePixelRatio:
+ window.devicePixelRatio > 1 ? window.devicePixelRatio * 0.75 : 1,
+ freezeOnOffscreen: true,
+ };
+}
+
+/**
+ * Checks if a value is null or undefined (empty marker check)
+ */
+export function isNullish(value: any): boolean {
+ return value === null || value === undefined || value === '';
+}
diff --git a/src/components/ScrollerLottie/ScrollerLottie.mdx b/src/components/ScrollerLottie/ScrollerLottie.mdx
deleted file mode 100644
index 79ddb5eb..00000000
--- a/src/components/ScrollerLottie/ScrollerLottie.mdx
+++ /dev/null
@@ -1,363 +0,0 @@
-import { Meta } from '@storybook/blocks';
-
-import * as ScrollerLottieStories from './ScrollerLottie.stories.svelte';
-import CompositionMarkerImage from './assets/marker.png?url';
-
-