1- import { useEffect , useState } from "react" ;
1+ import { SetStateAction , useContext , useEffect , useState } from "react" ;
22import { animated , useTransition } from "react-spring" ;
33import "./styles/HVContent.css" ;
44import Deerfall from "./projects/Deerfall" ;
55import MediaMatchup from "./projects/MediaMatchup" ;
66import Introduction from "./Introduction" ;
7+ import HVSideNav from "./HVSideNav" ;
8+ import AppContext from "../contexts/AppContext" ;
9+ import { useIntersectionObserver } from "../hooks/useIntersectionObserver" ;
10+ import { useLocation , useNavigate } from "react-router-dom" ;
711
812interface Props {
913 project : string ;
@@ -12,9 +16,40 @@ interface Props {
1216}
1317
1418const HVContent = ( { project, isIntro, allParams } : Props ) => {
15- // - - - - STATES - - - -
19+ // = = = = = NAVIGATION = = = = =
1620 const [ isPortfolio , setIsPortfolio ] = useState < boolean > ( true ) ;
17- // - - - - PROJECTS - - - -
21+ const [ currentNav , setCurrentNav ] = useState < string > ( "media" ) ;
22+ const [ scrollIsBuffering , setScrollIsBuffering ] = useState ( false ) ;
23+ const { scrollRefs, hueRotation } = useContext ( AppContext ) ;
24+ const location = useLocation ( ) ;
25+ const navigate = useNavigate ( ) ;
26+ const observerOptions : IntersectionObserverInit = {
27+ threshold : 0.5 ,
28+ root : null ,
29+ rootMargin : "0px" ,
30+ } ;
31+ const mediaScrollObserver = useIntersectionObserver (
32+ scrollRefs . media ,
33+ observerOptions ,
34+ false
35+ ) ;
36+ const techScrollObserver = useIntersectionObserver (
37+ scrollRefs . tech ,
38+ observerOptions ,
39+ false
40+ ) ;
41+ const blogScrollObserver = useIntersectionObserver (
42+ scrollRefs . blog ,
43+ observerOptions ,
44+ false
45+ ) ;
46+ const aboutScrollObserver = useIntersectionObserver (
47+ scrollRefs . about ,
48+ observerOptions ,
49+ false
50+ ) ;
51+
52+ // = = = = = PROJECTS = = = = =
1853 const allProjList = {
1954 intro : < Introduction /> ,
2055 deerfall : < Deerfall isPortfolio = { isPortfolio } /> ,
@@ -28,7 +63,7 @@ const HVContent = ({ project, isIntro, allParams }: Props) => {
2863 } ;
2964 const [ localProject , setLocalProject ] = useState < string > ( "" ) ;
3065 const [ show , setShow ] = useState < boolean > ( true ) ;
31- // - - - - TRANSITIONS - - - -
66+ // = = = = = TRANSITIONS = = = = =
3267 const transitionFade = useTransition ( show , {
3368 from : { opacity : 0 } ,
3469 enter : { opacity : 1 } ,
@@ -37,6 +72,8 @@ const HVContent = ({ project, isIntro, allParams }: Props) => {
3772 // exitBeforeEnter: true,
3873 } ) ;
3974
75+ // = = = = = FUNCTIONS = = = = =
76+
4077 const checkAndSetProjComp = ( ) => {
4178 if ( isIntro ) {
4279 setLocalProject ( "intro" ) ;
@@ -45,7 +82,14 @@ const HVContent = ({ project, isIntro, allParams }: Props) => {
4582 }
4683 } ;
4784
48- // - - - - - USE EFFECTS - - - - -
85+ const scrollToElement = ( ref : React . MutableRefObject < any > ) => {
86+ ref . current ?. scrollIntoView ( {
87+ behavior : "smooth" ,
88+ } ) ;
89+ console . log ( "scrollToElement Triggered" ) ;
90+ } ;
91+
92+ // = = = = = USE EFFECTS = = = = =
4993 // Hide Project when it is Changed, then set the new project once hidden
5094 useEffect ( ( ) => {
5195 setShow ( false ) ;
@@ -66,8 +110,61 @@ const HVContent = ({ project, isIntro, allParams }: Props) => {
66110 }
67111 } , [ allParams ] ) ;
68112
113+ useEffect ( ( ) => {
114+ if ( mediaScrollObserver ?. isIntersecting && ! scrollIsBuffering ) {
115+ navigate ( `${ location . pathname } #media` ) ;
116+ } else if ( techScrollObserver ?. isIntersecting && ! scrollIsBuffering ) {
117+ navigate ( `${ location . pathname } #tech` ) ;
118+ } else if ( blogScrollObserver ?. isIntersecting && ! scrollIsBuffering ) {
119+ navigate ( `${ location . pathname } #blog` ) ;
120+ } else if ( aboutScrollObserver ?. isIntersecting && ! scrollIsBuffering ) {
121+ navigate ( `${ location . pathname } #about` ) ;
122+ }
123+ } , [
124+ mediaScrollObserver ?. isIntersecting ,
125+ techScrollObserver ?. isIntersecting ,
126+ blogScrollObserver ?. isIntersecting ,
127+ aboutScrollObserver ?. isIntersecting ,
128+ ] ) ;
129+
130+ useEffect ( ( ) => {
131+ setScrollIsBuffering ( true ) ;
132+ if ( location . hash === "#media" ) {
133+ scrollToElement ( scrollRefs . media ) ;
134+ setCurrentNav ( "media" ) ;
135+ } else if ( location . hash === "#tech" ) {
136+ scrollToElement ( scrollRefs . tech ) ;
137+ setCurrentNav ( "tech" ) ;
138+ } else if ( location . hash === "#about" ) {
139+ scrollToElement ( scrollRefs . about ) ;
140+ setCurrentNav ( "about" ) ;
141+ } else if ( location . hash === "#blog" ) {
142+ scrollToElement ( scrollRefs . blog ) ;
143+ setCurrentNav ( "blog" ) ;
144+ }
145+ } , [ location . hash ] ) ;
146+
147+ useEffect ( ( ) => {
148+ if ( scrollIsBuffering ) {
149+ setTimeout ( ( ) => setScrollIsBuffering ( false ) , 500 ) ;
150+ }
151+ } , [ scrollIsBuffering ] ) ;
152+
69153 return (
70- < div className = 'HVContent' >
154+ < main className = 'HVContent' >
155+ { isIntro ? (
156+ ""
157+ ) : (
158+ < HVSideNav
159+ isPortfolio = { isPortfolio }
160+ allParams = { allParams }
161+ hueRotation = { hueRotation }
162+ currentNav = { currentNav }
163+ setCurrentNav = { setCurrentNav }
164+ setScrollIsBuffering = { setScrollIsBuffering }
165+ />
166+ ) }
167+
71168 { transitionFade (
72169 ( styles , item ) =>
73170 item && (
@@ -76,7 +173,7 @@ const HVContent = ({ project, isIntro, allParams }: Props) => {
76173 </ animated . div >
77174 )
78175 ) }
79- </ div >
176+ </ main >
80177 ) ;
81178} ;
82179
0 commit comments