diff --git a/src/content/TextAnimations/TextPressure/TextPressure.jsx b/src/content/TextAnimations/TextPressure/TextPressure.jsx
index e0858130..e337eb8c 100644
--- a/src/content/TextAnimations/TextPressure/TextPressure.jsx
+++ b/src/content/TextAnimations/TextPressure/TextPressure.jsx
@@ -1,11 +1,31 @@
// Component ported from https://codepen.io/JuanFuentes/full/rgXKGQ
-import { useEffect, useRef, useState } from 'react';
+import { useEffect, useRef, useState, useMemo, useCallback } from 'react';
+
+const dist = (a, b) => {
+ const dx = b.x - a.x;
+ const dy = b.y - a.y;
+ return Math.sqrt(dx * dx + dy * dy);
+};
+
+const getAttr = (distance, maxDist, minVal, maxVal) => {
+ const val = maxVal - Math.abs((maxVal * distance) / maxDist);
+ return Math.max(minVal, val + minVal);
+};
+
+const debounce = (func, delay) => {
+ let timeoutId;
+ return (...args) => {
+ clearTimeout(timeoutId);
+ timeoutId = setTimeout(() => {
+ func.apply(this, args);
+ }, delay);
+ };
+};
const TextPressure = ({
text = 'Compressa',
fontFamily = 'Compressa VF',
- // This font is just an example, you should not use it in commercial projects.
fontUrl = 'https://res.cloudinary.com/dr6lvwubh/raw/upload/v1529908256/CompressaPRO-GX.woff2',
width = true,
@@ -36,12 +56,6 @@ const TextPressure = ({
const chars = text.split('');
- const dist = (a, b) => {
- const dx = b.x - a.x;
- const dy = b.y - a.y;
- return Math.sqrt(dx * dx + dy * dy);
- };
-
useEffect(() => {
const handleMouseMove = e => {
cursorRef.current.x = e.clientX;
@@ -54,7 +68,7 @@ const TextPressure = ({
};
window.addEventListener('mousemove', handleMouseMove);
- window.addEventListener('touchmove', handleTouchMove, { passive: false });
+ window.addEventListener('touchmove', handleTouchMove, { passive: true });
if (containerRef.current) {
const { left, top, width, height } = containerRef.current.getBoundingClientRect();
@@ -70,7 +84,7 @@ const TextPressure = ({
};
}, []);
- const setSize = () => {
+ const setSize = useCallback(() => {
if (!containerRef.current || !titleRef.current) return;
const { width: containerW, height: containerH } = containerRef.current.getBoundingClientRect();
@@ -92,14 +106,14 @@ const TextPressure = ({
setLineHeight(yRatio);
}
});
- };
+ }, [chars.length, minFontSize, scale]);
useEffect(() => {
- setSize();
- window.addEventListener('resize', setSize);
- return () => window.removeEventListener('resize', setSize);
- // eslint-disable-next-line
- }, [scale, text]);
+ const debouncedSetSize = debounce(setSize, 100);
+ debouncedSetSize();
+ window.addEventListener('resize', debouncedSetSize);
+ return () => window.removeEventListener('resize', debouncedSetSize);
+ }, [setSize]);
useEffect(() => {
let rafId;
@@ -122,18 +136,19 @@ const TextPressure = ({
const d = dist(mouseRef.current, charCenter);
- const getAttr = (distance, minVal, maxVal) => {
- const val = maxVal - Math.abs((maxVal * distance) / maxDist);
- return Math.max(minVal, val + minVal);
- };
+ const wdth = width ? Math.floor(getAttr(d, maxDist, 5, 200)) : 100;
+ const wght = weight ? Math.floor(getAttr(d, maxDist, 100, 900)) : 400;
+ const italVal = italic ? getAttr(d, maxDist, 0, 1).toFixed(2) : 0;
+ const alphaVal = alpha ? getAttr(d, maxDist, 0, 1).toFixed(2) : 1;
- const wdth = width ? Math.floor(getAttr(d, 5, 200)) : 100;
- const wght = weight ? Math.floor(getAttr(d, 100, 900)) : 400;
- const italVal = italic ? getAttr(d, 0, 1).toFixed(2) : 0;
- const alphaVal = alpha ? getAttr(d, 0, 1).toFixed(2) : 1;
+ const newFontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`;
- span.style.opacity = alphaVal;
- span.style.fontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`;
+ if (span.style.fontVariationSettings !== newFontVariationSettings) {
+ span.style.fontVariationSettings = newFontVariationSettings;
+ }
+ if (alpha && span.style.opacity !== alphaVal) {
+ span.style.opacity = alphaVal;
+ }
});
}
@@ -142,20 +157,10 @@ const TextPressure = ({
animate();
return () => cancelAnimationFrame(rafId);
- }, [width, weight, italic, alpha, chars.length]);
+ }, [width, weight, italic, alpha]);
- const dynamicClassName = [className, flex ? 'flex' : '', stroke ? 'stroke' : ''].filter(Boolean).join(' ');
-
- return (
-
+ const styleElement = useMemo(() => {
+ return (
+ );
+ }, [fontFamily, fontUrl, flex, stroke, textColor, strokeColor]);
+ const dynamicClassName = [className, flex ? 'flex' : '', stroke ? 'stroke' : ''].filter(Boolean).join(' ');
+
+ return (
+
+ {styleElement}
{
+ const dx = b.x - a.x;
+ const dy = b.y - a.y;
+ return Math.sqrt(dx * dx + dy * dy);
+};
+
+const getAttr = (distance, maxDist, minVal, maxVal) => {
+ const val = maxVal - Math.abs((maxVal * distance) / maxDist);
+ return Math.max(minVal, val + minVal);
+};
+
+const debounce = (func, delay) => {
+ let timeoutId;
+ return (...args) => {
+ clearTimeout(timeoutId);
+ timeoutId = setTimeout(() => {
+ func.apply(this, args);
+ }, delay);
+ };
+};
const TextPressure = ({
text = 'Compressa',
@@ -37,12 +58,6 @@ const TextPressure = ({
const chars = text.split('');
- const dist = (a, b) => {
- const dx = b.x - a.x;
- const dy = b.y - a.y;
- return Math.sqrt(dx * dx + dy * dy);
- };
-
useEffect(() => {
const handleMouseMove = e => {
cursorRef.current.x = e.clientX;
@@ -55,7 +70,7 @@ const TextPressure = ({
};
window.addEventListener('mousemove', handleMouseMove);
- window.addEventListener('touchmove', handleTouchMove, { passive: false });
+ window.addEventListener('touchmove', handleTouchMove, { passive: true });
if (containerRef.current) {
const { left, top, width, height } = containerRef.current.getBoundingClientRect();
@@ -71,7 +86,7 @@ const TextPressure = ({
};
}, []);
- const setSize = () => {
+ const setSize = useCallback(() => {
if (!containerRef.current || !titleRef.current) return;
const { width: containerW, height: containerH } = containerRef.current.getBoundingClientRect();
@@ -93,14 +108,14 @@ const TextPressure = ({
setLineHeight(yRatio);
}
});
- };
+ }, [chars.length, minFontSize, scale]);
useEffect(() => {
- setSize();
- window.addEventListener('resize', setSize);
- return () => window.removeEventListener('resize', setSize);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [scale, text]);
+ const debouncedSetSize = debounce(setSize, 100);
+ debouncedSetSize();
+ window.addEventListener('resize', debouncedSetSize);
+ return () => window.removeEventListener('resize', debouncedSetSize);
+ }, [setSize]);
useEffect(() => {
let rafId;
@@ -123,18 +138,19 @@ const TextPressure = ({
const d = dist(mouseRef.current, charCenter);
- const getAttr = (distance, minVal, maxVal) => {
- const val = maxVal - Math.abs((maxVal * distance) / maxDist);
- return Math.max(minVal, val + minVal);
- };
+ const wdth = width ? Math.floor(getAttr(d, maxDist, 5, 200)) : 100;
+ const wght = weight ? Math.floor(getAttr(d, maxDist, 100, 900)) : 400;
+ const italVal = italic ? getAttr(d, maxDist, 0, 1).toFixed(2) : 0;
+ const alphaVal = alpha ? getAttr(d, maxDist, 0, 1).toFixed(2) : 1;
- const wdth = width ? Math.floor(getAttr(d, 5, 200)) : 100;
- const wght = weight ? Math.floor(getAttr(d, 100, 900)) : 400;
- const italVal = italic ? getAttr(d, 0, 1).toFixed(2) : 0;
- const alphaVal = alpha ? getAttr(d, 0, 1).toFixed(2) : 1;
+ const newFontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`;
- span.style.opacity = alphaVal;
- span.style.fontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`;
+ if (span.style.fontVariationSettings !== newFontVariationSettings) {
+ span.style.fontVariationSettings = newFontVariationSettings;
+ }
+ if (alpha && span.style.opacity !== alphaVal) {
+ span.style.opacity = alphaVal;
+ }
});
}
@@ -143,10 +159,10 @@ const TextPressure = ({
animate();
return () => cancelAnimationFrame(rafId);
- }, [width, weight, italic, alpha, chars.length]);
+ }, [width, weight, italic, alpha]);
- return (
-
+ const styleElement = useMemo(() => {
+ return (
+ );
+ }, [fontFamily, fontUrl, stroke, textColor, strokeColor, strokeWidth]);
+ return (
+
+ {styleElement}
{
+ const dx = b.x - a.x;
+ const dy = b.y - a.y;
+ return Math.sqrt(dx * dx + dy * dy);
+};
+
+const getAttr = (distance: number, maxDist: number, minVal: number, maxVal: number) => {
+ const val = maxVal - Math.abs((maxVal * distance) / maxDist);
+ return Math.max(minVal, val + minVal);
+};
+
+const debounce = (func: (...args: any[]) => void, delay: number) => {
+ let timeoutId: NodeJS.Timeout;
+ return (...args: any[]) => {
+ clearTimeout(timeoutId);
+ timeoutId = setTimeout(() => {
+ func.apply(this, args);
+ }, delay);
+ };
+};
+
const TextPressure: React.FC = ({
text = 'Compressa',
fontFamily = 'Compressa VF',
@@ -48,12 +69,6 @@ const TextPressure: React.FC = ({
const chars = text.split('');
- const dist = (a: { x: number; y: number }, b: { x: number; y: number }) => {
- const dx = b.x - a.x;
- const dy = b.y - a.y;
- return Math.sqrt(dx * dx + dy * dy);
- };
-
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
cursorRef.current.x = e.clientX;
@@ -66,7 +81,7 @@ const TextPressure: React.FC = ({
};
window.addEventListener('mousemove', handleMouseMove);
- window.addEventListener('touchmove', handleTouchMove, { passive: false });
+ window.addEventListener('touchmove', handleTouchMove, { passive: true });
if (containerRef.current) {
const { left, top, width, height } = containerRef.current.getBoundingClientRect();
@@ -82,7 +97,7 @@ const TextPressure: React.FC = ({
};
}, []);
- const setSize = () => {
+ const setSize = useCallback(() => {
if (!containerRef.current || !titleRef.current) return;
const { width: containerW, height: containerH } = containerRef.current.getBoundingClientRect();
@@ -104,13 +119,14 @@ const TextPressure: React.FC = ({
setLineHeight(yRatio);
}
});
- };
+ }, [chars.length, minFontSize, scale]);
useEffect(() => {
- setSize();
- window.addEventListener('resize', setSize);
- return () => window.removeEventListener('resize', setSize);
- }, [scale, text]);
+ const debouncedSetSize = debounce(setSize, 100);
+ debouncedSetSize();
+ window.addEventListener('resize', debouncedSetSize);
+ return () => window.removeEventListener('resize', debouncedSetSize);
+ }, [setSize]);
useEffect(() => {
let rafId: number;
@@ -133,18 +149,19 @@ const TextPressure: React.FC = ({
const d = dist(mouseRef.current, charCenter);
- const getAttr = (distance: number, minVal: number, maxVal: number) => {
- const val = maxVal - Math.abs((maxVal * distance) / maxDist);
- return Math.max(minVal, val + minVal);
- };
+ const wdth = width ? Math.floor(getAttr(d, maxDist, 5, 200)) : 100;
+ const wght = weight ? Math.floor(getAttr(d, maxDist, 100, 900)) : 400;
+ const italVal = italic ? getAttr(d, maxDist, 0, 1).toFixed(2) : '0';
+ const alphaVal = alpha ? getAttr(d, maxDist, 0, 1).toFixed(2) : '1';
- const wdth = width ? Math.floor(getAttr(d, 5, 200)) : 100;
- const wght = weight ? Math.floor(getAttr(d, 100, 900)) : 400;
- const italVal = italic ? getAttr(d, 0, 1).toFixed(2) : 0;
- const alphaVal = alpha ? getAttr(d, 0, 1).toFixed(2) : 1;
+ const newFontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`;
- span.style.opacity = alphaVal.toString();
- span.style.fontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`;
+ if (span.style.fontVariationSettings !== newFontVariationSettings) {
+ span.style.fontVariationSettings = newFontVariationSettings;
+ }
+ if (alpha && span.style.opacity !== alphaVal) {
+ span.style.opacity = alphaVal;
+ }
});
}
@@ -153,20 +170,10 @@ const TextPressure: React.FC = ({
animate();
return () => cancelAnimationFrame(rafId);
- }, [width, weight, italic, alpha, chars.length]);
+ }, [width, weight, italic, alpha]);
- const dynamicClassName = [className, flex ? 'flex' : '', stroke ? 'stroke' : ''].filter(Boolean).join(' ');
-
- return (
-
+ const styleElement = useMemo(() => {
+ return (
+ );
+ }, [fontFamily, fontUrl, flex, stroke, textColor, strokeColor]);
+ const dynamicClassName = [className, flex ? 'flex' : '', stroke ? 'stroke' : ''].filter(Boolean).join(' ');
+
+ return (
+
+ {styleElement}
{
+ const dx = b.x - a.x;
+ const dy = b.y - a.y;
+ return Math.sqrt(dx * dx + dy * dy);
+};
+
+const getAttr = (distance: number, maxDist: number, minVal: number, maxVal: number) => {
+ const val = maxVal - Math.abs((maxVal * distance) / maxDist);
+ return Math.max(minVal, val + minVal);
+};
+
+const debounce = (func: (...args: any[]) => void, delay: number) => {
+ let timeoutId: NodeJS.Timeout;
+ return (...args: any[]) => {
+ clearTimeout(timeoutId);
+ timeoutId = setTimeout(() => {
+ func.apply(this, args);
+ }, delay);
+ };
+};
+
const TextPressure: React.FC = ({
text = 'Compressa',
fontFamily = 'Compressa VF',
@@ -50,12 +71,6 @@ const TextPressure: React.FC = ({
const chars = text.split('');
- const dist = (a: { x: number; y: number }, b: { x: number; y: number }) => {
- const dx = b.x - a.x;
- const dy = b.y - a.y;
- return Math.sqrt(dx * dx + dy * dy);
- };
-
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
cursorRef.current.x = e.clientX;
@@ -68,7 +83,7 @@ const TextPressure: React.FC = ({
};
window.addEventListener('mousemove', handleMouseMove);
- window.addEventListener('touchmove', handleTouchMove, { passive: false });
+ window.addEventListener('touchmove', handleTouchMove, { passive: true });
if (containerRef.current) {
const { left, top, width, height } = containerRef.current.getBoundingClientRect();
@@ -84,7 +99,7 @@ const TextPressure: React.FC = ({
};
}, []);
- const setSize = () => {
+ const setSize = useCallback(() => {
if (!containerRef.current || !titleRef.current) return;
const { width: containerW, height: containerH } = containerRef.current.getBoundingClientRect();
@@ -106,13 +121,14 @@ const TextPressure: React.FC = ({
setLineHeight(yRatio);
}
});
- };
+ }, [chars.length, minFontSize, scale]);
useEffect(() => {
- setSize();
- window.addEventListener('resize', setSize);
- return () => window.removeEventListener('resize', setSize);
- }, [scale, text]);
+ const debouncedSetSize = debounce(setSize, 100);
+ debouncedSetSize();
+ window.addEventListener('resize', debouncedSetSize);
+ return () => window.removeEventListener('resize', debouncedSetSize);
+ }, [setSize]);
useEffect(() => {
let rafId: number;
@@ -135,18 +151,19 @@ const TextPressure: React.FC = ({
const d = dist(mouseRef.current, charCenter);
- const getAttr = (distance: number, minVal: number, maxVal: number) => {
- const val = maxVal - Math.abs((maxVal * distance) / maxDist);
- return Math.max(minVal, val + minVal);
- };
+ const wdth = width ? Math.floor(getAttr(d, maxDist, 5, 200)) : 100;
+ const wght = weight ? Math.floor(getAttr(d, maxDist, 100, 900)) : 400;
+ const italVal = italic ? getAttr(d, maxDist, 0, 1).toFixed(2) : '0';
+ const alphaVal = alpha ? getAttr(d, maxDist, 0, 1).toFixed(2) : '1';
- const wdth = width ? Math.floor(getAttr(d, 5, 200)) : 100;
- const wght = weight ? Math.floor(getAttr(d, 100, 900)) : 400;
- const italVal = italic ? getAttr(d, 0, 1).toFixed(2) : '0';
- const alphaVal = alpha ? getAttr(d, 0, 1).toFixed(2) : '1';
+ const newFontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`;
- span.style.opacity = alphaVal;
- span.style.fontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${italVal}`;
+ if (span.style.fontVariationSettings !== newFontVariationSettings) {
+ span.style.fontVariationSettings = newFontVariationSettings;
+ }
+ if (alpha && span.style.opacity !== alphaVal) {
+ span.style.opacity = alphaVal;
+ }
});
}
@@ -155,10 +172,10 @@ const TextPressure: React.FC = ({
animate();
return () => cancelAnimationFrame(rafId);
- }, [width, weight, italic, alpha, chars.length]);
+ }, [width, weight, italic, alpha]);
- return (
-
+ const styleElement = useMemo(() => {
+ return (
+ );
+ }, [fontFamily, fontUrl, stroke, textColor, strokeColor, strokeWidth]);
+ return (
+
+ {styleElement}