Вообщем у меня было странная задумка. Я делаю сайт, механика такова, что пользователь заходит на сайт, может скролить вниз и вверх, при клике на какую нибудь вкладку в навбаре удалются все дом элементы и создаются два новых страница на которой находится пользователь и страница на которую он должен попасть. Попадает он на неё при помощи gsap горизонтального скролла и при помощи библиотеки react-scroll. Вообще реализация работает, но есть помеха, она заключается в том что пока реализуется handleClick() пользователь не может кликать, скролить, нажимать какие либо клавиши на сайте, иначе анимация скроло просто прекращается и просто появляется страница на которую кликнул пользователь в навбаре. Реализация странная, тк я в реакт и в js всего полтора месяца. Хотел бы обратиться за помощью как правильно реализовать мой кривой код?
Вот и он:
App:
import './App.css';
import {Header} from "./components/header/Header";
import {Main} from "./components/main/Main";
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";
import React, {useLayoutEffect, useRef, useState} from "react";
import './styles.css'
gsap.registerPlugin(ScrollTrigger);
function App() {
const [data, setData]
= useState({state: false,
panel: {object: <Main/>, colors: ['#4d4d4d','#fff','#4d4d4d','#4d4d4d','#4d4d4d']},
panelBefore: {object: <Main/>, colors: ['#4d4d4d','#fff','#4d4d4d','#4d4d4d','#4d4d4d']},
navBarPos: 'absolute'})
const handleData = (state, panel, panelBefore, navBarPos) => {
setData({state: state, panel: panel, panelBefore: panelBefore, navBarPos: navBarPos})
}
const component = useRef();
const slider = useRef();
useLayoutEffect(() => {
let ctx = gsap.context(() => {
let panels = gsap.utils.toArray(".panel");
gsap.to(panels, {
xPercent: -100 * (panels.length),
ease: "none",
scrollTrigger: {
trigger: slider.current,
pin: true,
scrub: 0,
snap: 0 / (panels.length - 1),
end: () => "+=" + slider.current.offsetWidth
}
});
}, component);
return () => ctx.revert();
})
return (
<>
<div key={'a'} ><Header handleData={handleData} color={data.panel.colors} state={data.state} position={data.navBarPos}/></div>
{
!data.state ?
(<>
<div key={'b'} style={{display: 'none'}} ref={component}>
<div key={'c'} ref={slider}></div>
</div>
{data.panel.object}
</>
)
:
(<div key={'d'} ref={component}>
<div key={'e'} ref={slider} className="container">
<div key={'f'} className="panel">{data.panelBefore.object}</div>
<div key={'g'} className="panel">{data.panel.object}/></div>
</div>
</div>)
}
</>
);
}
export default App;
Header:
import React from "react";
import {NavBar} from './NavBar'
import styled from 'styled-components';
export const Header = (props) => {
const handleData = props.handleData
const position = props.position
const color = props.color
return (
<>
<Wrapper position={position} >
<Label>
</Label>
<NavBarStyles>
<NavBar handleData={handleData} color={color} />
</NavBarStyles>
<SocialMedia>
</SocialMedia>
</Wrapper>
</>
);
}
NavBar:
import React from "react";
import {motion} from "framer-motion";
import {useState} from "react";
import {Main} from "../main/Main";
import {Services} from "../services/Services";
import {Contacts} from "../contacts/Contacts";
import {Works} from "../works/Works";
import {About} from "../about/About";
import $ from "jquery";
import styled from "styled-components";
let handleData
export const NavBar = (props) => {
handleData = props.handleData
const [selected, setSelected] = useState(false)
const [getPanel, setPanel] = useState( {object: <Main/>, colors: ['#4d4d4d','#fff','#4d4d4d','#4d4d4d','#4d4d4d']})
const [activeIndex, setActive] = useState(0)
const Scroll = require('react-scroll');
const scroll = Scroll.animateScroll;
const menuData = [{
name: 'главная', scroll: function () {
scroll.scrollTo(window.innerWidth)
},
panel: {object: <Main/>, colors: ['#4d4d4d','#e8e6e6','#4d4d4d','#4d4d4d','#4d4d4d']},
color: props.color[0],
number: 0
},
{
name: 'обо мне', scroll: function () {
scroll.scrollTo(window.innerWidth)
},
panel: {object: <About/>, colors: ['#4d4d4d','#4d4d4d','#4d4d4d','#4d4d4d','#4d4d4d']},
color: props.color[1],
number: 1
},
{
name: 'мои работы', scroll: function () {
scroll.scrollTo(window.innerWidth)
},
panel: {object: <Works/>, colors: ['#4d4d4d','#4d4d4d','#4d4d4d','#4d4d4d','#4d4d4d']},
color: props.color[2],
number: 2
},
{
name: 'услуги', scroll: function () {
scroll.scrollTo(window.innerWidth)
},
panel: {object: <Services/>, colors: ['#4d4d4d','#4d4d4d','#4d4d4d','#4d4d4d','#4d4d4d']},
color: props.color[3],
number: 3
},
{
name: 'контакты', scroll: function () {
scroll.scrollTo(window.innerWidth)
},
panel: {object: <Contacts/>, colors: ['#4d4d4d','#4d4d4d','#4d4d4d','#4d4d4d','#4d4d4d']},
color: props.color[4],
number: 4
}]
const handleClick = (item, index) => {
setActive(index)
handleData(true, item.panel, getPanel, 'fixed')
$('html').css('overflow-y', 'hidden')
item.scroll()
setSelected(true)
setTimeout(function () {
setPanel(item.panel)
}, 1100)
setTimeout(function () {
window.scrollTo(0, 0)
}, 1200)
setTimeout(function () {
handleData(false, item.panel, getPanel, 'absolute')
$('html').css('overflow-y', 'visible')
$('window').css('height', '100vh')
setSelected(false)
}, 1200)
}
return (
<>
<Wrapper>
{
menuData.map((item, index) => (
<MenuItem
key={'a'}
item={item}
isSelected={activeIndex === index}
handleClick={() => selected === false && handleClick(item, index)}
selected={selected}
/>
))
}
</Wrapper>
</>
);
}
const MenuItem = (props) => {
const {
item,
isSelected,
handleClick,
selected
} = props;
return (
<motion.div
onClick = {handleClick}
>
{isSelected && <ActiveLine item={item} color={item.color}/>}
<Item color={item.color} pointerEvents={selected ? 'none':'auto'}>
{item.name}
</Item>
</motion.div>
);
}
const ActiveLine = (props) => {
const color = props.color
return (
<>
<motion.div
layoutId='size'
transition={{
duration: 1
}}
>
<Line color={color} />
</motion.div>
</>
);
}
styles.css:
.container {
width: 200vw;
height: 100vh;
display: flex;
flex-wrap: wrap;
}
.firstContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
background: yellow;
}
.lastContainer {
display: flex;
height: 100vh;
background: yellow;
}
.panel {
width: 100vw;
height: 100vh;
}
Все компоненты которые я не скинул и присутствующие в коде не имеют логики, имеют только стили.