mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-04 09:15:58 +02:00
fix: move to a more stable scroll API to avoid jumping
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, { Component } from "react"
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { useDebounce, useWindowScroll } from "react-use"
|
||||
import cx from "classnames"
|
||||
|
||||
import * as SC from "./styles"
|
||||
@@ -16,10 +17,6 @@ interface IBoxedTitleProps {
|
||||
content?: React.ReactNode
|
||||
}
|
||||
|
||||
type HeaderBareboneState = {
|
||||
scrollY: number
|
||||
}
|
||||
|
||||
const BoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
|
||||
return (
|
||||
<SC.Box>
|
||||
@@ -59,86 +56,63 @@ const StickyBoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
|
||||
}
|
||||
|
||||
const StickyContainer: React.FC = ({ children, ...restProps }) => {
|
||||
return <SC.StickyContainerWrapper {...restProps}>{children}</SC.StickyContainerWrapper>
|
||||
return (
|
||||
<SC.StickyContainerWrapper {...restProps}>
|
||||
{children}
|
||||
</SC.StickyContainerWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
const debounce = (fn) => {
|
||||
let frame
|
||||
return (...params) => {
|
||||
if (frame) {
|
||||
cancelAnimationFrame(frame)
|
||||
export const HeaderBarebone = (props: IHeaderBareboneProps) => {
|
||||
const { y } = useWindowScroll()
|
||||
const [scrollY, setScrollY] = useState(0)
|
||||
|
||||
const [, cancel] = useDebounce(
|
||||
() => {
|
||||
setScrollY(y)
|
||||
},
|
||||
10,
|
||||
[y]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
cancel()
|
||||
}
|
||||
frame = requestAnimationFrame(() => {
|
||||
fn(...params)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class HeaderBarebone extends Component<IHeaderBareboneProps, HeaderBareboneState> {
|
||||
controller: AbortController
|
||||
state: HeaderBareboneState = {
|
||||
scrollY: 0
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.tick = this.tick.bind(this)
|
||||
}
|
||||
|
||||
tick() {
|
||||
if (typeof window !== 'undefined') {
|
||||
this.setState({
|
||||
scrollY: window.scrollY
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.controller = new AbortController()
|
||||
document.addEventListener('scroll', debounce(this.tick), { passive: true, signal: this.controller.signal })
|
||||
this.tick()
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.controller.abort()
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const isBoxed = props.above || props.content
|
||||
|
||||
if (this.state.scrollY <= 250) {
|
||||
return (
|
||||
<SC.HeaderWrapper className={props.className}>
|
||||
<SC.Background />
|
||||
|
||||
<Container>
|
||||
{isBoxed && (
|
||||
<BoxedTitle above={props.above} content={props.content}>
|
||||
{props.title}
|
||||
</BoxedTitle>
|
||||
)}
|
||||
|
||||
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
|
||||
</Container>
|
||||
</SC.HeaderWrapper>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<SC.HeaderWrapperSticky className={props.className}>
|
||||
<SC.Background />
|
||||
|
||||
<StickyContainer>
|
||||
{isBoxed && (
|
||||
<StickyBoxedTitle above={props.above}>
|
||||
{props.title}
|
||||
</StickyBoxedTitle>
|
||||
)}
|
||||
|
||||
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
|
||||
</StickyContainer>
|
||||
</SC.HeaderWrapperSticky>
|
||||
)
|
||||
}
|
||||
}
|
||||
}, [cancel])
|
||||
|
||||
const isBoxed = props.above || props.content
|
||||
|
||||
const stickyHeader = (
|
||||
<SC.HeaderWrapperSticky className={props.className}>
|
||||
<SC.Background />
|
||||
|
||||
<StickyContainer>
|
||||
{isBoxed && (
|
||||
<StickyBoxedTitle above={props.above}>{props.title}</StickyBoxedTitle>
|
||||
)}
|
||||
|
||||
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
|
||||
</StickyContainer>
|
||||
</SC.HeaderWrapperSticky>
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<SC.HeaderWrapper className={props.className}>
|
||||
<SC.Background />
|
||||
|
||||
<Container>
|
||||
{isBoxed && (
|
||||
<BoxedTitle above={props.above} content={props.content}>
|
||||
{props.title}
|
||||
</BoxedTitle>
|
||||
)}
|
||||
|
||||
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
|
||||
</Container>
|
||||
</SC.HeaderWrapper>
|
||||
{scrollY >= 270 && stickyHeader}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export const Sidebar = styled.div`
|
||||
margin: 64px 0;
|
||||
padding: 0 32px;
|
||||
position: sticky;
|
||||
top: 32px;
|
||||
top: 119px;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
||||
Reference in New Issue
Block a user