products layers
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 383 KiB |
@@ -1,4 +1,4 @@
|
||||
import { Marquee } from '../Main/Marquee';
|
||||
// import { Marquee } from '../Main/Marquee';
|
||||
|
||||
export function Motivation() {
|
||||
return (
|
||||
@@ -18,7 +18,7 @@ export function Motivation() {
|
||||
производительность
|
||||
</h3>
|
||||
</div>
|
||||
<Marquee />
|
||||
{/* <Marquee /> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,70 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { ForTeaching } from './Tabs/ForTeachingTab';
|
||||
import { Simulators } from './Tabs/SimulatorsTab';
|
||||
import { IndustrialTrainings } from './Tabs/TrainingsTab';
|
||||
|
||||
export function Products() {
|
||||
const ref1 = useRef<HTMLDivElement>(null);
|
||||
const ref2 = useRef<HTMLDivElement>(null);
|
||||
const ref3 = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [stiked1, setSticked1] = useState(false);
|
||||
const [stiked2, setSticked2] = useState(false);
|
||||
|
||||
function handleMouseMove(e: WheelEvent) {
|
||||
setSticked1(
|
||||
Math.round(ref2.current!.getBoundingClientRect().top) <=
|
||||
+window.getComputedStyle(ref2.current!).top.slice(0, -2),
|
||||
);
|
||||
setSticked2(
|
||||
Math.round(ref3.current!.getBoundingClientRect().top) <=
|
||||
+window.getComputedStyle(ref3.current!).top.slice(0, -2),
|
||||
);
|
||||
if (e.deltaY > 0) {
|
||||
if (
|
||||
ref1.current!.getBoundingClientRect().top ===
|
||||
+window.getComputedStyle(ref1.current!).top.slice(0, -2) &&
|
||||
Math.round(ref2.current!.getBoundingClientRect().top) !==
|
||||
+window.getComputedStyle(ref2.current!).top.slice(0, -2)
|
||||
) {
|
||||
window.scrollBy({
|
||||
behavior: 'smooth',
|
||||
top:
|
||||
ref2.current!.getBoundingClientRect().top -
|
||||
+window.getComputedStyle(ref2.current!).top.slice(0, -2),
|
||||
});
|
||||
setSticked1(true);
|
||||
}
|
||||
if (
|
||||
Math.round(ref2.current!.getBoundingClientRect().top) ===
|
||||
+window.getComputedStyle(ref2.current!).top.slice(0, -2)
|
||||
) {
|
||||
window.scrollBy({
|
||||
top:
|
||||
ref3.current!.getBoundingClientRect().top -
|
||||
+window.getComputedStyle(ref3.current!).top.slice(0, -2),
|
||||
});
|
||||
setSticked2(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
window?.addEventListener('wheel', handleMouseMove);
|
||||
|
||||
return () => {
|
||||
window?.removeEventListener('wheel', handleMouseMove);
|
||||
};
|
||||
}, [ref1, ref2, ref3]);
|
||||
|
||||
return (
|
||||
<div
|
||||
id="products"
|
||||
className="lg:py-[40px] sm:max-lg:pt-14 sm:max-lg:pb-8 max-sm:py-14 lg:-mx-10 sm:-mx-6 -mx-4 lg:aspect-[1600/923] sm:aspect-[768/672] aspect-[360/856]"
|
||||
className="lg:pt-[100px] sm:max-lg:pt-[70px] max-sm:py-14 lg:-mx-10 sm:-mx-6 -mx-4 sm:space-y-[500px]"
|
||||
>
|
||||
<IndustrialTrainings />
|
||||
<Simulators />
|
||||
<ForTeaching />
|
||||
<IndustrialTrainings ref={ref1} sticked={stiked1} />
|
||||
<Simulators ref={ref2} sticked={stiked2} />
|
||||
<ForTeaching ref={ref3} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useRef } from 'react';
|
||||
import { forwardRef, useRef } from 'react';
|
||||
import { useHover } from 'usehooks-ts';
|
||||
import { getIcon } from '../../../../utils/getIcon';
|
||||
import { useInView } from 'framer-motion';
|
||||
@@ -35,35 +35,47 @@ function ForTeachingOption({
|
||||
);
|
||||
}
|
||||
|
||||
export function ForTeaching() {
|
||||
export const ForTeaching = forwardRef<HTMLDivElement>((_, ref) => {
|
||||
return (
|
||||
<div
|
||||
id="teaching"
|
||||
className="lg:ml-[129px] lg:aspect-[1471/647] sm:aspect-[768/672] aspect-[360/856] sm:sticky z-50 lg:top-[calc(276/647*100%)] sm:top-[calc(176/672*100%)] lg:p-10 xl:pb-[98px] sm:p-6 sm:pb-44 p-4 lg:space-y-14 sm:space-y-10 space-y-6 [background:right_bottom/60%_url(src/assets/products/teaching/teaching.png)_no-repeat,#14161F] bg-[length:calc((880-195)/1600*100vw)] bg-no-repeat lg:border-l border-t border-[#3D425C]"
|
||||
ref={ref}
|
||||
className="lg:ml-[129px] lg:min-h-[calc(100vh-276px)] lg:min-w-[calc(100vw-129px)] sm:min-h-[calc(100vh-176px)] min-h-[calc(100vh)] min-w-[100vw] sm:sticky z-50 lg:top-[276px] sm:top-[176px] top-0 lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 lg:border-l bg-[#14161F] border-t border-[#3D425C]"
|
||||
>
|
||||
<h2 className={'h2 font-medium flex justify-between'}>
|
||||
Интерактивные тренажеры для учебных заведений
|
||||
<p className="h3 font-medium text-[#3D425C]">03</p>
|
||||
</h2>
|
||||
<div className="lg:space-y-14 sm:space-y-10 space-y-6 max-w-[calc(413/768*100vw)]">
|
||||
<div className="lg:space-y-7 space-y-4 xl:max-w-[calc(507/1600*100vw)] lg:max-w-[40vw]">
|
||||
<ForTeachingOption
|
||||
title="cоздание обучающих VR систем"
|
||||
description="Проведение виртуальных практических работ, создание учебных мастерских и стендов"
|
||||
type="teaching"
|
||||
/>
|
||||
<ForTeachingOption
|
||||
title="cоздание VR лабораторий"
|
||||
description="Тренажер для проведения лабораториных работ позволит избежать
|
||||
поломки оборудования, а также экономить на расходных средствах"
|
||||
type="labs"
|
||||
/>
|
||||
<p className="lg:text-2xl sm:text-xl font-medium">
|
||||
Оснащение учебных классов и центров всем необходимым для
|
||||
современного обучения под «ключ»
|
||||
</p>
|
||||
<div className="flex justify-between max-sm:flex-col">
|
||||
<div className="lg:space-y-14 sm:space-y-10 space-y-6 sm:max-w-[calc(413/768*100vw)] lg:mt-14 sm:mt-10 mt-6">
|
||||
<div className="lg:space-y-7 space-y-4 xl:max-w-[calc(507/1600*100vw)] lg:max-w-[40vw] flex-1">
|
||||
<ForTeachingOption
|
||||
title="cоздание обучающих VR систем"
|
||||
description="Проведение виртуальных практических работ, создание учебных мастерских и стендов"
|
||||
type="teaching"
|
||||
/>
|
||||
<ForTeachingOption
|
||||
title="cоздание VR лабораторий"
|
||||
description="Тренажер для проведения лабораториных работ позволит избежать
|
||||
поломки оборудования, а также экономить на расходных средствах"
|
||||
type="labs"
|
||||
/>
|
||||
<p className="lg:text-2xl sm:text-xl font-medium">
|
||||
Оснащение учебных классов и центров всем необходимым для
|
||||
современного обучения под «ключ»
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
src="src/assets/products/teaching/teaching.png"
|
||||
className="max-sm:hidden w-[calc(685/1600*100vw)] sm:self-start self-stretch"
|
||||
alt=""
|
||||
/>
|
||||
<img
|
||||
src="src/assets/products/teaching/teaching_mobile.png"
|
||||
className="sm:hidden"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
function SimulatorsItem({ text }: { text: string }) {
|
||||
return (
|
||||
<div className="lg:text-2xl sm:text-xl bg-[#3D425C4D] rounded-[44px] w-fit sm:px-5 sm:py-2 px-4 py-[6px]">
|
||||
@@ -6,49 +8,66 @@ function SimulatorsItem({ text }: { text: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function Simulators() {
|
||||
return (
|
||||
<div
|
||||
id="simulators"
|
||||
className="lg:ml-[65px] snap-center lg:aspect-[1535/923] sm:aspect-[768/672] aspect-[360/856] sm:sticky z-30 lg:top-[calc(138/785*100%)] sm:top-[calc(88/672*100%)] bg-[#14161F] lg:p-10 sm:p-6 p-4 max-lg:pr-10 lg:space-y-12 sm:space-y-10 space-y-6 lg:border-l border-t border-[#3D425C]"
|
||||
>
|
||||
<h2 className={'h2 font-medium flex justify-between gap-x-2'}>
|
||||
Симуляторы управления техникой
|
||||
<p className="text-[#3D425C] h3 font-medium">02</p>
|
||||
</h2>
|
||||
<div className="flex flex-wrap gap-2 lg:max-w-[1000px]">
|
||||
<SimulatorsItem text="авиационные симуляторы" />
|
||||
<SimulatorsItem text="погрузчики – ричстракеры" />
|
||||
<SimulatorsItem text="тяговые составы железной дороги" />
|
||||
<SimulatorsItem text="грузовые краны" />
|
||||
<SimulatorsItem text="вертолетная техника" />
|
||||
<SimulatorsItem text="горные самосвалы и экскаваторы" />
|
||||
</div>
|
||||
<div className="sm:flex max-sm:space-y-6 gap-x-2 lg:max-w-[calc(1417/1600*100vw)]">
|
||||
<div className="space-y-[10px] lg:w-[calc(498.5/1600*100vw)] sm:w-[calc(331/768*100vw)]">
|
||||
<img
|
||||
src="src/assets/products/simulators/rzhd2.jpg"
|
||||
className="object-cover sm:max-lg:aspect-[331/292] max-sm:aspect-[328/172] rounded-lg"
|
||||
alt=""
|
||||
/>
|
||||
<p className="l-text opacity-60">
|
||||
В основу симуляторов заложена математическая модель, полностью
|
||||
соответствующая работе настоящего оборудования
|
||||
</p>
|
||||
export const Simulators = forwardRef<HTMLDivElement, { sticked: boolean }>(
|
||||
({ sticked }, ref) => {
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className="lg:ml-[65px] lg:min-h-[calc(100svh-138px)] lg:min-w-[calc(100vw-65px)] sm:min-h-[calc(100svh-88px)] min-w-[100vw] min-h-[calc(100svh)] sm:sticky z-30 lg:top-[138px] sm:top-[88px] top-0 bg-[#14161F] lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 lg:space-y-12 sm:space-y-10 space-y-6 lg:border-l border-t border-[#3D425C]"
|
||||
>
|
||||
<h2
|
||||
className={
|
||||
'h2 font-medium flex justify-between gap-x-2' +
|
||||
(sticked ? ' text-[#3D425C] transition-colors' : '')
|
||||
}
|
||||
>
|
||||
Симуляторы управления техникой
|
||||
<p className="text-[#3D425C] h3 font-medium">02</p>
|
||||
</h2>
|
||||
<div
|
||||
className={
|
||||
'flex flex-wrap gap-2 lg:max-w-[1000px]' +
|
||||
(sticked ? ' transition-opacity opacity-0' : ' opacity-100')
|
||||
}
|
||||
>
|
||||
<SimulatorsItem text="авиационные симуляторы" />
|
||||
<SimulatorsItem text="погрузчики – ричстракеры" />
|
||||
<SimulatorsItem text="тяговые составы железной дороги" />
|
||||
<SimulatorsItem text="грузовые краны" />
|
||||
<SimulatorsItem text="вертолетная техника" />
|
||||
<SimulatorsItem text="горные самосвалы и экскаваторы" />
|
||||
</div>
|
||||
<div className="space-y-[10px] lg:w-[calc(498.5/1600*100vw)] sm:w-[calc(331/768*100vw)]">
|
||||
<img
|
||||
src="src/assets/products/simulators/rzhd.jpg"
|
||||
className="object-cover sm:max-lg:aspect-[331/292] max-sm:aspect-[328/172] rounded-lg"
|
||||
alt=""
|
||||
/>
|
||||
<p className="l-text opacity-60">
|
||||
Модель позволяет производить расчеты характеристик работы,
|
||||
отслеживать безопасность работы устройств и симулировать внештатные
|
||||
ситуации.
|
||||
</p>
|
||||
<div
|
||||
className={
|
||||
'sm:flex max-sm:space-y-6 gap-x-2 lg:max-w-[calc(1417/1600*100vw)]' +
|
||||
(sticked ? ' transition-opacity opacity-0' : ' opacity-100')
|
||||
}
|
||||
>
|
||||
<div className="space-y-[10px] lg:w-[calc(498.5/1600*100vw)] sm:w-[calc(331/768*100vw)]">
|
||||
<img
|
||||
src="src/assets/products/simulators/rzhd2.jpg"
|
||||
className="object-cover sm:max-lg:aspect-[331/292] max-sm:aspect-[328/172] rounded-lg"
|
||||
alt=""
|
||||
/>
|
||||
<p className="l-text opacity-60">
|
||||
В основу симуляторов заложена математическая модель, полностью
|
||||
соответствующая работе настоящего оборудования
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-[10px] lg:w-[calc(498.5/1600*100vw)] sm:w-[calc(331/768*100vw)]">
|
||||
<img
|
||||
src="src/assets/products/simulators/rzhd.jpg"
|
||||
className="object-cover sm:max-lg:aspect-[331/292] max-sm:aspect-[328/172] rounded-lg"
|
||||
alt=""
|
||||
/>
|
||||
<p className="l-text opacity-60">
|
||||
Модель позволяет производить расчеты характеристик работы,
|
||||
отслеживать безопасность работы устройств и симулировать
|
||||
внештатные ситуации.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useRef } from 'react';
|
||||
import { forwardRef, useRef } from 'react';
|
||||
import { getIcon } from '../../../../utils/getIcon';
|
||||
import { useHover } from 'usehooks-ts';
|
||||
import { useInView } from 'framer-motion';
|
||||
@@ -35,20 +35,31 @@ function TeachingItem({
|
||||
);
|
||||
}
|
||||
|
||||
export function IndustrialTrainings() {
|
||||
export const IndustrialTrainings = forwardRef<
|
||||
HTMLDivElement,
|
||||
{ sticked: boolean }
|
||||
>(({ sticked }, ref) => {
|
||||
return (
|
||||
<div
|
||||
id="industral"
|
||||
className="sm:sticky top-0 snap-center lg:aspect-[1600/923] sm:aspect-[768/672] aspect-[360/856] overflow-hidden lg:p-10 sm:p-6 p-4 border-t border-[#3D425C] max-sm:flex flex-col items-center gap-y-4"
|
||||
ref={ref}
|
||||
className="sm:sticky top-0 min-h-[100svh] min-w-[100vw] overflow-hidden lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 border-t border-[#3D425C] bg-[#14161F] max-sm:flex flex-col items-center gap-y-4"
|
||||
>
|
||||
<div className="lg:space-y-14 sm:space-y-10 space-y-6">
|
||||
<h2
|
||||
className={'h2 font-medium w-full flex justify-between items-center'}
|
||||
className={
|
||||
'h2 font-medium w-full flex justify-between items-center' +
|
||||
(sticked ? ' text-[#3D425C] transition-colors' : '')
|
||||
}
|
||||
>
|
||||
Промышленные тренажеры
|
||||
<p className="h3 font-medium text-[#3D425C]">01</p>
|
||||
</h2>
|
||||
<div className="sm:space-y-7 space-y-4 xl:max-w-[max(450px,calc(507/1600*100vw))] lg:max-w-[440px] sm:max-w-[calc(379/768*100vw)]">
|
||||
<div
|
||||
className={
|
||||
'sm:space-y-7 space-y-4 xl:max-w-[max(450px,calc(507/1600*100vw))] lg:max-w-[440px] sm:max-w-[calc(379/768*100vw)]' +
|
||||
(sticked ? ' transition-opacity opacity-0' : ' opacity-100')
|
||||
}
|
||||
>
|
||||
<TeachingItem
|
||||
iconType="danger"
|
||||
text="Отработка проведения технологических операций: оказание первой помощи, работы на высоте, работа с доменной печью и т.п."
|
||||
@@ -68,12 +79,18 @@ export function IndustrialTrainings() {
|
||||
</div>
|
||||
<img
|
||||
src="src/assets/products/trainings/trainings_desktop.png"
|
||||
className="absolute right-0 top-[calc(121px)] object-cover lg:w-[calc(1000/1600*100vw)] xl:w-[calc(1152/1600*100vw)] max-lg:hidden"
|
||||
className={
|
||||
'absolute right-0 top-[calc(121px)] object-cover lg:w-[calc(1000/1600*100vw)] xl:w-[calc(1152/1600*100vw)] max-lg:hidden' +
|
||||
(sticked ? ' transition-opacity opacity-0' : ' opacity-100')
|
||||
}
|
||||
alt=""
|
||||
/>
|
||||
<img
|
||||
src="src/assets/products/trainings/trainings_tablet.png"
|
||||
className="absolute right-0 top-[120px] object-cover w-[calc(438/768*100vw)] hidden sm:max-lg:block"
|
||||
className={
|
||||
'absolute right-0 top-[120px] object-cover w-[calc(438/768*100vw)] hidden sm:max-lg:block' +
|
||||
(sticked ? ' transition-opacity opacity-0' : ' opacity-100')
|
||||
}
|
||||
alt=""
|
||||
/>
|
||||
<img
|
||||
@@ -83,4 +100,4 @@ export function IndustrialTrainings() {
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PlayIcon } from '../icons/PlayIcon';
|
||||
import { CloseIcon } from '../icons/CloseIcon';
|
||||
import { Fullscreen } from '../icons/Fullscreen';
|
||||
|
||||
export function Video() {
|
||||
const [open, setOpen] = useState(false);
|
||||
@@ -15,17 +15,13 @@ export function Video() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex bg-[url(src/assets/video/video.jpg)] lg:h-[836px] sm:h-[561px] h-[400px] bg-cover bg-right bg-no-repeat justify-center relative z-20 lg:-mx-10 sm:-mx-6 -mx-4">
|
||||
<div className="flex bg-[url(src/assets/video/video.jpg)] bg-cover bg-right bg-no-repeat justify-center relative z-20 lg:aspect-[1552/616] sm:aspect-[720/512] aspect-[328/204]">
|
||||
<button
|
||||
className="self-center outline-none"
|
||||
className="self-center outline-none p-[22px] rounded-full border bg-[#14161F33]"
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<PlayIcon className="lg:w-[114px] sm:w-[94px] outline-none" />
|
||||
<Fullscreen />
|
||||
</button>
|
||||
<div className="flex self-end absolute right-0 max-sm:hidden -z-30">
|
||||
<div className="w-0 h-0 lg:border-b-[100px] lg:border-l-[100px] sm:border-b-[82px] sm:border-l-[82px] border-[transparent_transparent_#14161F_transparent]" />
|
||||
<div className="lg:w-[260px] sm:w-[216px] mobile bg-[#14161F]" />
|
||||
</div>
|
||||
</div>
|
||||
{open && (
|
||||
<div className="fixed top-0 left-0 z-50 w-full h-full flex justify-center items-center overflow-hidden">
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export function Fullscreen() {
|
||||
return (
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
viewBox="0 0 28 28"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6.31626 23.3335L11.3246 18.3251L9.67472 16.6752L4.66634 21.6836V16.6752L2.33301 19.0085V25.6668H8.9913L11.3246 23.3335H6.31626Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M23.333 6.31675V11.3251L25.6663 8.99179V2.3335L19.008 2.3335L16.6747 4.66683H21.6831L16.6747 9.6752L18.3246 11.3251L23.333 6.31675Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -15,7 +15,7 @@ export function MainPage() {
|
||||
const width = useWindowWidth();
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
<div>
|
||||
{width >= 1024 && <Ellipse />}
|
||||
<Motivation />
|
||||
<Video />
|
||||
|
||||
@@ -100,7 +100,7 @@ export function SliderWithScaling<T extends { title: string }>({
|
||||
|
||||
return (
|
||||
<div className={'flex flex-col relative ' + className}>
|
||||
<div className="overflow-hidden -mx-6 h-full">
|
||||
<div className="overflow-hidden lg:-mx-10 sm:-mx-6 -mx-4 h-full">
|
||||
<div {...handlers} className="h-full">
|
||||
<div
|
||||
className={`flex items-${alignItems} gap-x-4 -mr-6 select-none`}
|
||||
|
||||
Reference in New Issue
Block a user