1- import React , { useEffect } from 'react' ;
1+ import React , { useState , useEffect , useCallback , useRef } from 'react' ;
22import './footer.css' ;
33
4+ const ScrambleText = ( { text } ) => {
5+ const [ scrambledText , setScrambledText ] = useState ( text ) ;
6+ const ref = useRef ( null ) ;
7+ const [ isVisible , setIsVisible ] = useState ( false ) ;
8+ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
9+
10+ const scramble = useCallback ( ( ) => {
11+ let iterations = 0 ;
12+ const maxIterations = 10 ;
13+ const interval = setInterval ( ( ) => {
14+ setScrambledText ( prev =>
15+ text . split ( '' ) . map ( ( char , index ) => {
16+ if ( char === " " ) return " " ;
17+ if ( iterations > index ) return char ;
18+ return characters [ Math . floor ( Math . random ( ) * characters . length ) ] ;
19+ } ) . join ( "" )
20+ ) ;
21+
22+ iterations += 1 / 3 ;
23+ if ( iterations >= maxIterations ) {
24+ clearInterval ( interval ) ;
25+ setScrambledText ( text ) ;
26+ }
27+ } , 30 ) ;
28+
29+ return ( ) => clearInterval ( interval ) ;
30+ } , [ text , characters ] ) ;
31+
32+ useEffect ( ( ) => {
33+ const observer = new IntersectionObserver (
34+ ( [ entry ] ) => {
35+ setIsVisible ( entry . isIntersecting ) ;
36+ } ,
37+ { threshold : 0.1 }
38+ ) ;
39+
40+ if ( ref . current ) observer . observe ( ref . current ) ;
41+
42+ return ( ) => {
43+ if ( ref . current ) observer . unobserve ( ref . current ) ;
44+ } ;
45+ } , [ ] ) ;
46+
47+ useEffect ( ( ) => {
48+ if ( isVisible ) {
49+ scramble ( ) ;
50+ }
51+ } , [ isVisible , scramble ] ) ;
52+
53+ return (
54+ < span ref = { ref } className = "scramble-text" >
55+ { scrambledText }
56+ </ span >
57+ ) ;
58+ } ;
59+
460const Footer = ( ) => {
561 useEffect ( ( ) => {
662 const script = document . createElement ( 'script' )
@@ -17,23 +73,23 @@ const Footer = () => {
1773 < div className = "outlaws" >
1874 < div className = "outlaws-image" >
1975 < img src = "./footer-images/no_outlaw-cropped.svg" alt = "text" />
20- < h1 > Code The Journey</ h1 >
76+ < h1 > < ScrambleText text = " Code The Journey" /> </ h1 >
2177 </ div >
2278 </ div >
23- < div className = "everything" >
79+ < div className = "everything" data-aos = "fade-up" data-aos-once = "true" data-aos-duration = "300" >
2480 < div className = "M" >
2581 < img src = "./footer-images/MATURE_17.svg" alt = "MATURE" />
2682 </ div >
27- < div className = "logo" >
28- < div className = "save-the-date" > SAVE THE DATE</ div >
29- < div className = "april-dates" > APRIL 12 | 13</ div >
83+ < div className = "logo" >
84+ < div className = "save-the-date" data-aos = "fade-down" data-aos-duration = "500" data-aos-delay = "300" > SAVE THE DATE</ div >
85+ < div className = "april-dates" data-aos = "fade-up" data-aos-duration = "500" data-aos-delay = "450" > APRIL 12 | 13</ div >
3086
3187 < div
3288 className = "apply-button"
3389 data-hackathon-slug = "gajshield-kjsse-hack8"
3490 data-button-theme = "dark-inverted"
3591 > </ div >
36- < div className = "social-icons" >
92+ < div className = "social-icons" data-aos = "zoom-up" data-aos-duration = "500" data-aos-delay = "300" >
3793 < a href = "https://www.facebook.com/kjscecodecell/" target = "_blank" rel = "noopener noreferrer" >
3894 < img src = "./footer-images/facebook.svg" alt = "Facebook" style = { { width : '30px' , height : '30px' } } />
3995 </ a >
@@ -50,7 +106,10 @@ const Footer = () => {
50106 < img src = "./footer-images/linkedin.svg" alt = "LinkedIn" style = { { width : '30px' , height : '30px' } } />
51107 </ a >
52108 </ div >
53- < p > Made with < span > 🤍</ span > by < a href = "https://www.kjssecodecell.com/" target = "_blank" rel = "noopener noreferrer" > KJSSE CodeCell</ a > </ p >
109+ < div >
110+ < p > Made with < span > 🤍</ span > by < a href = "https://www.kjssecodecell.com/" target = "_blank" rel = "noopener noreferrer" > KJSSE CodeCell</ a > </ p >
111+ </ div >
112+
54113 </ div >
55114 < div className = "G" >
56115 < img src = "./footer-images/MATURE_17.svg" alt = "MATURE" />
0 commit comments