Skip to content

Commit f490988

Browse files
authored
Merge pull request #20 from JS-GitRepo/feature/contentDisplay
Feature/content display
2 parents 4b94a7b + 0561bdb commit f490988

38 files changed

+674
-313
lines changed

.firebase/hosting.YnVpbGQ.cache

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ logo192.png,1658782384754,94a05bb86f2fa54e8d3f48900f954b5e79c3ea27468b473afd1510
33
logo512.png,1658782384754,7b92476b36f05aa53bd69500645fb5fe8866d7f0e3ef517c7b6529251418faff
44
manifest.json,1658782384755,00ed38bd68df8fe063a1fda8efbea33c1e6e5118444b200531d8996998372fa5
55
robots.txt,1650942577330,bfe106a3fb878dc83461c86818bf74fc1bdc7f28538ba613cd3e775516ce8b49
6-
asset-manifest.json,1666066965842,b98d7748f2593ca71be3514094e362d67650c2c5bc536a2fee5e223d4a1dea50
7-
index.html,1666066965828,2e2d977f5c005a34dfdc0f06e13752a1470a2ec186b51fcad7538e67d7f192b7
8-
static/css/main.b78c790c.css,1666066965840,4c817b2f6f2cbc4a0a186a4ea01dc6484366d0526b5720911f83f325cf7e1547
9-
static/js/787.cda612ba.chunk.js,1666066965840,bfd132cf30c4fc458aab63f8fb2d23785590a026a1cca2b97e5b7762f6d57df7
10-
static/js/main.598fef70.js.LICENSE.txt,1666066965840,389af84f5364120c1a9af11313b67a410e2e78bc2556eec2c4507b542075a54b
11-
static/js/787.cda612ba.chunk.js.map,1666066965842,db251c987184ae9b3dc222f3dc2c99654213dfb7d350df7db2aa272b583ed9a9
12-
static/css/main.b78c790c.css.map,1666066965839,97879dbd3e1bb07c2c9cdbc0a91bf04e8699b12bdfdb3f06de25f4c229deead0
13-
static/media/munro.f78662ff4aad4d038806.ttf,1666066965839,20391d127ab073c6108d379243b6af3bf56456829f3102be643063141524ea38
14-
static/media/animated-14fps.0a0c585671594fb5b8d7.png,1666066965840,01b9d75a2e4091fe5814de2e31d0e13c3c41c94f3141bc554ce2930b7cffe1f8
15-
static/media/ST4vsArt.64e6ec0dc2fce1023124.jpg,1666066965839,55d40e1482a37fb9b93d70efa539a829d3a48171c481550a096b46c57514f46f
16-
static/media/Headshot-PurpleFlannel.2b06661cd39ac41784bd.png,1666066965839,bf2d5ce61d627da14c23b29a12c90013d1773a8bed9f83e0be9d7a8cefae95b7
17-
static/media/DeerfallBannerPoster.5318e7922524aab5a4b1.jpg,1666066965839,5241662b3103ea00e937b1de64dc74e70267c5ad16d6e87de938f1acaf659f34
18-
static/js/main.598fef70.js,1666066965839,f829529374101438a02efbd5144311f7bd87b60d39c8459929651020d541ed39
19-
static/media/DeerfallBanner_H265.26575320e1418ba9b542.mp4,1666066965841,a0f474b066407039c297e98db245737e4a232ec9996ed7f0de16961b94b84d3a
20-
static/media/DeerfallBanner_AV1.d420aebda0fdbb533e69.mp4,1666066965841,dc1f6c0e3c7adfe3b0b2c184a62775168ba847fa060460aa1a99535186060d3d
21-
static/media/DeerfallBanner_H264.d3d2d7793a0a0e61516b.mp4,1666066965842,5d9c3d555cf4b2d0775c18d015a709e07b1d2c3f8fa42612de1e184584354091
22-
static/js/main.598fef70.js.map,1666066965841,c06963706d277aa92ef2b9c15ff3d33ef90e57839a9e62e0dc9d821c5813f816
6+
asset-manifest.json,1666228677731,8587ff0e282d38665e3d4083dfcbd08e0643cf51909f796c5c9d14c1c64886f1
7+
index.html,1666228677719,cbd50d72dddceff54e2292487378050926f41f29cef41a7f86265c9e3d6a1b67
8+
static/css/main.bf399fb6.css,1666228677731,3021a3f58f6e8bcfb460f5f54ba0397e177a665940b1f4654c9be580d29fe755
9+
static/js/787.cda612ba.chunk.js,1666228677730,bfd132cf30c4fc458aab63f8fb2d23785590a026a1cca2b97e5b7762f6d57df7
10+
static/css/main.bf399fb6.css.map,1666228677730,f5c6f41cc441d782aa66d992a188e7da8164a1e1dfb53f25373217c03620bc1f
11+
static/js/main.21bc060d.js.LICENSE.txt,1666228677730,95cfff0d80fe8c950e4635524b106edf7b8ed9c6a91c0498cb6f2440f661f48c
12+
static/js/787.cda612ba.chunk.js.map,1666228677731,db251c987184ae9b3dc222f3dc2c99654213dfb7d350df7db2aa272b583ed9a9
13+
static/media/munro.f78662ff4aad4d038806.ttf,1666228677729,20391d127ab073c6108d379243b6af3bf56456829f3102be643063141524ea38
14+
static/media/animated-14fps.0a0c585671594fb5b8d7.png,1666228677729,01b9d75a2e4091fe5814de2e31d0e13c3c41c94f3141bc554ce2930b7cffe1f8
15+
static/media/ST4vsArt.64e6ec0dc2fce1023124.jpg,1666228677729,55d40e1482a37fb9b93d70efa539a829d3a48171c481550a096b46c57514f46f
16+
static/media/Headshot-PurpleFlannel.2b06661cd39ac41784bd.png,1666228677728,bf2d5ce61d627da14c23b29a12c90013d1773a8bed9f83e0be9d7a8cefae95b7
17+
static/media/DeerfallBannerPoster.5318e7922524aab5a4b1.jpg,1666228677729,5241662b3103ea00e937b1de64dc74e70267c5ad16d6e87de938f1acaf659f34
18+
static/js/main.21bc060d.js,1666228677729,95c8a21bdc62c35b0422ff8e086363c212e9c45e4145040fae1f1cbfdd17d9d5
19+
static/media/DeerfallBanner_H265.26575320e1418ba9b542.mp4,1666228677730,a0f474b066407039c297e98db245737e4a232ec9996ed7f0de16961b94b84d3a
20+
static/media/DeerfallBanner_AV1.d420aebda0fdbb533e69.mp4,1666228677731,dc1f6c0e3c7adfe3b0b2c184a62775168ba847fa060460aa1a99535186060d3d
21+
static/media/DeerfallBanner_H264.d3d2d7793a0a0e61516b.mp4,1666228677731,5d9c3d555cf4b2d0775c18d015a709e07b1d2c3f8fa42612de1e184584354091
22+
static/js/main.21bc060d.js.map,1666228677731,12edd3d4f07d0f145b52d5c2d6adc0348e0be01f3e544d785a2294872d08ae90

src/components/HVContent.tsx

Lines changed: 104 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import { useEffect, useState } from "react";
1+
import { SetStateAction, useContext, useEffect, useState } from "react";
22
import { animated, useTransition } from "react-spring";
33
import "./styles/HVContent.css";
44
import Deerfall from "./projects/Deerfall";
55
import MediaMatchup from "./projects/MediaMatchup";
66
import 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

812
interface Props {
913
project: string;
@@ -12,9 +16,40 @@ interface Props {
1216
}
1317

1418
const 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

src/components/HVFooter.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ const HVFooter = ({ allParams, isIntro }: Props) => {
1414
const { hueRotation } = useContext(AppContext);
1515

1616
return (
17-
<div className='HVFooter'>
18-
<div className='project-nav-ctr'>
17+
<footer className='HVFooter'>
18+
<nav className='project-nav-ctr'>
1919
<div className={isIntro ? "project-nav hidden" : "project-nav"}>
2020
<span className='material-symbols-outlined'>chevron_left</span>
2121
<h2>{allParams[3]}</h2>
@@ -53,7 +53,7 @@ const HVFooter = ({ allParams, isIntro }: Props) => {
5353
</li>
5454
</ul>
5555
</div>
56-
</div>
56+
</nav>
5757

5858
<div className='rights-ctr'>
5959
<p>
@@ -64,7 +64,7 @@ const HVFooter = ({ allParams, isIntro }: Props) => {
6464
}>{${currentYear.getFullYear()} All Rights Reserved`}</animated.span>{" "}
6565
</p>
6666
</div>
67-
</div>
67+
</footer>
6868
);
6969
};
7070

src/components/HVHeader.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const HVHeader = ({ subtitle, subEmoji, allParams, isIntro }: Props) => {
1717

1818
// Some elements in the return will be hidden by media query CSS, to allow UI elements in the header or footer depending on mobile / Desktop. This is why there are some "redundant" elements
1919
return (
20-
<div className='HVHeader'>
20+
<header className='HVHeader'>
2121
<Link className='title-ctr' to={{ pathname: "/landing" }}>
2222
<h1>
2323
{`${isIntro ? "who is " : ""}`}
@@ -77,7 +77,7 @@ const HVHeader = ({ subtitle, subEmoji, allParams, isIntro }: Props) => {
7777
</ul>
7878
</div>
7979
</div>
80-
<div className={isIntro ? "hidden" : "nav-category-ctr"}>
80+
<nav className={isIntro ? "hidden" : "nav-category-ctr"}>
8181
<ul>
8282
<li>
8383
<NavLink
@@ -98,8 +98,8 @@ const HVHeader = ({ subtitle, subEmoji, allParams, isIntro }: Props) => {
9898
</NavLink>
9999
</li>
100100
</ul>
101-
</div>
102-
</div>
101+
</nav>
102+
</header>
103103
);
104104
};
105105

src/components/HVSideNav.tsx

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import "./styles/HVSideNav.css";
2+
import mediaIcon from "../img/navIcons/media.png";
3+
import techIcon from "../img/navIcons/tech.png";
4+
import aboutIcon from "../img/navIcons/about.png";
5+
import blogIcon from "../img/navIcons/blog.png";
6+
import { animated, useSpring } from "react-spring";
7+
import { useEffect, useState } from "react";
8+
import { HueRotation } from "../models/Models";
9+
import { useLocation, useNavigate } from "react-router-dom";
10+
11+
interface Props {
12+
hueRotation: HueRotation;
13+
isPortfolio: boolean;
14+
allParams: string[];
15+
currentNav: string;
16+
setCurrentNav: React.Dispatch<React.SetStateAction<string>>;
17+
setScrollIsBuffering: React.Dispatch<React.SetStateAction<boolean>>;
18+
}
19+
20+
const HVSideNav = ({
21+
isPortfolio,
22+
allParams,
23+
hueRotation,
24+
currentNav,
25+
setCurrentNav,
26+
setScrollIsBuffering,
27+
}: Props) => {
28+
const navigate = useNavigate();
29+
const location = useLocation();
30+
const navSizeChange = useSpring({
31+
from: { height: "150px" },
32+
to: { height: "110px" },
33+
config: { mass: 1, tension: 200, friction: 15 },
34+
reverse: isPortfolio,
35+
});
36+
37+
const navigateToSection = (navName: string) => {
38+
setScrollIsBuffering(true);
39+
navigate(`${location.pathname}#${navName}`);
40+
setCurrentNav(navName);
41+
};
42+
43+
useEffect(() => {
44+
navigateToSection("media");
45+
}, [allParams[1]]);
46+
47+
return (
48+
<animated.nav className='HVSideNav' style={navSizeChange}>
49+
{isPortfolio ? (
50+
<ul>
51+
<li>
52+
<animated.img
53+
onClick={() => navigateToSection("media")}
54+
className='nav-icon'
55+
style={currentNav === "media" ? hueRotation : {}}
56+
src={mediaIcon}
57+
alt='media navigation icon'
58+
/>
59+
</li>
60+
<li>
61+
<animated.img
62+
onClick={() => navigateToSection("tech")}
63+
className='nav-icon'
64+
style={currentNav === "tech" ? hueRotation : {}}
65+
src={techIcon}
66+
alt='technologies and skills navigation icon'
67+
/>
68+
</li>
69+
<li>
70+
<animated.img
71+
onClick={() => navigateToSection("about")}
72+
className='nav-icon'
73+
style={currentNav === "about" ? hueRotation : {}}
74+
src={aboutIcon}
75+
alt='about project navigation icon'
76+
/>
77+
</li>
78+
</ul>
79+
) : (
80+
<ul>
81+
<li>
82+
<animated.img
83+
onClick={() => navigateToSection("media")}
84+
className='nav-icon'
85+
style={currentNav === "media" ? hueRotation : {}}
86+
src={mediaIcon}
87+
alt='media navigation icon'
88+
/>
89+
</li>
90+
<li>
91+
<animated.img
92+
onClick={() => navigateToSection("blog")}
93+
className='nav-icon'
94+
style={currentNav === "blog" ? hueRotation : {}}
95+
src={blogIcon}
96+
alt='media navigation icon'
97+
/>
98+
</li>
99+
</ul>
100+
)}
101+
</animated.nav>
102+
);
103+
};
104+
105+
export default HVSideNav;

src/components/Introduction.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const Introduction = () => {
1515
const introP5 = AppConfig.built_using_txt;
1616

1717
return (
18-
<div className='Introduction'>
18+
<section className='Introduction'>
1919
<div className='bg-img-ctr'>
2020
<animated.img
2121
className={`bg-img`}
@@ -42,7 +42,7 @@ const Introduction = () => {
4242
</animated.div>
4343
</div>
4444
</div>
45-
</div>
45+
</section>
4646
);
4747
};
4848

0 commit comments

Comments
 (0)