todo: scrolls and top of products

This commit is contained in:
2024-08-28 19:35:21 +05:00
parent c80bb781e0
commit 2ce7c00ead
7 changed files with 45 additions and 267 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ export function Layout() {
return (
<>
<Header />
<main className="relative lg:px-10 sm:px-6 px-4">
<main className="relative overflow-x-clip lg:px-10 sm:px-6 px-4">
<Outlet />
<Feedback />
</main>
+1 -1
View File
@@ -6,7 +6,7 @@ export function Products() {
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"
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]"
>
<IndustrialTrainings />
<Simulators />
@@ -3,41 +3,6 @@ import { useHover } from 'usehooks-ts';
import { getIcon } from '../../../../utils/getIcon';
import { useInView } from 'framer-motion';
export function ForTeachingTab() {
return (
<div className="lg:bg-[url('src/assets/products/teaching/teaching.png')] lg:aspect-[1520/546] sm:aspect-[720/460] w-full lg:h-[max(534px,34vw)] md:h-[min(460px,60vw)] sm:h-[max(460px,60vw)] bg-[#3D425C4D] bg-no-repeat lg:p-10 sm:p-7 p-5 rounded-xl 2xl:bg-contain bg-right lg:bg-[length:50%]">
<div className='sm:max-lg:bg-[url("src/assets/products/teaching/teaching.png")] bg-no-repeat bg-right bg-[length:50%] sm:max-lg:pb-[55px] max-lg:border-b border-[#3D425C] sm:mb-8 mb-4'>
<h3 className=" font-medium lg:max-w-[455px] sm:max-w-[326px] max-sm:mb-0 h3">
Интерактивные тренажеры для учебных заведений
</h3>
<img
src="src/assets/products/teaching/teaching.png"
className="sm:hidden"
alt="Интерактивные тренажеры для учебных заведений"
/>
</div>
<div className="flex lg:flex-col max-sm:flex-col lg:gap-y-6 gap-y-4 lg:mb-12 sm:mb-8 mb-4 sm:max-lg:border-b border-[#3D425C] sm:max-lg:pb-8">
<ForTeachingOption
title="cоздание обучающих VR систем"
description="Проведение виртуальных практических работ, создание учебных
мастерских и стендов"
type="teaching"
/>
<ForTeachingOption
title="cоздание VR лабораторий"
description="Тренажер для проведения лабораториных работ позволит избежать
поломки оборудования, а также экономить на расходных средствах"
type="labs"
/>
</div>
<h4 className="font-medium lg:max-w-[408px] l-text">
Оснащение учебных классов и центров всем необходимым для современного
обучения под «ключ»
</h4>
</div>
);
}
function ForTeachingOption({
title,
description,
@@ -72,17 +37,19 @@ function ForTeachingOption({
export function ForTeaching() {
return (
<div className="lg:ml-[129px] sticky z-50 top-[376px] lg:p-10 lg:pb-[98px] sm:p-6 p-4 [background:right_bottom/50%_url(src/assets/products/teaching/teaching.png)_no-repeat,#14161F] bg-right-bottom bg-[length:calc((880-195)/1600*100vw)] bg-no-repeat lg:border-l border-t border-[#3D425C]">
<div className="lg:space-y-14 sm:space-y-10 space-y-6">
<h2 className="h2 font-medium flex justify-between">
Интерактивные тренажеры для учебных заведений
<p className="h3 font-medium text-[#3D425C]">03</p>
</h2>
<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]"
>
<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="Проведение виртуальных практических работ, создание учебных
мастерских и стендов"
description="Проведение виртуальных практических работ, создание учебных мастерских и стендов"
type="teaching"
/>
<ForTeachingOption
@@ -1,172 +1,3 @@
// export function SimulatorsTab() {
// const width = useWindowWidth();
// const imgWidth = Math.min(width, 500);
// const [slide, setSlide] = useState(0);
// const [sliderOffset, setSliderOffset] = useState(-imgWidth + 72);
// const [isAnimating, setIsAnimating] = useState(false);
// const ref = useRef<HTMLDivElement>(null);
// const [order, dispatch] = useReducer(
// (state: string[], action: string) => {
// switch (action) {
// case 'prev':
// setSliderOffset(prev => prev + imgWidth - 72);
// return [...state.slice(1), state[state.length - 3]];
// case 'next':
// setSliderOffset(prev => prev - imgWidth + 72);
// return [state[state.length - 2], ...state.slice(0, -1)];
// default:
// return state;
// }
// },
// [
// 'src/assets/products/simulators/dispatcher.jpg',
// 'src/assets/products/simulators/winda.jpg',
// 'src/assets/products/simulators/train.jpg',
// 'src/assets/products/simulators/dispatcher.jpg',
// 'src/assets/products/simulators/winda.jpg',
// 'src/assets/products/simulators/train.jpg',
// 'src/assets/products/simulators/dispatcher.jpg',
// ],
// );
// useEffect(() => {
// setSliderOffset(-imgWidth + 72);
// }, [order, slide, imgWidth]);
// const handlers = useSwipeable({
// onSwipedLeft: () => {
// if (!isAnimating) {
// setIsAnimating(true);
// setSlide(prev => (prev === order.length - 5 ? 0 : prev + 1));
// dispatch('prev');
// }
// },
// onSwipedRight: () => {
// if (!isAnimating) {
// setIsAnimating(true);
// setSlide(prev => (prev === 0 ? order.length - 5 : prev - 1));
// dispatch('next');
// }
// },
// trackMouse: true,
// preventScrollOnSwipe: true,
// touchEventOptions: { passive: true },
// });
// useEffect(() => {
// const refValue = ref.current;
// refValue?.addEventListener('transitionend', () => setIsAnimating(false));
// return () =>
// refValue?.removeEventListener('transitionend', () =>
// setIsAnimating(false),
// );
// }, [order, sliderOffset, slide]);
// return (
// <div className="bg-[#3D425C4D] rounded-xl flex lg:aspect-[1520/546] sm:aspect-[720/460] w-full lg:h-[max(534px,34vw)] md:h-[min(460px,60vw)] sm:h-[max(460px,60vw)] lg:p-10 sm:p-7 p-5 select-none max-sm:overflow-hidden">
// <div className="flex sm:justify-between w-full h-full max-sm:flex-col items-center gap-x-2">
// <div className="lg:max-w-[539px] sm:max-w-[50vw] self-start flex flex-col sm:max-lg:justify-between sm:max-lg:h-full">
// <div className="flex flex-col">
// <h3 className="sm:max-lg:max-w-[455px] font-medium h3 lg:mb-8 sm:mb-6 mb-5">
// Интерактивные симуляторы управления техникой
// </h3>
// <div className="flex flex-wrap max-sm:grid lg:gap-2 gap-1 lg:mb-12 max-sm:mb-5 sm:max-lg:max-w-[325px]">
// <SimulatorsItem text="авиационные симуляторы" />
// <SimulatorsItem text="погрузчики – ричстракеры" />
// <SimulatorsItem text="тяговые составы железной дороги" />
// <SimulatorsItem text="грузовые краны" />
// <SimulatorsItem text="вертолетная техника" />
// <SimulatorsItem text="горные самосвалы и экскаваторы" />
// </div>
// </div>
// <div className="sm:max-lg:max-w-[455px]">
// <h4 className="font-medium l-text lg:mb-2 max-sm:mb-3">
// В основу симуляторов заложена математическая модель, полностью
// соответствующая работе настоящего оборудования
// </h4>
// <p className="sm:max-lg:hidden mb-5 opacity-60 m-text">
// модель позволяет производить расчеты характеристик работы,
// отслеживать безопасность работы устройств и симулировать
// внештатные ситуации.
// </p>
// </div>
// </div>
// <div className="self-center sm:max-lg:max-w-[234px] flex flex-col justify-between h-full">
// <div {...handlers}>
// <div
// ref={ref}
// className="flex h-full lg:justify-end select-none max-sm:relative xl:max-w-[clamp(553px,553px+(100vw-1280px)/320*160,713px)] 2xl:max-w-[calc((100vw-256px)*0.53)] lg:max-w-[300px] sm:max-lg:flex-col sm:flex-wrap gap-2 sm:max-lg:smb-10"
// style={
// width < 640
// ? {
// transform: `translateX(${sliderOffset}px)`,
// transition: `${sliderOffset === 0 || sliderOffset === -(imgWidth - 72) * 2 ? 0 : 0.5}s`,
// }
// : {}
// }
// >
// {width < 640 ? (
// order.map((src, index) => (
// <div
// key={index}
// className="bg-no-repeat rounded-xl aspect-[280/176] pointer-events-none h-full bg-cover"
// style={{
// minWidth: imgWidth - 80,
// backgroundImage: `url(${src})`,
// }}
// >
// <img
// src={src}
// width={imgWidth - 80}
// className="invisible rounded-xl object-cover h-full"
// alt="Симулятор"
// />
// </div>
// ))
// ) : (
// <>
// <img
// src="src/assets/products/simulators/train.jpg"
// className="rounded-xl xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] object-cover aspect-[232/229] 2xl:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
// alt="Поезд"
// />
// <img
// src="src/assets/products/simulators/dispatcher.jpg"
// className="rounded-lg xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] object-cover aspect-[232/229] 2xl:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
// alt="Диспетчер"
// />
// <img
// src="src/assets/products/simulators/winda.jpg"
// className="rounded-xl xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] object-cover aspect-[232/229] 2xl:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
// alt="Диспетчер"
// />
// <img
// src="src/assets/products/simulators/rzhd.jpg"
// className="rounded-xl xl:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] object-cover aspect-[352/229] 2xl:w-[calc((100vw-256px)*0.22)]"
// alt="РЖД"
// />
// <img
// src="src/assets/products/simulators/rzhd2.jpg"
// className="rounded-xl xl:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] object-cover aspect-[352/229] 2xl:w-[calc((100vw-256px)*0.22)]"
// alt="РЖД"
// />
// </>
// )}
// </div>
// </div>
// <p className="lg:hidden max-sm:hidden opacity-60 m-text">
// модель позволяет производить расчеты характеристик работы,
// отслеживать безопасность работы устройств и симулировать внештатные
// ситуации.
// </p>
// </div>
// </div>
// </div>
// );
// }
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]">
@@ -177,8 +8,11 @@ function SimulatorsItem({ text }: { text: string }) {
export function Simulators() {
return (
<div className="lg:ml-[65px] sticky z-20 top-[138px] bg-[#14161F] lg:p-10 sm:p-6 py-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">
<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>
@@ -3,44 +3,6 @@ import { getIcon } from '../../../../utils/getIcon';
import { useHover } from 'usehooks-ts';
import { useInView } from 'framer-motion';
export function TrainingsTab() {
return (
<div className="bg-[#3D425C4D] rounded-xl lg:aspect-[1520/546] sm:aspect-[720/460] lg:h-[max(534px,34vw)] md:h-[min(460px,60vw)] sm:h-[max(460px,60vw)] w-full lg:bg-[url('src/assets/products/trainings/trainings.png')] 2xl:bg-[length:70%] lg:bg-right-bottom lg:bg-[length:55%] sm:bg-contain sm:max-lg:bg-[top_120px] lg:p-10 sm:p-7 p-5 bg-no-repeat">
<div className="lg:max-w-[max(455px,28vw)]">
<div className="sm:max-lg:border-b border-[#3D425C] sm:max-lg:bg-[url('src/assets/products/trainings/trainings.png')] bg-no-repeat md:bg-contain bg-right-bottom sm:bg-[length:40%]">
<div className="sm:max-lg:max-w-[51vw] max-sm:border-b border-[#3D425C]">
<h3 className=" font-medium lg:mb-8 sm:mb-28 h3">
Промышленные тренажеры виртуальной реальности
</h3>
<img
src="src/assets/products/trainings/trainings.png"
className="sm:hidden mt-4 object-cover w-full"
alt="Промышленные тренажеры виртуальной реальности"
/>
</div>
</div>
<div className="lg:flex flex lg:flex-col sm:grid grid-cols-3 lg:gap-y-6 sm:max-lg:mt-8 max-sm:mt-4 h-full max-sm:flex-col max-sm:gap-y-4 sm:max-lg:gap-x-3">
<TeachingItem
iconType="danger"
text="Отработка проведения технологических операций: оказание первой помощи, работы на высоте, работа с доменной печью и т.п."
title="обучение навыкам работы на опасных производствах"
/>
<TeachingItem
iconType="service"
text="отработка определения неисправностей оборудования и выполнения ремонтных работ на цифровом двойнике"
title="обучение обслуживанию и ремонту оборудования, систем, техники"
/>
<TeachingItem
iconType="safety"
text="отработка плана мероприятий по локализации и ликвидации последствий аварий. "
title="обучение правилам промышленной безопасности и охраны труда"
/>
</div>
</div>
</div>
);
}
function TeachingItem({
title,
text,
@@ -75,13 +37,18 @@ function TeachingItem({
export function IndustrialTrainings() {
return (
<div className="sticky top-0 h-screen lg:p-10 sm:p-6 p-4 border-t border-[#3D425C] max-sm:flex flex-col items-center gap-y-4 overflow-hidden lg:bg-[url(src/assets/products/trainings/trainings_desktop.png)] sm:bg-[url(src/assets/products/trainings/trainings_tablet.png)] xl:bg-[length:60%] lg:bg-[length:60%] md:max-lg:bg-[length:45%] sm:max-md:bg-[length:50%] bg-right-bottom bg-no-repeat">
<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"
>
<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">
<h2
className={'h2 font-medium w-full flex justify-between items-center'}
>
Промышленные тренажеры
<p className="h3 font-medium text-[#3D425C]">01</p>
</h2>
<div className="sm:space-y-7 space-y-4 xl:max-w-[507px] lg:max-w-[50%] sm:max-w-[50vw]">
<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)]">
<TeachingItem
iconType="danger"
text="Отработка проведения технологических операций: оказание первой помощи, работы на высоте, работа с доменной печью и т.п."
@@ -99,9 +66,19 @@ export function IndustrialTrainings() {
/>
</div>
</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"
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"
alt=""
/>
<img
src="src/assets/products/trainings/trainings_mobile.png"
className="sm:hidden object-cover self-center"
className="sm:hidden object-cover object-center"
alt=""
/>
</div>
+1 -1
View File
@@ -15,7 +15,7 @@ export function MainPage() {
const width = useWindowWidth();
return (
<div className="overflow-x-clip">
<div className="">
{width >= 1024 && <Ellipse />}
<Motivation />
<Video />
+8 -8
View File
@@ -73,17 +73,17 @@ export function SliderWithScaling<T extends { title: string }>({
}, []);
function nextSlide() {
if (!transiting) {
setCurrentSliding('next');
dispatch('next');
}
// if (!transiting) {
// }
setCurrentSliding('next');
dispatch('next');
}
function prevSlide() {
if (!transiting) {
setCurrentSliding('prev');
dispatch('prev');
}
// if (!transiting) {
// }
setCurrentSliding('prev');
dispatch('prev');
}
useEffect(() => {