mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-04 09:15:58 +02:00
feat: add a proof of concept
Using debouncing idea described in https://css-tricks.com/styling-based-on-scroll-position/ to record scrollY value and render the `BoxedTitle` base on the value. The box is hidden when scrollY is greater than 30. The class-style React component is used to register an event listener for scrolling event.
This commit is contained in:
committed by
Jean-Philippe Sirois
parent
47f811373c
commit
38e1a4ba56
@@ -1,4 +1,4 @@
|
||||
import React from "react"
|
||||
import React, { Component } from "react"
|
||||
import cx from "classnames"
|
||||
|
||||
import * as SC from "./styles"
|
||||
@@ -16,6 +16,10 @@ interface IBoxedTitleProps {
|
||||
content?: React.ReactNode
|
||||
}
|
||||
|
||||
type HeaderBareboneState = {
|
||||
scrollY: Number
|
||||
}
|
||||
|
||||
const BoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
|
||||
return (
|
||||
<SC.Box>
|
||||
@@ -35,22 +39,58 @@ const BoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const HeaderBarebone: React.FC<IHeaderBareboneProps> = (props) => {
|
||||
const isBoxed = props.above || props.content
|
||||
|
||||
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>
|
||||
)
|
||||
const debounce = (fn) => {
|
||||
let frame
|
||||
return (...params) => {
|
||||
if (frame) {
|
||||
cancelAnimationFrame(frame)
|
||||
}
|
||||
frame = requestAnimationFrame(() => {
|
||||
fn(...params)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class HeaderBarebone extends Component<IHeaderBareboneProps, HeaderBareboneState> {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.tick = this.tick.bind(this)
|
||||
}
|
||||
|
||||
tick() {
|
||||
this.setState({
|
||||
scrollY: window.scrollY
|
||||
})
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.tick()
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('scroll', debounce(this.tick), { passive: true })
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const isBoxed = props.above || props.content
|
||||
|
||||
return (
|
||||
<SC.HeaderWrapper className={props.className}>
|
||||
<SC.Background />
|
||||
|
||||
<Container>
|
||||
{(isBoxed && this.state.scrollY < 30) && (
|
||||
<BoxedTitle above={props.above} content={props.content}>
|
||||
{props.title}
|
||||
</BoxedTitle>
|
||||
)}
|
||||
|
||||
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
|
||||
</Container>
|
||||
</SC.HeaderWrapper>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user