This commit is contained in:
Дмитрий Савенко 2023-02-10 19:58:28 +03:00
parent 487da1c08b
commit 113520e22c
39 changed files with 4398 additions and 67 deletions

3937
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,11 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"devDependencies": {
"sass": "^1.58.0",
"sass-loader": "^13.2.0",
"node-sass": "8.0.0"
},
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",

View File

@ -1,38 +1,8 @@
.App { * {
text-align: center; margin: 0;
} padding: 0;
box-sizing: border-box;
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
} }
html {
/*overflow-x: hidden;*/
} }

View File

@ -1,24 +1,18 @@
import logo from './logo.svg'; import React from "react";
import {Header} from "./components/Header/Header";
import {Main} from "./components/Main/Main";
import {Footer} from "./components/Footer/Footer";
import './App.css'; import './App.css';
function App() { function App() {
return ( return (
<div className="App"> <>
<header className="App-header"> <Header/>
<img src={logo} className="App-logo" alt="logo" /> <Main/>
<p> <Footer/>
Edit <code>src/App.js</code> and save to reload. </>
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
); );
} }

View File

@ -0,0 +1,30 @@
import React from "react";
import './contentBlock.scss'
export const ContentBlock = ({props: {title, content}}) => {
const evenFn = (number) => !!number % 2 === 0;
return (
<div className='contentBlock'>
<h2 className='contentBlock__title'>
{title}
</h2>
{Array.isArray(content) && content.map((el, index) =>
<div className={`contentBlock__wrapper ${!evenFn(index) ? 'contentBlock__wrapper--even' : ''}`}
key={`${title}-${index}`}>
<div className='contentBlock__imageWrapper'>
<img className='contentBlock__image' src={el.img} alt="Content"/>
</div>
<div className='contentBlock__content'>
<h3 className='contentBlock__subtitle'>{el.subTitle}</h3>
<p className='contentBlock__text'>{el.text}</p>
</div>
</div>
)}
</div>
)
};

View File

@ -0,0 +1,73 @@
.contentBlock {
max-width: 1588px;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
&__title {
text-align: center;
font-family: "Orchidea Pro", sans-serif;
font-size: 48px;
font-weight: 500;
margin: 200px 0 120px;
text-transform: uppercase;
}
&__imageWrapper {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
object-fit: contain;
max-width: 860px;
max-height: 480px;
}
&__image {
width: 100%;
height: auto;
}
&__content {
max-width: 600px;
}
&__subtitle {
font-family: "Orchidea Pro", sans-serif;
font-size: 48px;
font-weight: 500;
margin-bottom: 25px;
}
&__text {
font-family: "Manrope", sans-serif;
font-size: 18px;
font-weight: 500;
}
&__wrapper {
display: grid;
grid-row: revert;
grid-template-columns: 2.2fr 1.5fr;
gap: 120px;
margin-bottom: 100px;
&--even {
.contentBlock {
&__imageWrapper {
order: 2
}
&__content {
margin-left: auto;
}
}
}
}
}

View File

@ -0,0 +1,12 @@
import React from "react";
import './footer.scss'
export const Footer = () => {
return (
<footer className='footer'>
<p className='footer__text'> © TEST, 10222022</p>
</footer>
)
};

View File

@ -0,0 +1,13 @@
.footer {
width: 100%;
height: 200px;
background: #141414;
&__text {
font-family: "Roboto", sans-serif;
color: white;
text-align: center;
position: relative;
padding-top: 150px;
}
}

View File

@ -0,0 +1,16 @@
import React from "react";
import './header.scss'
import logo from './logo.png'
export const Header = () => {
return (
<header className='header'>
<div className='header__container'>
<div className='header__logo'>
<img className='header__logoImg' src={logo} alt="logo"/>
</div>
<div className='header__phone'>+7 (495) 495-49-54</div>
</div>
</header>
)
};

View File

@ -0,0 +1,23 @@
.header {
height: 100px;
background: linear-gradient(0deg, #464341 0%, #010101 100%);
&__phone {
color: white;
font-family: 'Manrope', sans-serif;
font-weight: 500;
font-size: 24px;
}
&__container {
padding: 0 20px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 100%;
max-width: 1280px;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,15 @@
import React from "react";
import {ContentBlock} from "../ContentBlock/ContentBlock";
import {ScrollContent} from "../ScrollContent/ScrollContent";
import {mockData, scrollData} from "./mock/mock";
export const Main = () => {
return (
<div className='main'>
<ContentBlock props={mockData[0]}/>
<ScrollContent data={scrollData}/>
<ContentBlock props={mockData[1]}/>
</div>
)
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

View File

@ -0,0 +1,52 @@
import img1_1 from './img1-1.png'
import img1_2 from './img1-2.png'
import img2_1 from './img2-1.png'
import img2_2 from './img2-2.png'
import scroll1 from './scroll1.png'
import scroll2 from './scroll2.png'
import scroll3 from './scroll3.png'
import scroll4 from './scroll4.png'
import scroll5 from './scroll5.png'
import scroll6 from './scroll6.png'
import scroll7 from './scroll7.png'
import scroll8 from './scroll8.png'
export const mockData = [
{
title: 'ut aliquip ex ea commodo consequat',
content: [{
img: img1_1,
subTitle: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
text: 'Incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n' +
'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
},
{
img: img1_2,
subTitle: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
text: 'Incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n' +
'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
},
]
},
{
title: "ut aliquip ex ea commodo consequat",
content: [
{
img: img2_1,
subTitle: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
text: 'Incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n' +
'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
},
{
img: img2_2,
subTitle: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
text: 'Incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.\n' +
'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
},
]
}
];
export const scrollData = [scroll1, scroll2, scroll3, scroll4, scroll5, scroll6, scroll7, scroll8, scroll3, scroll4, scroll5, scroll6, scroll7, scroll8]

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

View File

@ -0,0 +1,128 @@
import React, {useEffect, useRef, useState} from "react";
import './scrollContent.scss'
const throttle = (func, limit) => {
let lastFunc;
let lastRan;
return function () {
const context = this;
const args = arguments;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now()
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function () {
if ((Date.now() - lastRan) >= limit) {
func.apply(context, args);
lastRan = Date.now()
}
}, limit - (Date.now() - lastRan))
}
}
};
export const ScrollContent = ({data}) => {
const [stiky, setStiky] = useState();
const [scrollStep, setScrollStep] = useState();
const stikyRef = useRef();
useEffect(() => {
setStiky(stikyRef.current);
}, []);
useEffect(() => {
if (stiky) {
bindEvents();
setStickyContainerSize()
}
}, [stiky, data]);
useEffect(() => {
setScrollStep(document.documentElement.scrollTop)
}, []);
function bindEvents() {
// window.addEventListener('wheel', wheelHandler);
window.onscroll = throttle(scrollHandler, 400);
}
function setStickyContainerSize() {
stiky.setAttribute('style', `height:${stiky.scrollWidth}px`);
}
function isElementInViewport(el) {
if (el) {
const rect = el.getBoundingClientRect();
return rect.top <= 0 && rect.bottom > document.documentElement.clientHeight;
} else {
return null
}
}
function scrollHandler(evt) {
const containerInViewPort = isElementInViewport(stiky) && stiky;
if (!containerInViewPort) {
return;
}
console.log(window.scrollY);
const body = document.body,
html = document.documentElement;
const height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
// console.log(height - window.scrollY);
console.log(containerInViewPort.offsetTop, 'Расстояние от начала документа');
console.log(document.documentElement.clientHeight, 'Высота Экран');
console.log(document.documentElement.scrollTop, 'Текущая высота скрола');
setScrollStep((prev) => prev < 0 ? prev + document.documentElement.scrollTop : prev - document.documentElement.scrollTop)
console.log(scrollStep, "ASDASD");
console.log(containerInViewPort.offsetHeight, 'Высота родительского блока для определения горизонтального скрола');
const isPlaceHolderBelowTop = containerInViewPort.offsetTop < document.documentElement.scrollTop;
const isPlaceHolderBelowBottom = containerInViewPort.offsetTop + containerInViewPort.offsetHeight > document.documentElement.scrollTop;
const g_canScrollHorizontally = isPlaceHolderBelowTop && isPlaceHolderBelowBottom;
// console.log(isPlaceHolderBelowBottom, 'Хуйня');
if (g_canScrollHorizontally) {
containerInViewPort.scrollLeft = containerInViewPort.scrollLeft + evt.deltaY;
}
}
return (
<div className='scroll'>
<h3 className='scroll__title'>Lorem ipsum dolor sit amet</h3>
<div className='scroll__content sticky-container' id='scroll_container' ref={stikyRef}>
<div className="scroll__hiddenWrapper">
{
data.map((img, index) =>
<div className='scroll__item' key={`scroll-${index}`}>
<img className='scroll__image' src={img} alt="scrollContent"/>
</div>
)
}
</div>
</div>
</div>
)
};

View File

@ -0,0 +1,52 @@
.scroll {
display: flex;
flex-direction: column;
max-width: 1558px;
margin-left: auto;
&__title {
font-family: "Orchidea Pro", sans-serif;
font-weight: 500;
font-size: 48px;
text-transform: uppercase;
position: sticky;
}
&__content {
width: 100%;
}
.sticky-container {
transition: all ease 0.3s;
min-height: 100vh;
position: relative;
overflow: hidden;
}
&__hiddenWrapper {
transform-style: preserve-3d;
transition: all ease 3s;
//display: inline-flex;
display: flex;
//display: inline-block;
position: sticky;
position:-webkit-sticky;
top: 0px;
}
&__item {
height: 488px;
object-fit: contain;
overflow: hidden;
min-width: 320px;
margin: 0 20px;
//flex-shrink: 0;
}
&__image {
width: 100%;
height: auto;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

27
src/fonts/fonts.css Normal file
View File

@ -0,0 +1,27 @@
@font-face {
font-family: 'Manrope';
src: url('./Manrope/Manrope-Medium.woff2') format('woff2'),
url('./Manrope/Manrope-Medium.woff') format('woff'),
url('./Manrope/Manrope-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Orchidea Pro';
src: url('./OrchideaPro/OrchideaPro-Medium.woff2') format('woff2'),
url('./OrchideaPro/OrchideaPro-Medium.woff') format('woff'),
url('./OrchideaPro/OrchideaPro-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Roboto';
src: url('./Roboto/Roboto-Medium.woff2') format('woff2'),
url('./Roboto/Roboto-Medium.woff') format('woff'),
url('./Roboto/Roboto-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}

View File

@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App'; import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
import './index.css';
import '../src/fonts/fonts.css'
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( root.render(

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB