Skip to content

Commit 63bc902

Browse files
authored
Merge pull request #2612 from input-output-hk/filip/feat/docs-homepage-rewrite-scroll-animations
filip(fix): rewrite scroll-based animation with pure css/js to exclude framer
2 parents b3b0702 + 9f7f660 commit 63bc902

File tree

7 files changed

+148
-169
lines changed

7 files changed

+148
-169
lines changed

docs/website/helpers/media-queries.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ export const forLaptop = "(min-width: 1024px)";
88

99
export const forDesktop = "(min-width: 1280px)";
1010

11+
export const forLargeScreen = "(min-width: 1550px)";
12+
1113
export const forTabletOnly = `${forTablet} and (max-width: 1024px)`;
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import React, { useEffect, useRef } from "react";
2+
import Link from "@docusaurus/Link";
3+
import { WhyMithrilContents } from "../../homepage-content/why-mithril";
4+
import { cx } from "cva";
5+
import useMediaQuery from "../hooks/useMediaQuery";
6+
import { forLargeScreen } from "../../helpers/media-queries";
7+
8+
const WhyMithril = () => {
9+
const containerRef = useRef<HTMLDivElement>(null);
10+
const itemRefs = useRef<(HTMLDivElement | null)[]>([]);
11+
const isLargeScreen = useMediaQuery(forLargeScreen);
12+
13+
useEffect(() => {
14+
let animationFrameId: number;
15+
16+
const animate = () => {
17+
const container = containerRef.current;
18+
if (!container) return;
19+
20+
const scrollY = window.scrollY;
21+
const viewportHeight = window.innerHeight;
22+
23+
const containerTop = container.offsetTop;
24+
const containerHeight = container.offsetHeight;
25+
const scrollProgress =
26+
(scrollY + viewportHeight - containerTop) /
27+
(containerHeight + viewportHeight);
28+
29+
itemRefs.current.forEach((el, index) => {
30+
if (!el) return;
31+
32+
const start = 0.07 + index * 0.08;
33+
const end = start + 0.75;
34+
35+
let localProgress = (scrollProgress - start) / (end - start);
36+
localProgress = Math.min(Math.max(localProgress, 0), 1);
37+
38+
const translateZ = -200 + localProgress * 400;
39+
const opacity =
40+
localProgress < 0.5 ? localProgress * 2 : (1 - localProgress) * 2;
41+
const blur =
42+
localProgress < 0.5
43+
? 5 - localProgress * 10
44+
: (1 - localProgress) * 100;
45+
46+
el.style.opacity = `${opacity}`;
47+
el.style.transform = `translateZ(${translateZ}px)`;
48+
el.style.filter = `blur(${blur}px)`;
49+
});
50+
51+
animationFrameId = requestAnimationFrame(animate);
52+
};
53+
54+
animationFrameId = requestAnimationFrame(animate);
55+
56+
return () => cancelAnimationFrame(animationFrameId);
57+
}, []);
58+
59+
return (
60+
<section className="component bg-blue-light">
61+
<div className="pageContainer">
62+
<h5 className="text-base text-black pb-12">
63+
{WhyMithrilContents.title}
64+
</h5>
65+
66+
<div className="flex tablet:flex-row flex-col justify-between gap-[1.625rem] text-primary">
67+
<div
68+
className="text-3xl text-center flex justify-center text-blue items-center basis-1/2 stuck-grid flex-col gap-4"
69+
ref={containerRef}
70+
>
71+
{WhyMithrilContents.timeline.map((item, index) => (
72+
<div
73+
key={index}
74+
ref={(el) => (itemRefs.current[index] = el)}
75+
className={cx(
76+
"timeline-grid-item",
77+
item === "Basho" && "text-blue-highlight",
78+
)}
79+
style={{
80+
transformStyle: "preserve-3d",
81+
opacity: 0,
82+
filter: "blur(5px)",
83+
transform: "translateZ(-200px)",
84+
alignSelf: [
85+
"flex-start",
86+
"flex-end",
87+
"flex-start",
88+
"center",
89+
"flex-end",
90+
][index % 5],
91+
}}
92+
>
93+
{item}
94+
</div>
95+
))}
96+
</div>
97+
98+
<div className="flex flex-col basis-1/2 gap-10 fade-in delay">
99+
{WhyMithrilContents.descriptionParagraph.message}
100+
<Link
101+
className="inline-block px-4 py-3 font-bold text-sm text-white rounded-lg border-[0.5px] border-gray-border no-underline bg-secondary hover:bg-blue-extralight hover:no-underline hover:text-primary hover:scale-105 transition-all w-fit hover:text-white"
102+
to="/mithril/beginner/why-use-mithril"
103+
>
104+
Learn more
105+
</Link>
106+
</div>
107+
</div>
108+
</div>
109+
</section>
110+
);
111+
};
112+
113+
export default WhyMithril;

docs/website/src/components/why-mithril/AnimatedTimelineItem.tsx

Lines changed: 0 additions & 76 deletions
This file was deleted.

docs/website/src/components/why-mithril/WhyMithril.tsx

Lines changed: 0 additions & 68 deletions
This file was deleted.

docs/website/src/css/custom.css

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,21 @@ a.menu__link {
302302
perspective: 500px;
303303
transform-style: preserve-3d;
304304
}
305+
306+
.timeline-grid-item {
307+
will-change: transform, opacity, filter;
308+
transition:
309+
opacity 0.1s ease,
310+
transform 0.1s ease,
311+
filter 0.1s ease;
312+
}
313+
314+
.landing-navbar--top {
315+
background-color: rgba(255, 255, 255, 0);
316+
transition: background-color 0.3s ease;
317+
}
318+
319+
.landing-navbar--scrolled {
320+
background-color: rgba(255, 255, 255, 0.96);
321+
transition: background-color 0.3s ease;
322+
}

docs/website/src/pages/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import React from "react";
22
import Layout from "@theme/Layout";
3-
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
43
import { PageContext, PageType } from "../context/PageContext";
54
import HomepageHero from "../components/HomepageHero";
65
import Features from "../components/Features";
7-
import WhyMithril from "../components/why-mithril/WhyMithril";
86
import AnimatedText from "../components/AnimatedText";
97
import UseCases from "../components/UseCases";
8+
import WhyMithril from "../components/WhyMithril";
109

1110
export default function HomePage() {
1211
return (

docs/website/src/theme/Navbar/Layout/index.tsx

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import {
88
import { translate } from "@docusaurus/Translate";
99
import NavbarMobileSidebar from "@theme/Navbar/MobileSidebar";
1010
import styles from "./styles.module.css";
11-
12-
import { useScroll, motion, useTransform, MotionValue } from "framer-motion";
1311
import { useIsLandingPage } from "../../../hooks/useIsLandingPage";
1412

1513
function NavbarBackdrop(props) {
@@ -21,6 +19,7 @@ function NavbarBackdrop(props) {
2119
/>
2220
);
2321
}
22+
2423
export default function NavbarLayout({ children }) {
2524
const isLandingPage = useIsLandingPage();
2625
const {
@@ -29,26 +28,19 @@ export default function NavbarLayout({ children }) {
2928
const mobileSidebar = useNavbarMobileSidebar();
3029
const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll);
3130

32-
const { scrollY } = useScroll();
33-
const y = useTransform(
34-
scrollY,
35-
[0, 70],
36-
["rgba(255, 255, 255, 0)", "rgba(255, 255, 255, 0.96)"],
37-
);
31+
const [scrolled, setScrolled] = useState(false);
3832

39-
const [isMounted, setIsMounted] = useState(false);
4033
useEffect(() => {
41-
setIsMounted(true);
34+
const onScroll = () => {
35+
setScrolled(window.scrollY > 70);
36+
};
37+
38+
window.addEventListener("scroll", onScroll);
39+
return () => window.removeEventListener("scroll", onScroll);
4240
}, []);
41+
4342
return (
44-
<motion.header
45-
//@ts-ignore
46-
style={
47-
isLandingPage &&
48-
isMounted && {
49-
backgroundColor: y,
50-
}
51-
}
43+
<header
5244
ref={navbarRef}
5345
aria-label={translate({
5446
id: "theme.NavBar.navAriaLabel",
@@ -61,12 +53,11 @@ export default function NavbarLayout({ children }) {
6153
? "border-none pt-3"
6254
: "border-b border-[#EAEAEB] pt-3 pb-4 tablet:px-2",
6355
"navbar--fixed-top",
64-
hideOnScroll && [
65-
// styles.navbarHideable,
66-
!isNavbarVisible && styles.navbarHidden,
67-
],
56+
hideOnScroll && !isNavbarVisible && styles.navbarHidden,
6857
{
6958
"navbar-sidebar--show": mobileSidebar.shown,
59+
"landing-navbar--scrolled": isLandingPage && scrolled,
60+
"landing-navbar--top": isLandingPage && !scrolled,
7061
},
7162
)}
7263
>
@@ -79,6 +70,6 @@ export default function NavbarLayout({ children }) {
7970
</div>
8071
<NavbarBackdrop onClick={mobileSidebar.toggle} />
8172
<NavbarMobileSidebar />
82-
</motion.header>
73+
</header>
8374
);
8475
}

0 commit comments

Comments
 (0)