Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 🎸 freezeOnOffscreen render config #297

Merged
merged 11 commits into from
Aug 28, 2024
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 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 @@ -164,7 +165,9 @@
// useFrameInterpolation: false,
});

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 All @@ -181,7 +184,7 @@
)
.then(async (res) => res.arrayBuffer())
.then((data): void => {
console.log(data);

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

View workflow job for this annotation

GitHub Actions / validate

Unexpected console statement
const canvas = document.getElementById('canvas') as HTMLCanvasElement;

const dotLottie = new DotLottie({
Expand All @@ -202,7 +205,7 @@
dotLottie.postStateMachineEvent('OnPointerDown: 0.0 0.0');
});

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

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

View workflow job for this annotation

GitHub Actions / validate

Unexpected console statement

const playPauseButton = document.getElementById('playPause') as HTMLButtonElement;
const stopButton = document.getElementById('stop') as HTMLButtonElement;
Expand Down Expand Up @@ -394,7 +397,7 @@
});

dotLottie.addEventListener('ready', (event) => {
console.log(event, dotLottie.isReady);

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

View workflow job for this annotation

GitHub Actions / validate

Unexpected console statement
});

dotLottie.addEventListener('load', (event) => {
Expand Down Expand Up @@ -439,7 +442,7 @@

activeAnimationSpan.textContent = dotLottie.activeAnimationId ?? 'None';

console.log(event);

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

View workflow job for this annotation

GitHub Actions / validate

Unexpected console statement
});

dotLottie.addEventListener('loadError', (event) => {
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
34 changes: 4 additions & 30 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 @@ -151,8 +133,6 @@ export const useDotLottie = (config?: DotLottieConfig): UseDotLottieResult => {
dotLottieInstance.freeze();
}

intersectionObserver?.observe(canvas);

if (config?.autoResizeCanvas) {
resizeObserver?.observe(canvas);
}
Expand All @@ -166,11 +146,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 +194,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
18 changes: 0 additions & 18 deletions packages/wc/src/dotlottie-wc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ export class DotLottieWC extends LitElement {

@state() public dotLottie: DotLottie | null = null;

private readonly _intersectionObserver: IntersectionObserver;

private readonly _resizeObserver: ResizeObserver;

public static override styles = css`
Expand All @@ -46,20 +44,6 @@ export class DotLottieWC extends LitElement {

public constructor() {
super();
this._intersectionObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (this.dotLottie) {
if (entry.isIntersecting) {
this.dotLottie.unfreeze();
} else {
this.dotLottie.freeze();
}
}
});
},
{ threshold: 0.1 },
);

this._resizeObserver = new ResizeObserver((entries) => {
if (this.dotLottie && entries[0]) {
Expand Down Expand Up @@ -92,7 +76,6 @@ export class DotLottieWC extends LitElement {
this.dotLottie = null;
}

this._intersectionObserver.disconnect();
this._resizeObserver.disconnect();
}

Expand Down Expand Up @@ -124,7 +107,6 @@ export class DotLottieWC extends LitElement {
renderConfig: this.renderConfig,
useFrameInterpolation: this.useFrameInterpolation,
});
this._intersectionObserver.observe(canvas);
this._resizeObserver.observe(canvas);
}
}
Expand Down
Loading
Loading