diff --git a/packages/magickbase/package.json b/packages/magickbase/package.json index acfc0b1b..c1114ddc 100644 --- a/packages/magickbase/package.json +++ b/packages/magickbase/package.json @@ -22,6 +22,7 @@ "next-i18next": "15.0.0", "react": "18.2.0", "react-dom": "18.2.0", + "react-page-scroller": "^3.0.1", "react-use": "17.4.0", "tailwindcss": "3.3.5", "typescript": "5.2.2" diff --git a/packages/magickbase/src/components/About/index.tsx b/packages/magickbase/src/components/About/index.tsx index b5b54088..b434e7a8 100644 --- a/packages/magickbase/src/components/About/index.tsx +++ b/packages/magickbase/src/components/About/index.tsx @@ -1,6 +1,9 @@ +import { useEffect, useRef } from 'react' import type { FC } from 'react' import classnames from 'classnames' import Spline from '@splinetool/react-spline' +import { useScroll } from 'react-use' +import type { Application } from '@splinetool/runtime' import styles from './styles.module.scss' const timelineItms = [ @@ -41,37 +44,96 @@ const timelineItms = [

At Magickbase, we believe in the power of community, collaboration, and inclusivity. We're a team of - passionate developers who are committed to making a difference in the world, and we're always looking for ways - to learn from each other and grow together. + passionate developers who are committed to making a difference in the world, and we're always looking for + ways to learn from each other and grow together.

), }, ] -export const AboutUs: FC = () => ( -
-

About us

-
-
- {timelineItms.map((item, index) => ( -
-
{(index + 1).toString().padStart(2, "0")}
-

{item.title}

- {item.description} -
- ))} -
+interface AboutUsProps { + onScrollPositionChange?: (position: 'top' | 'middle' | 'bottom') => void +} + +export const AboutUs: FC = ({ onScrollPositionChange }) => { + const spline = useRef() + const scrollRef = useRef(null) + const itemsRef = useRef(Array(timelineItms.length).fill(null)) + const { y } = useScroll(scrollRef) + + useEffect(() => { + if (!spline.current) return + const obj = spline.current.findObjectByName('旋转') + if (!obj) return + + const scrollEndOffset = (scrollRef.current?.scrollHeight || 0) - (scrollRef.current?.offsetHeight || 0) + + obj.rotation.x = Math.PI * 2 * (y / scrollEndOffset) + + }, [y, spline, scrollRef]) + + const position = (() => { + if (y === 0) { + return 'top' + } else if (y === (scrollRef.current?.scrollHeight || 0) - (scrollRef.current?.offsetHeight || 0)) { + return 'bottom' + } + + return 'middle' + })() + + onScrollPositionChange && onScrollPositionChange(position) + + const activeItemIndex = (() => { + let index = 0 + const { top, height } = scrollRef.current?.getBoundingClientRect() || { top: 0, height: 0 } + + const point = top + height / 2 + + itemsRef.current.forEach((item, i) => { + if (item) { + const { top: itemTop } = item.getBoundingClientRect() + if (itemTop < point) { + index = i + } + } + }) + return index + })() + + return ( +
+

About us

+
+
+ {timelineItms.map((item, index) => ( +
(itemsRef.current[index] = el)} + key={index} + className={classnames(styles.item, { + [styles.active]: activeItemIndex === index, + })} + > +
{(index + 1).toString().padStart(2, '0')}
+

{item.title}

+ {item.description} +
+ ))} +
+
-
- { - console.log(app) - }} - /> +
+ { + app.stop() + spline.current = app + }} + /> +
-
-) + ) +} diff --git a/packages/magickbase/src/components/About/styles.module.scss b/packages/magickbase/src/components/About/styles.module.scss index 78f95a8b..f16501b6 100644 --- a/packages/magickbase/src/components/About/styles.module.scss +++ b/packages/magickbase/src/components/About/styles.module.scss @@ -1,19 +1,41 @@ .timeline { position: relative; - &::after { - content: " "; - position: absolute; - width: 1px; - left: 0; - top: 8px; - bottom: 0; - background-color: #fff; - } .item { padding-left: 24px; padding-bottom: 64px; position: relative; + transition: all .3s; + color: #646464; + + &.active { + color: #fff; + + &:last-child::before { + background: linear-gradient(180deg, #fff, #000); + } + &::before { + background: #fff; + } + &::after { + background: #fff; + } + } + + &:last-child::before { + background: linear-gradient(180deg, #646464, #000); + } + + &::before { + content: " "; + position: absolute; + width: 1px; + left: 0; + top: 8px; + bottom: -8px; + transition: all .3s; + background: #646464; + } &::after { content: " "; width: 12px; @@ -22,7 +44,8 @@ top: 5px; left: -6px; border-radius: 999px; - background-color: #fff; + transition: all .3s; + background-color: #646464; } .index { font-size: 20px; @@ -44,5 +67,8 @@ } .splineWrapper { - pointer-events: none; + canvas { + width: 100% !important; + height: 100% !important; + } } diff --git a/packages/magickbase/src/components/ContactUs/index.tsx b/packages/magickbase/src/components/ContactUs/index.tsx index d3c66c5f..01a98243 100644 --- a/packages/magickbase/src/components/ContactUs/index.tsx +++ b/packages/magickbase/src/components/ContactUs/index.tsx @@ -1,25 +1,25 @@ import type { FC } from 'react' import classnames from 'classnames' -import logoPng from './logo.png' -import maskTopPng from './mask_top.png' -import maskBottomPng from './mask_bottom.png' +import Spline from '@splinetool/react-spline' export const ContactUs: FC = () => ( -
-
-
- +
+
+ +
-
+
-
-

Contact us

-

+

+

Contact us

+

Magickbase consistently adheres to the spirit of open source mutual benefit, and welcomes users to participate in the construction of the product and learn from each other to grow together.

- +
diff --git a/packages/magickbase/src/components/ContactUs/logo.png b/packages/magickbase/src/components/ContactUs/logo.png deleted file mode 100644 index e99489e3..00000000 Binary files a/packages/magickbase/src/components/ContactUs/logo.png and /dev/null differ diff --git a/packages/magickbase/src/components/ContactUs/mask_bottom.png b/packages/magickbase/src/components/ContactUs/mask_bottom.png deleted file mode 100644 index 6e746b28..00000000 Binary files a/packages/magickbase/src/components/ContactUs/mask_bottom.png and /dev/null differ diff --git a/packages/magickbase/src/components/ContactUs/mask_top.png b/packages/magickbase/src/components/ContactUs/mask_top.png deleted file mode 100644 index c6699f93..00000000 Binary files a/packages/magickbase/src/components/ContactUs/mask_top.png and /dev/null differ diff --git a/packages/magickbase/src/components/Header/index.module.scss b/packages/magickbase/src/components/Header/index.module.scss index 177e42a3..e0f3a407 100644 --- a/packages/magickbase/src/components/Header/index.module.scss +++ b/packages/magickbase/src/components/Header/index.module.scss @@ -120,6 +120,9 @@ $desktopHeaderContentHeight: 88px; padding: 0 var(--menuIconRightOffset) 96px 96px; color: #f5f5f5; background: #111; + padding-right: 24px; + padding-left: 64px; + padding-bottom: 64px; &:focus-visible { outline: none; diff --git a/packages/magickbase/src/components/Services/index.tsx b/packages/magickbase/src/components/Services/index.tsx index ab3bab05..bf5de2bb 100644 --- a/packages/magickbase/src/components/Services/index.tsx +++ b/packages/magickbase/src/components/Services/index.tsx @@ -1,26 +1,32 @@ import type { FC } from 'react' -import neuronBg from './neuron_bg.png'; -import MoreIcon from './more.svg'; +import neuronBg from './neuron_bg.png' +import MoreIcon from './more.svg' export const Services: FC = () => ( -
-
+
+
-
-

Neuron

-
-
CKB desktop wallet
- +
+
+

Neuron

+
+
CKB desktop wallet
+
-
-
-
Neuron
-
CKB Explorer
-
Godwoken Explorer
-
Axon Explorer
-
Kuai
+
+
Neuron
+
CKB Explorer
+
Godwoken Explorer
+
Axon Explorer
+
Kuai
+
) diff --git a/packages/magickbase/src/pages/index.tsx b/packages/magickbase/src/pages/index.tsx index b7652a71..8efb372b 100644 --- a/packages/magickbase/src/pages/index.tsx +++ b/packages/magickbase/src/pages/index.tsx @@ -1,22 +1,34 @@ +import { useState } from 'react' +import ReactPageScroller from 'react-page-scroller' import { Footer } from '../components/Footer' import { Header } from '../components/Header' import { Branding } from '../components/Branding' import { AboutUs } from '../components/About' import { ContactUs } from '../components/ContactUs' import { Services } from '../components/Services' -import styles from './page.module.css' export default function Home() { + const [currentPage, setCurrentPage] = useState(0) + const [aboutUsScrollPosition, setAboutUsScrollPosition] = useState('top') + const isAbout = currentPage === 1 + return ( -
+
- -
- -
- - -