Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 🎸 Add Industry Comparison Section #427

Merged
merged 16 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/components/DataRoom/CryptoPunks/Content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Typography } from '@mui/material'
import type { BaseBlock } from '@/components/Home/types'
import type { MotionValue } from 'framer-motion'
import { motion, useTransform } from 'framer-motion'
import dynamic from 'next/dynamic'
import LinksWrapper from '../LinksWrapper'
import css from './styles.module.css'
import { useSafeDataRoomStats } from '@/hooks/useSafeDataRoomStats'
import { useIsMediumScreen } from '@/hooks/useMaxWidth'

const PunksGrid = dynamic(() => import('./PunksGrid'))
const SlidingPanel = dynamic(() => import('@/components/common/SlidingPanel'))

const CRYPTOPUNKS_TOTAL = 10000
const CRYPTOPUNKS_PERCENTAGE_STORED_FALLBACK = 0.092

const Content = ({ scrollYProgress, title, text, link }: BaseBlock & { scrollYProgress: MotionValue<number> }) => {
const { cryptoPunksStoredPercentage } = useSafeDataRoomStats()
const isMobile = useIsMediumScreen()

const opacityParams = isMobile ? [0.4, 0.45, 0.65, 0.66] : [0.25, 0.35, 0.65, 0.7]
const opacity = useTransform(scrollYProgress, opacityParams, [0, 1, 1, 0])

const percentageValue = cryptoPunksStoredPercentage || CRYPTOPUNKS_PERCENTAGE_STORED_FALLBACK
// Converts to percentage with 1 decimal place
const percentageToDisplay = (percentageValue * 100).toFixed(1) + '%'

const cryptoPunksStored = (percentageValue * CRYPTOPUNKS_TOTAL).toFixed(0)
const fractionToDisplay = `${cryptoPunksStored}/${CRYPTOPUNKS_TOTAL}`

return (
<motion.div
className={css.slidingPanelContent}
style={{
opacity,
}}
>
<Typography variant="h2" className={css.text}>
{text}
</Typography>

<Typography variant="h2">{title}</Typography>

<div className={css.statsContainer}>
<Typography variant="h1" className={css.percentage}>
{percentageToDisplay}
</Typography>
<Typography variant="h2" className={css.fraction}>
{fractionToDisplay}
</Typography>
</div>

{link && <LinksWrapper link={link} variant="dark" />}
</motion.div>
)
}

export default Content
53 changes: 53 additions & 0 deletions src/components/DataRoom/CryptoPunks/PunksGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { getRandomColor } from '@/components/DataRoom/CryptoPunks/utils/getRandomColor'
import CryptoPunk from '@/public/images/DataRoom/cryptopunk-silhouette.svg'
import type { MotionValue } from 'framer-motion'
import { motion, useTransform } from 'framer-motion'
import css from './styles.module.css'

const CRYPTOPUNK_ROWS_NR = 8
const CRYPTOPUNK_COLUMNS_NR = 24

const PunksGrid = ({ scrollYProgress, isMobile }: { scrollYProgress: MotionValue<number>; isMobile: boolean }) => {
const translateParams = isMobile ? [0, 1] : [0.25, 0.75]
const opacity = useTransform(scrollYProgress, [0, 0.25, 0.7, 0.75], [0, 1, 1, 0])
const translateLTR = useTransform(scrollYProgress, translateParams, ['-50%', '0%'])
const translateRTL = useTransform(scrollYProgress, translateParams, ['0%', '-50%'])

const translateDirection = (index: number) => (index % 2 === 1 ? translateLTR : translateRTL)

return (
<motion.div
style={{
opacity,
}}
className={css.punksGrid}
>
{Array.from({ length: CRYPTOPUNK_ROWS_NR }).map((_, outerIndex) => (
<motion.div
style={{ translateX: translateDirection(outerIndex) }}
className={css.cryptoPunkColumns}
key={outerIndex}
>
{Array.from({ length: CRYPTOPUNK_COLUMNS_NR }).map((_, innerIndex) => (
<motion.div
key={innerIndex}
initial={{ opacity: 0, scale: 0.5 }}
whileInView={{ opacity: 1, scale: 1 }}
transition={{
duration: 0.3,
}}
style={{
transformOrigin: 'center',
color: getRandomColor(),
}}
>
<CryptoPunk className={css.cryptopunk} />
</motion.div>
))}
</motion.div>
))}
</motion.div>
)
}

export default PunksGrid
134 changes: 15 additions & 119 deletions src/components/DataRoom/CryptoPunks/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
import { Typography } from '@mui/material'
import type { BaseBlock } from '@/components/Home/types'
import { useIsMediumScreen } from '@/hooks/useMaxWidth'
import { useScroll } from 'framer-motion'
import dynamic from 'next/dynamic'
import { useRef } from 'react'
import { useScroll, motion, useTransform } from 'framer-motion'
import type { ReactNode } from 'react'
import type { MotionValue } from 'framer-motion'
import css from './styles.module.css'
import LinksWrapper from '../LinksWrapper'
import { getRandomColor } from '@/components/DataRoom/CryptoPunks/utils/getRandomColor'
import CryptoPunk from '@/public/images/DataRoom/cryptopunk-silhouette.svg'
import { useIsMediumScreen } from '@/hooks/useMaxWidth'
import { useSafeDataRoomStats } from '@/hooks/useSafeDataRoomStats'

const CRYPTOPUNKS_TOTAL = 10000
const CRYPTOPUNKS_PERCENTAGE_STORED_FALLBACK = 0.092

const CRYPTOPUNK_ROWS_NR = 8
const CRYPTOPUNK_COLUMNS_NR = 24
const PunksGrid = dynamic(() => import('./PunksGrid'))
const Content = dynamic(() => import('./Content'))
const SlidingPanel = dynamic(() => import('@/components/common/SlidingPanel'))

const CryptoPunks = ({ title, text, link }: BaseBlock) => {
const { cryptoPunksStoredPercentage } = useSafeDataRoomStats()

const backgroundRef = useRef<HTMLDivElement>(null)
const isMobile = useIsMediumScreen()

Expand All @@ -28,113 +18,19 @@ const CryptoPunks = ({ title, text, link }: BaseBlock) => {
offset: ['start end', 'end start'],
})

const percentageValue = cryptoPunksStoredPercentage || CRYPTOPUNKS_PERCENTAGE_STORED_FALLBACK
// Converts to percentage with 1 decimal place
const percentageToDisplay = (percentageValue * 100).toFixed(1) + '%'

const cryptoPunksStored = (percentageValue * CRYPTOPUNKS_TOTAL).toFixed(0)
const fractionToDisplay = `${cryptoPunksStored}/${CRYPTOPUNKS_TOTAL}`

return (
<div ref={backgroundRef} className={css.sectionContainer}>
<div className={css.stickyContainer}>
<LeftPanel scrollYProgress={scrollYProgress} isMobile={isMobile} />
<RightPanel scrollYProgress={scrollYProgress} isMobile={isMobile}>
<Typography variant="h2" className={css.text}>
{text}
</Typography>

<Typography variant="h2">{title}</Typography>

<div className={css.statsContainer}>
<Typography variant="h1" className={css.percentage}>
{percentageToDisplay}
</Typography>
<Typography variant="h2" className={css.fraction}>
{fractionToDisplay}
</Typography>
</div>

{link && <LinksWrapper link={link} variant="dark" />}
</RightPanel>
</div>
</div>
)
}

const LeftPanel = ({ scrollYProgress, isMobile }: { scrollYProgress: MotionValue<number>; isMobile: boolean }) => {
const translateParams = isMobile ? [0, 1] : [0.25, 0.75]
const opacity = useTransform(scrollYProgress, [0, 0.25, 0.7, 0.75], [0, 1, 1, 0])
const translateLTR = useTransform(scrollYProgress, translateParams, ['-50%', '0%'])
const translateRTL = useTransform(scrollYProgress, translateParams, ['0%', '-50%'])

const translateDirection = (index: number) => (index % 2 === 1 ? translateLTR : translateRTL)

return (
<motion.div
style={{
opacity,
}}
className={css.leftPanelContainer}
>
{Array.from({ length: CRYPTOPUNK_ROWS_NR }).map((_, outerIndex) => (
<motion.div
style={{ translateX: translateDirection(outerIndex) }}
className={css.cryptoPunkColumns}
key={outerIndex}
<PunksGrid scrollYProgress={scrollYProgress} isMobile={isMobile} />
<SlidingPanel
panelWidth={isMobile ? '100%' : '50%'}
scrollParams={isMobile ? [0.4, 0.45, 0.65, 0.7] : [0.25, 0.35, 0.65, 0.75]}
translateParams={['100%', '0%', '0%', '100%']}
scrollYProgress={scrollYProgress}
>
{Array.from({ length: CRYPTOPUNK_COLUMNS_NR }).map((_, innerIndex) => (
<motion.div
key={innerIndex}
initial={{ opacity: 0, scale: 0.5 }}
whileInView={{ opacity: 1, scale: 1 }}
transition={{
duration: 0.3,
}}
style={{
transformOrigin: 'center',
color: getRandomColor(),
}}
>
<CryptoPunk className={css.cryptopunk} />
</motion.div>
))}
</motion.div>
))}
</motion.div>
)
}

const RightPanel = ({
scrollYProgress,
children,
isMobile,
}: {
scrollYProgress: MotionValue<number>
children: ReactNode
isMobile: boolean
}) => {
const opacityParams = isMobile ? [0.4, 0.45, 0.65, 0.66] : [0.25, 0.35, 0.65, 0.7]
const translateParams = isMobile ? [0.4, 0.45, 0.65, 0.7] : [0.25, 0.35, 0.65, 0.75]
const opacity = useTransform(scrollYProgress, opacityParams, [0, 1, 1, 0])
const bgTranslate = useTransform(scrollYProgress, translateParams, ['100%', '0%', '0%', '100%'])

return (
<div className={css.rightPanelContainer}>
<motion.div
className={css.rightPanelContent}
style={{
opacity,
}}
>
{children}
</motion.div>
<motion.div
className={css.rightPanelBG}
style={{
translateX: bgTranslate,
}}
></motion.div>
<Content title={title} text={text} link={link} scrollYProgress={scrollYProgress} />
</SlidingPanel>
</div>
</div>
)
}
Expand Down
44 changes: 5 additions & 39 deletions src/components/DataRoom/CryptoPunks/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,7 @@
display: flex;
}

.rightPanelContainer {
width: 50%;
height: 100%;
position: absolute;
right: 0;
color: var(--mui-palette-text-dark);
overflow-x: hidden;
display: flex;
align-items: flex-end;
padding-top: 64px;
}

.rightPanelContent {
.slidingPanelContent {
z-index: 20;
display: flex;
flex-direction: column;
Expand All @@ -33,14 +21,6 @@
gap: 30px;
}

.rightPanelBG {
position: absolute;
inset: 0;
background-color: var(--mui-palette-primary-main);
z-index: 10;
margin-top: 72px;
}

.percentage {
font-size: 120px;
line-height: 120px;
Expand All @@ -65,7 +45,7 @@
align-items: baseline;
}

.leftPanelContainer {
.punksGrid {
width: 100%;
height: 100%;
overflow: hidden;
Expand Down Expand Up @@ -94,39 +74,25 @@
flex-direction: column-reverse;
}

.leftPanelContainer {
.punksGrid {
padding-top: 72px;
width: 100%;
height: 100%;
overflow: hidden;
}

.rightPanelContainer {
width: 100%;
height: 100%;
position: absolute;
bottom: 0;
}

.rightPanelContent {
.slidingPanelContent {
justify-content: end;
padding: 30px;
gap: 30px;
}

.rightPanelBG {
margin-top: 64px;
}

.statsContainer {
display: flex;
flex-direction: column;
gap: 30px;
}

.leftPanelContainer {
overflow: hidden;
}

.cryptopunk {
width: 60px;
}
Expand Down
40 changes: 40 additions & 0 deletions src/components/DataRoom/IndustryComparison/Content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { BaseBlock } from '@/components/Home/types'
import { Typography } from '@mui/material'
import type { MotionValue } from 'framer-motion'
import { motion, useTransform } from 'framer-motion'
import DotGrid from './DotGrid'
import css from './styles.module.css'
import { useIsMediumScreen } from '@/hooks/useMaxWidth'
import type { RefObject } from 'react'

const Content = ({
scrollYProgress,
title,
containerRef,
}: {
title: BaseBlock['title']
scrollYProgress: MotionValue<number>
containerRef: RefObject<HTMLDivElement>
}) => {
const isMobile = useIsMediumScreen()

const scrollParams = [0.25, 0.35, 0.65, 0.75]
const opacityParams = [0, 1, 1, 0]
const opacity = useTransform(scrollYProgress, scrollParams, opacityParams)

return (
<motion.div
className={css.slidingPanelContent}
style={{
opacity: isMobile ? 1 : opacity,
}}
>
<Typography className={css.title} variant="h1">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this title class, do you?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need it to apply z-index and pointer-events properties. Will remove any font size attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9f82803

{title}
</Typography>
<DotGrid containerRef={containerRef} scrollYProgress={scrollYProgress} />
</motion.div>
)
}

export default Content
Loading
Loading