cleanup, refactors
This commit is contained in:
parent
867155c189
commit
916344dcab
2 changed files with 109 additions and 113 deletions
|
|
@ -4,7 +4,14 @@
|
||||||
import { DotLottie } from '@lottiefiles/dotlottie-web';
|
import { DotLottie } from '@lottiefiles/dotlottie-web';
|
||||||
import { createLottieState } from './ts/lottieState.svelte';
|
import { createLottieState } from './ts/lottieState.svelte';
|
||||||
import { isEqual } from 'es-toolkit';
|
import { isEqual } from 'es-toolkit';
|
||||||
import { map } from './ts/utils';
|
import {
|
||||||
|
syncLottieState,
|
||||||
|
getMarkerRange,
|
||||||
|
calculateTargetFrame,
|
||||||
|
isReverseMode,
|
||||||
|
createRenderConfig,
|
||||||
|
isNullish,
|
||||||
|
} from './ts/utils';
|
||||||
import { Tween } from 'svelte/motion';
|
import { Tween } from 'svelte/motion';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
|
|
@ -74,7 +81,7 @@
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (marker == '' || marker == null || marker == undefined) {
|
if (isNullish(marker)) {
|
||||||
start = segment ? segment[0] : 0;
|
start = segment ? segment[0] : 0;
|
||||||
end = segment ? segment[1] : lottiePlayer.totalFrames - 1;
|
end = segment ? segment[1] : lottiePlayer.totalFrames - 1;
|
||||||
}
|
}
|
||||||
|
|
@ -92,86 +99,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRenderEvent() {
|
function onRenderEvent() {
|
||||||
const keys = [
|
|
||||||
'currentFrame',
|
|
||||||
'totalFrames',
|
|
||||||
'duration',
|
|
||||||
'loop',
|
|
||||||
'speed',
|
|
||||||
'loopCount',
|
|
||||||
'mode',
|
|
||||||
'isPaused',
|
|
||||||
'isPlaying',
|
|
||||||
'isStopped',
|
|
||||||
'isLoaded',
|
|
||||||
'isFrozen',
|
|
||||||
'segment',
|
|
||||||
'autoplay',
|
|
||||||
'layout',
|
|
||||||
'activeThemeId',
|
|
||||||
'marker',
|
|
||||||
];
|
|
||||||
|
|
||||||
if (lottiePlayer && lottieState) {
|
if (lottiePlayer && lottieState) {
|
||||||
keys.forEach((key) => {
|
syncLottieState(lottiePlayer, lottieState);
|
||||||
switch (key) {
|
|
||||||
case 'currentFrame':
|
|
||||||
lottieState.currentFrame = lottiePlayer!.currentFrame;
|
|
||||||
break;
|
|
||||||
case 'totalFrames':
|
|
||||||
lottieState.totalFrames = lottiePlayer!.totalFrames;
|
|
||||||
break;
|
|
||||||
case 'duration':
|
|
||||||
lottieState.duration = lottiePlayer!.duration;
|
|
||||||
break;
|
|
||||||
case 'loop':
|
|
||||||
lottieState.loop = lottiePlayer!.loop;
|
|
||||||
break;
|
|
||||||
case 'speed':
|
|
||||||
lottieState.speed = lottiePlayer!.speed;
|
|
||||||
break;
|
|
||||||
case 'loopCount':
|
|
||||||
lottieState.loopCount = lottiePlayer!.loopCount;
|
|
||||||
break;
|
|
||||||
case 'mode':
|
|
||||||
lottieState.mode = lottiePlayer!.mode;
|
|
||||||
break;
|
|
||||||
case 'isPaused':
|
|
||||||
lottieState.isPaused = lottiePlayer!.isPaused;
|
|
||||||
break;
|
|
||||||
case 'isPlaying':
|
|
||||||
lottieState.isPlaying = lottiePlayer!.isPlaying;
|
|
||||||
break;
|
|
||||||
case 'isStopped':
|
|
||||||
lottieState.isStopped = lottiePlayer!.isStopped;
|
|
||||||
break;
|
|
||||||
case 'isLoaded':
|
|
||||||
lottieState.isLoaded = lottiePlayer!.isLoaded;
|
|
||||||
break;
|
|
||||||
case 'isFrozen':
|
|
||||||
lottieState.isFrozen = lottiePlayer!.isFrozen;
|
|
||||||
break;
|
|
||||||
case 'segment':
|
|
||||||
lottieState.segment = lottiePlayer!.segment ?? null;
|
|
||||||
break;
|
|
||||||
case 'autoplay':
|
|
||||||
lottieState.autoplay = lottiePlayer!.autoplay ?? false;
|
|
||||||
break;
|
|
||||||
case 'layout':
|
|
||||||
lottieState.layout = lottiePlayer!.layout ?? null;
|
|
||||||
break;
|
|
||||||
case 'activeThemeId':
|
|
||||||
lottieState.activeThemeId = lottiePlayer!.activeThemeId ?? null;
|
|
||||||
break;
|
|
||||||
case 'marker':
|
|
||||||
lottieState.marker = lottiePlayer!.marker ?? undefined;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
progress = (lottiePlayer.currentFrame + 1) / lottiePlayer.totalFrames;
|
progress = (lottiePlayer.currentFrame + 1) / lottiePlayer.totalFrames;
|
||||||
lottieState.progress = progress;
|
lottieState.progress = progress;
|
||||||
onRender(); // call user-defined onRender function
|
onRender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,12 +121,7 @@
|
||||||
|
|
||||||
progressTween = new Tween(0, { duration: tweenDuration, easing: easing });
|
progressTween = new Tween(0, { duration: tweenDuration, easing: easing });
|
||||||
|
|
||||||
const _renderConfig = {
|
const _renderConfig = createRenderConfig();
|
||||||
autoResize: true,
|
|
||||||
devicePixelRatio:
|
|
||||||
window.devicePixelRatio > 1 ? window.devicePixelRatio * 0.75 : 1,
|
|
||||||
freezeOnOffscreen: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
lottiePlayer = new DotLottie({
|
lottiePlayer = new DotLottie({
|
||||||
canvas,
|
canvas,
|
||||||
|
|
@ -252,20 +179,11 @@
|
||||||
lottiePlayer?.unfreeze();
|
lottiePlayer?.unfreeze();
|
||||||
lottieState.isFrozen = false;
|
lottieState.isFrozen = false;
|
||||||
}
|
}
|
||||||
const targetFrame = map(
|
const targetFrame = calculateTargetFrame(progress, mode, start, end);
|
||||||
mode == 'reverse' || mode == 'reverse-bounce' ?
|
|
||||||
1 - progress
|
|
||||||
: progress,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
start,
|
|
||||||
end
|
|
||||||
);
|
|
||||||
progressTween.target = targetFrame;
|
progressTween.target = targetFrame;
|
||||||
// lottiePlayer.setFrame(targetFrame);
|
// lottiePlayer.setFrame(targetFrame);
|
||||||
} else if ((progress < 0 || progress > 1) && !lottieState.isFrozen) {
|
} else if ((progress < 0 || progress > 1) && !lottieState.isFrozen) {
|
||||||
// lottiePlayer.setFrame(progress < 0 ? start : end);
|
if (isReverseMode(mode)) {
|
||||||
if (mode == 'reverse' || mode == 'reverse-bounce') {
|
|
||||||
progressTween.target = progress < 0 ? end : start;
|
progressTween.target = progress < 0 ? end : start;
|
||||||
} else {
|
} else {
|
||||||
progressTween.target = progress < 0 ? start : end;
|
progressTween.target = progress < 0 ? start : end;
|
||||||
|
|
@ -297,22 +215,11 @@
|
||||||
// Handles marker change
|
// Handles marker change
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (lottieState.isLoaded && lottiePlayer?.marker !== marker) {
|
if (lottieState.isLoaded && lottiePlayer?.marker !== marker) {
|
||||||
if (typeof marker === 'string') {
|
if (typeof marker === 'string' && lottiePlayer) {
|
||||||
lottiePlayer?.setMarker(marker);
|
lottiePlayer.setMarker(marker);
|
||||||
|
[start, end] = getMarkerRange(lottiePlayer, marker);
|
||||||
start =
|
|
||||||
lottiePlayer?.markers().find((m) => m.name === marker)?.time ?? 0;
|
|
||||||
end =
|
|
||||||
start +
|
|
||||||
(lottiePlayer?.markers().find((m) => m.name === marker)?.duration ??
|
|
||||||
0);
|
|
||||||
|
|
||||||
// change lottieState marker because
|
|
||||||
// onRender fires before this
|
|
||||||
if (lottieState) {
|
|
||||||
lottieState.marker = marker;
|
lottieState.marker = marker;
|
||||||
}
|
} else if (isNullish(marker)) {
|
||||||
} else if (marker === null || marker === undefined) {
|
|
||||||
lottiePlayer?.setMarker('');
|
lottiePlayer?.setMarker('');
|
||||||
} else {
|
} else {
|
||||||
console.warn('Invalid marker type:', marker);
|
console.warn('Invalid marker type:', marker);
|
||||||
|
|
@ -488,7 +395,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if children}
|
{#if children}
|
||||||
{@render children?.()}
|
{@render children()}
|
||||||
{/if}
|
{/if}
|
||||||
</Block>
|
</Block>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import type { DotLottie } from '@lottiefiles/dotlottie-web';
|
||||||
|
import type { LottieState } from './lottieState.svelte';
|
||||||
|
|
||||||
function constrain(n: number, low: number, high: number) {
|
function constrain(n: number, low: number, high: number) {
|
||||||
return Math.max(Math.min(n, high), low);
|
return Math.max(Math.min(n, high), low);
|
||||||
}
|
}
|
||||||
|
|
@ -20,3 +23,89 @@ export function map(
|
||||||
return constrain(newval, stop2, start2);
|
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 === '';
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue