Skip to content

Commit

Permalink
feat: 🎸 freezeOnOffscreen render config (#297)
Browse files Browse the repository at this point in the history
* feat: 🎸 freezeOnOffscreen render config
  • Loading branch information
theashraf authored Aug 28, 2024
1 parent ad73820 commit b7148b9
Show file tree
Hide file tree
Showing 17 changed files with 698 additions and 331 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-snakes-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lottiefiles/dotlottie-web': minor
---

feat: 🎸 added freezeOnOffscreen option to renderConfig
5 changes: 4 additions & 1 deletion apps/dotlottie-web-example/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import './styles.css';
import type { Fit, Mode } from '@lottiefiles/dotlottie-web';
import { DotLottieWorker as DotLottie } from '@lottiefiles/dotlottie-web';
// import { DotLottie } from '@lottiefiles/dotlottie-web';

import wasmUrl from '../../../packages/web/dist/dotlottie-player.wasm?url';

Expand All @@ -11,7 +12,7 @@ const app = document.getElementById('app') as HTMLDivElement;
const baseUrl = window.location.origin + import.meta.env.BASE_URL;

app.innerHTML = `
<div class="grid">
<div class="grid" style="margin-top: 1000px">
<canvas data-src="https://lottie.host/b2d44b82-fd7e-401f-a4fa-77999147c0be/vqNwJryGBp.lottie"></canvas>
<canvas data-bg-color="green" data-src="https://lottie.host/1cf72a35-6d88-4d9a-9961-f1bb88087f2c/miJIHiyH4Q.lottie"></canvas>
<canvas data-src="https://lottie.host/647eb023-6040-4b60-a275-e2546994dd7f/zDCfp5lhLe.json"></canvas>
Expand Down Expand Up @@ -165,6 +166,8 @@ allCanvas.forEach((canvas) => {
});

dotLottie.addEventListener('loadError', console.error);

Check warning on line 168 in apps/dotlottie-web-example/src/main.ts

View workflow job for this annotation

GitHub Actions / validate

Unexpected console statement
dotLottie.addEventListener('freeze', console.log);

Check warning on line 169 in apps/dotlottie-web-example/src/main.ts

View workflow job for this annotation

GitHub Actions / validate

Unexpected console statement
dotLottie.addEventListener('unfreeze', console.log);

Check warning on line 170 in apps/dotlottie-web-example/src/main.ts

View workflow job for this annotation

GitHub Actions / validate

Unexpected console statement

window.addEventListener('resize', () => {
dotLottie.resize();
Expand Down
9 changes: 9 additions & 0 deletions apps/with-parcel-example/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
// Extend from the build config
"extends": "../../tsconfig.dev.json",

// Compiler options
"compilerOptions": {},

"include": ["src"]
}
48 changes: 4 additions & 44 deletions packages/react/src/use-dotlottie-worker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,6 @@ export const useDotLottieWorker = (config?: DotLottieWorkerConfig): UseDotLottie
}
}, []);

const intersectionObserver = useMemo(() => {
if (isServerSide()) return null;

const observerCallback = (entries: IntersectionObserverEntry[]): void => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
dotLottieRef.current?.unfreeze();
} else {
dotLottieRef.current?.freeze();
}
});
};

return new IntersectionObserver(observerCallback, {
threshold: 0,
});
}, []);

const resizeObserver = useMemo(() => {
if (isServerSide()) return null;

Expand Down Expand Up @@ -138,22 +120,6 @@ export const useDotLottieWorker = (config?: DotLottieWorkerConfig): UseDotLottie
canvas,
});

// Check if the canvas is initially in view
const initialEntry = canvas.getBoundingClientRect();

if (
initialEntry.top >= 0 &&
initialEntry.left >= 0 &&
initialEntry.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
initialEntry.right <= (window.innerWidth || document.documentElement.clientWidth)
) {
dotLottieInstance.unfreeze();
} else {
dotLottieInstance.freeze();
}

intersectionObserver?.observe(canvas);

if (config?.autoResizeCanvas) {
resizeObserver?.observe(canvas);
}
Expand All @@ -167,11 +133,10 @@ export const useDotLottieWorker = (config?: DotLottieWorkerConfig): UseDotLottie
dotLottieInstance?.destroy();
setDotLottie(null);
resizeObserver?.disconnect();
intersectionObserver?.disconnect();
canvas?.removeEventListener('mouseenter', hoverHandler);
canvas?.removeEventListener('mouseleave', hoverHandler);
};
}, [intersectionObserver, resizeObserver, hoverHandler]);
}, [resizeObserver, hoverHandler]);

// speed reactivity
useEffect(() => {
Expand Down Expand Up @@ -216,15 +181,10 @@ export const useDotLottieWorker = (config?: DotLottieWorkerConfig): UseDotLottie
useEffect(() => {
if (!dotLottieRef.current) return;

if (
typeof config?.segment === 'object' &&
Array.isArray(config.segment) &&
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
config.segment.length === 2
) {
const startFrame = config.segment[0];
const endFrame = config.segment[1];
const startFrame = config?.segment?.[0];
const endFrame = config?.segment?.[1];

if (typeof startFrame === 'number' && typeof endFrame === 'number') {
dotLottieRef.current.setSegment(startFrame, endFrame);
}
}, [config?.segment]);
Expand Down
48 changes: 4 additions & 44 deletions packages/react/src/use-dotlottie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,6 @@ export const useDotLottie = (config?: DotLottieConfig): UseDotLottieResult => {
}
}, []);

const intersectionObserver = useMemo(() => {
if (isServerSide()) return null;

const observerCallback = (entries: IntersectionObserverEntry[]): void => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
dotLottieRef.current?.unfreeze();
} else {
dotLottieRef.current?.freeze();
}
});
};

return new IntersectionObserver(observerCallback, {
threshold: 0,
});
}, []);

const resizeObserver = useMemo(() => {
if (isServerSide()) return null;

Expand Down Expand Up @@ -137,22 +119,6 @@ export const useDotLottie = (config?: DotLottieConfig): UseDotLottieResult => {
canvas,
});

// Check if the canvas is initially in view
const initialEntry = canvas.getBoundingClientRect();

if (
initialEntry.top >= 0 &&
initialEntry.left >= 0 &&
initialEntry.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
initialEntry.right <= (window.innerWidth || document.documentElement.clientWidth)
) {
dotLottieInstance.unfreeze();
} else {
dotLottieInstance.freeze();
}

intersectionObserver?.observe(canvas);

if (config?.autoResizeCanvas) {
resizeObserver?.observe(canvas);
}
Expand All @@ -166,11 +132,10 @@ export const useDotLottie = (config?: DotLottieConfig): UseDotLottieResult => {
dotLottieInstance?.destroy();
setDotLottie(null);
resizeObserver?.disconnect();
intersectionObserver?.disconnect();
canvas?.removeEventListener('mouseenter', hoverHandler);
canvas?.removeEventListener('mouseleave', hoverHandler);
};
}, [intersectionObserver, resizeObserver, hoverHandler]);
}, [resizeObserver, hoverHandler]);

// speed reactivity
useEffect(() => {
Expand Down Expand Up @@ -215,15 +180,10 @@ export const useDotLottie = (config?: DotLottieConfig): UseDotLottieResult => {
useEffect(() => {
if (!dotLottieRef.current) return;

if (
typeof config?.segment === 'object' &&
Array.isArray(config.segment) &&
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
config.segment.length === 2
) {
const startFrame = config.segment[0];
const endFrame = config.segment[1];
const startFrame = config?.segment?.[0];
const endFrame = config?.segment?.[1];

if (typeof startFrame === 'number' && typeof endFrame === 'number') {
dotLottieRef.current.setSegment(startFrame, endFrame);
}
}, [config?.segment]);
Expand Down
35 changes: 0 additions & 35 deletions packages/solid/src/use-dotlottie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,6 @@ export const useDotLottie = (config: DotLottieConfig): UseDotLottieReturn => {
}
};

const intersectionObserver = createMemo(() => {
if (isServer) return null;

const observerCallback = debounce((entries: IntersectionObserverEntry[]) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
dotLottie()?.unfreeze();
} else {
dotLottie()?.freeze();
}
});
}, 150);

return new IntersectionObserver(observerCallback, {
threshold: 0,
});
});

const resizeObserver = createMemo(() => {
if (isServer) return null;

Expand All @@ -114,21 +96,6 @@ export const useDotLottie = (config: DotLottieConfig): UseDotLottieReturn => {

setDotLottie(dotLottieInstance);

// check if canvas is initially in view
const initialEntry = canvas.getBoundingClientRect();

if (
initialEntry.top >= 0 &&
initialEntry.left >= 0 &&
initialEntry.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
initialEntry.right <= (window.innerWidth || document.documentElement.clientWidth)
) {
dotLottie()?.unfreeze();
} else {
dotLottie()?.freeze();
}

intersectionObserver()?.observe(canvas);
if (config.autoResizeCanvas) {
resizeObserver()?.observe(canvas);
}
Expand All @@ -137,7 +104,6 @@ export const useDotLottie = (config: DotLottieConfig): UseDotLottieReturn => {
canvas.addEventListener('mouseleave', hoverHandler);
} else {
dotLottie()?.destroy();
intersectionObserver()?.disconnect();
resizeObserver()?.disconnect();
}

Expand All @@ -156,7 +122,6 @@ export const useDotLottie = (config: DotLottieConfig): UseDotLottieReturn => {
dotLottie()?.destroy();
setDotLottie(null);
resizeObserver()?.disconnect();
intersectionObserver()?.disconnect();
if (canvasRef) {
canvasRef.removeEventListener('mouseenter', hoverHandler);
canvasRef.removeEventListener('mouseleave', hoverHandler);
Expand Down
12 changes: 0 additions & 12 deletions packages/svelte/src/lib/Dotlottie.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,15 @@
}
}, 150));
const intersectionObserver = new IntersectionObserver(debounce((entries: IntersectionObserverEntry[]) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
dotLottie.unfreeze();
} else {
dotLottie.freeze();
}
});
}, 150), { threshold: 0 });
if (autoResizeCanvas) {
resizeObserver.observe(canvas);
}
intersectionObserver.observe(canvas);
canvas.addEventListener('mouseenter', hoverHandler);
canvas.addEventListener('mouseleave', hoverHandler);
return () => {
resizeObserver.disconnect();
intersectionObserver.disconnect();
canvas.removeEventListener('mouseenter', hoverHandler);
canvas.removeEventListener('mouseleave', hoverHandler);
dotLottie.destroy();
Expand Down
31 changes: 7 additions & 24 deletions packages/vue/src/dotlottie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export const DotLottieVue = defineComponent({
useFrameInterpolation,
} = toRefs(props);
let dotLottie: DotLottie | null = null;
let intersectionObserver: IntersectionObserver | null = null;
let resizeObserver: ResizeObserver | null = null;

// Prop change
Expand Down Expand Up @@ -99,9 +98,13 @@ export const DotLottieVue = defineComponent({
watch(
() => segment?.value,
(newVal) => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (dotLottie && Array.isArray(newVal) && newVal.length === 2) {
dotLottie.setSegment(newVal[0], newVal[1]);
if (!dotLottie) return;

const startFrame = newVal?.[0];
const endFrame = newVal?.[1];

if (typeof startFrame === 'number' && typeof endFrame === 'number') {
dotLottie.setSegment(startFrame, endFrame);
}
},
);
Expand Down Expand Up @@ -172,23 +175,6 @@ export const DotLottieVue = defineComponent({
},
);

function getIntersectionObserver(): IntersectionObserver {
return new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
dotLottie?.unfreeze();
} else {
dotLottie?.freeze();
}
});
},
{
threshold: 0,
},
);
}

function getResizeObserver(): ResizeObserver {
return new ResizeObserver((entries) => {
entries.forEach(() => {
Expand All @@ -212,8 +198,6 @@ export const DotLottieVue = defineComponent({
autoplay: shouldAutoplay,
});

intersectionObserver = getIntersectionObserver();
intersectionObserver.observe(canvas.value);
if (typeof autoResizeCanvas?.value === 'boolean' && autoResizeCanvas.value) {
resizeObserver = getResizeObserver();
resizeObserver.observe(canvas.value);
Expand All @@ -226,7 +210,6 @@ export const DotLottieVue = defineComponent({

onBeforeUnmount(() => {
resizeObserver?.disconnect();
intersectionObserver?.disconnect();
canvas.value?.addEventListener('mouseenter', hoverHandler);
canvas.value?.addEventListener('mouseleave', hoverHandler);
dotLottie?.destroy();
Expand Down
Loading

0 comments on commit b7148b9

Please sign in to comment.