Spaces:
Configuration error
Configuration error
File size: 6,142 Bytes
30eeea4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
'use client'
import { useRef, useEffect } from 'react';
import { gsap } from 'gsap';
export function Footer() {
const listItemsRef = useRef<(HTMLLIElement | null)[]>([]);
const spanItemsRef = useRef<(HTMLSpanElement | null)[]>([]);
useEffect(() => {
const handleMouseEnter = (item: HTMLElement) => {
const textInitial = item.querySelector('.initial');
const textHover = item.querySelector('.hover');
gsap.to(textInitial, {
yPercent: -100,
perspective: 1000,
rotationX: 90,
duration: 1,
ease: 'power4.out',
});
gsap.to(textHover, {
yPercent: 0,
perspective: 1000,
rotationX: 0,
duration: 1,
ease: 'power4.out',
});
};
const handleMouseLeave = (item: HTMLElement) => {
const textInitial = item.querySelector('.initial');
const textHover = item.querySelector('.hover');
gsap.to(textInitial, {
yPercent: 0,
perspective: 1000,
rotationX: 0,
duration: 1,
ease: 'power4.out',
});
gsap.to(textHover, {
yPercent: 100,
perspective: 1000,
rotationX: -90,
duration: 1,
ease: 'power4.out',
});
};
const addEventListeners = (item: HTMLElement | null) => {
if (!item) return;
const textHover = item.querySelector('.hover');
gsap.set(textHover, { yPercent: 100, perspective: 1000, rotationX: -90 });
const enterHandler = () => handleMouseEnter(item);
const leaveHandler = () => handleMouseLeave(item);
item.addEventListener('mouseenter', enterHandler);
item.addEventListener('mouseleave', leaveHandler);
// Store handlers to remove them later
(item as any).__enterHandler = enterHandler;
(item as any).__leaveHandler = leaveHandler;
};
const removeEventListeners = (item: HTMLElement | null) => {
if (!item) return;
item.removeEventListener('mouseenter', (item as any).__enterHandler);
item.removeEventListener('mouseleave', (item as any).__leaveHandler);
};
listItemsRef.current.forEach(addEventListeners);
spanItemsRef.current.forEach(addEventListeners);
return () => {
listItemsRef.current.forEach(removeEventListeners);
spanItemsRef.current.forEach(removeEventListeners);
};
}, []);
return (
<footer className="flex relative flex-col container py-12 h-screen justify-evenly">
<div className='flex flex-col'>
<ul className="flex flex-col gap-5 uppercase w-24">
{['About', 'Services', 'Works', 'Contact'].map((text, index) => (
<li
key={index}
ref={(el) => { listItemsRef.current[index] = el; }}
className="relative overflow-hidden h-5 cursor-pointer"
>
<span className="block initial absolute top-0 left-0 w-full h-full">{text}</span>
<span className="block hover absolute top-0 left-0 w-full h-full">{text}</span>
</li>
))}
</ul>
</div>
<div className='relative overflow-hidden group/line py-12 mx-auto w-fit cursor-pointer'>
<h1 className='w-full text-[12vw] uppercase leading-none'>Let's Talk</h1>
<span className='block w-full bg-white h-3 -translate-x-full group-hover/line:translate-x-0 duration-500 opacity-0 group-hover/line:opacity-100' />
</div>
<div className='w-full flex flex-col md:flex-row gap-10 justify-between'>
<div className='flex gap-10 uppercase'>
<div className=' relative overflow-hidden group/line cursor-pointer'>
<h1 className='leading-none pb-2'>mail</h1>
<span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
</div>
<div className=' relative overflow-hidden group/line cursor-pointer'>
<h1 className='leading-none pb-2'>github</h1>
<span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
</div>
<div className=' relative overflow-hidden group/line cursor-pointer'>
<h1 className='leading-none pb-2'>behance</h1>
<span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
</div>
<div className=' relative overflow-hidden group/line cursor-pointer'>
<h1 className='leading-none pb-2'>dribble</h1>
<span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
</div>
<div className=' relative overflow-hidden group/line cursor-pointer'>
<h1 className='leading-none pb-2'>linkedin</h1>
<span className='block bg-white h-[2px] -translate-x-full group-hover/line:translate-x-0 group-hover/line:opacity-100 opacity-0 duration-500' />
</div>
</div>
<div className='flex gap-10 uppercase'>
<span>2024 © CharltonK.dev</span>
</div>
</div>
</footer>
);
}
export default Footer;
|