upd products
This commit is contained in:
@@ -1,8 +1,20 @@
|
||||
import { useRef } from 'react';
|
||||
import { getIcon } from '../../../../utils/getIcon';
|
||||
import { useInView } from 'framer-motion';
|
||||
import { motion, useInView } from 'framer-motion';
|
||||
|
||||
export function ForTeachingTab() {
|
||||
const titleRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const titleInView = useInView(titleRef, { once: true, amount: 'all' });
|
||||
|
||||
const textRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const textInView = useInView(textRef, { once: true, amount: 'all' });
|
||||
|
||||
const imgRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const imgInView = useInView(imgRef, { once: true, amount: 'all' });
|
||||
|
||||
return (
|
||||
<div
|
||||
itemProp="forEducation"
|
||||
@@ -10,12 +22,18 @@ export function ForTeachingTab() {
|
||||
itemType="https://schema.org/TrainingsForEducation"
|
||||
className="overflow-hidden lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 bg-[#14161F] border-y border-[#3D425C]"
|
||||
>
|
||||
<div className="flex justify-between">
|
||||
<motion.div
|
||||
ref={titleRef}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={titleInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 0.5 }}
|
||||
className="flex justify-between"
|
||||
>
|
||||
<h2 className="font-medium h2">
|
||||
Интерактивные тренажеры для учебных заведений
|
||||
</h2>
|
||||
<p className="h3 font-medium text-[#3D425C]">03</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
<div className="flex justify-between max-sm:flex-col">
|
||||
<div className="sm:max-w-[calc(500/768*100vw)] mt-6">
|
||||
<div itemProp="creating" className="space-y-4 lg:max-w-[40vw] flex-1">
|
||||
@@ -30,22 +48,35 @@ export function ForTeachingTab() {
|
||||
поломки оборудования, а также экономить на расходных средствах"
|
||||
type="labs"
|
||||
/>
|
||||
<p className="font-medium lg:text-2xl sm:text-xl">
|
||||
<motion.p
|
||||
ref={textRef}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={textInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 1.5 }}
|
||||
className="font-medium lg:text-2xl sm:text-xl"
|
||||
>
|
||||
Оснащение учебных классов и центров всем необходимым для
|
||||
современного обучения под «ключ»
|
||||
</p>
|
||||
</motion.p>
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
src="/images/products/teaching/teaching.png"
|
||||
className="max-sm:hidden w-[calc(685/1600*100vw)] sm:self-start lg:-mr-10 sm:-mr-6 -mr-4"
|
||||
alt="обучение"
|
||||
/>
|
||||
<img
|
||||
src="/images/products/teaching/teaching_mobile.png"
|
||||
className="mt-5 -mx-6 sm:hidden"
|
||||
alt="обучение"
|
||||
/>
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={imgInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 2 }}
|
||||
ref={imgRef}
|
||||
>
|
||||
<img
|
||||
src="/images/products/teaching/teaching.png"
|
||||
className="max-sm:hidden w-[calc(685/1600*100vw)] sm:self-start lg:-mr-10 sm:-mr-6 -mr-4"
|
||||
alt="обучение"
|
||||
/>
|
||||
<img
|
||||
src="/images/products/teaching/teaching_mobile.png"
|
||||
className="mt-5 -mx-6 sm:hidden"
|
||||
alt="обучение"
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -61,23 +92,24 @@ function ForTeachingOption({
|
||||
type: 'labs' | 'teaching';
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const isInView = useInView(ref, {
|
||||
margin: `0px 0px ${(ref.current?.clientHeight ?? 0) - window.innerHeight}px`,
|
||||
});
|
||||
const inView = useInView(ref, { once: true, amount: 'all' });
|
||||
|
||||
return (
|
||||
<div
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={inView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 1 }}
|
||||
ref={ref}
|
||||
className="flex sm:gap-x-7 items-start sm:max-lg:pr-3 max-sm:pb-4 max-sm:border-b border-[#3D425C]"
|
||||
>
|
||||
{getIcon(type, true, 'max-sm:hidden min-w-11')}
|
||||
<div className="lg:pl-4 sm:pl-[13px] sm:border-l border-[#3D425C] w-[90%]">
|
||||
<div className="flex items-center mb-1 sm:items-start sm:max-lg:flex-col max-sm:gap-x-2">
|
||||
{getIcon(type, isInView, 'sm:hidden min-w-11')}
|
||||
{getIcon(type, inView, 'sm:hidden min-w-11')}
|
||||
<h4 className="font-medium lg:text-2xl sm:text-xl">{title}</h4>
|
||||
</div>
|
||||
<p className="opacity-60 l-text">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,31 @@
|
||||
import { useRef } from 'react';
|
||||
import { getIcon } from '../../../../utils/getIcon';
|
||||
import { useInView } from 'framer-motion';
|
||||
import { motion, useInView } from 'framer-motion';
|
||||
|
||||
function TeachingItem({
|
||||
title,
|
||||
text,
|
||||
iconType,
|
||||
index,
|
||||
}: {
|
||||
title: string;
|
||||
text: string;
|
||||
iconType: 'danger' | 'service' | 'safety';
|
||||
index: number;
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
const isInView = useInView(ref, {
|
||||
margin: `0px 0px -${window.innerHeight - (ref.current?.clientHeight ?? 0)}px`,
|
||||
const rootInView = useInView(ref, {
|
||||
once: true,
|
||||
amount: 'all',
|
||||
// margin: `0px 0px -${window.innerHeight - (ref.current?.clientHeight ?? 0)}px`,
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={rootInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 0.5 + index / 4 }}
|
||||
itemProp={iconType}
|
||||
ref={ref}
|
||||
className="sm:border-l-0 max-sm:border-l-0 max-sm:first:border-t-0 max-sm:border-t border-[#3D425C] sm:flex lg:items-start sm:gap-x-7 max-sm:mr-4 max-sm:first:pt-0 max-sm:pt-4"
|
||||
@@ -26,16 +33,24 @@ function TeachingItem({
|
||||
{getIcon(iconType, true, 'max-sm:hidden sm:max-lg:mb-[14px] min-w-11')}
|
||||
<div className="sm:border-l border-[#3D425C] sm:pl-4">
|
||||
<div className="flex items-center mb-2 max-sm:gap-x-2">
|
||||
{getIcon(iconType, isInView, 'sm:hidden min-w-11')}
|
||||
{getIcon(iconType, rootInView, 'sm:hidden min-w-11')}
|
||||
<h4 className="font-medium lg:text-2xl sm:text-xl">{title}</h4>
|
||||
</div>
|
||||
<p className="l-text opacity-60">{text}</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export function IndustrialTab() {
|
||||
const titleRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const titleInView = useInView(titleRef, { once: true, amount: 'all' });
|
||||
|
||||
const imgRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const imgInView = useInView(imgRef, { once: true });
|
||||
|
||||
return (
|
||||
<div
|
||||
itemProp="industrial"
|
||||
@@ -43,10 +58,16 @@ export function IndustrialTab() {
|
||||
itemType="https://schema.org/IndustrialTrainings"
|
||||
className="lg:px-10 lg:py-10 sm:px-6 sm:py-6 px-4 py-4 border-t border-[#3D425C] bg-[#14161F] overflow-hidden space-y-6 lg:space-y-14 sm:space-y-10"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: titleInView ? 1 : 0 }}
|
||||
transition={{ duration: 1.5, delay: 0.5 }}
|
||||
ref={titleRef}
|
||||
className="flex items-center justify-between"
|
||||
>
|
||||
<h2 className="w-full font-medium h2">Промышленные тренажеры</h2>
|
||||
<p className="h3 font-medium text-[#3D425C]">01</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
<div className="flex justify-between max-sm:items-center max-sm:flex-col">
|
||||
<div
|
||||
itemProp="education"
|
||||
@@ -58,19 +79,28 @@ export function IndustrialTab() {
|
||||
iconType="danger"
|
||||
text="отработка проведения технологических операций: оказание первой помощи, работы на высоте, работа с доменной печью и т.п."
|
||||
title="обучение навыкам работы на опасных производствах"
|
||||
index={0}
|
||||
/>
|
||||
<TeachingItem
|
||||
iconType="service"
|
||||
text="отработка определения неисправностей оборудования и выполнения ремонтных работ на цифровом двойнике"
|
||||
title="обучение обслуживанию и ремонту оборудования, систем, техники"
|
||||
index={1}
|
||||
/>
|
||||
<TeachingItem
|
||||
iconType="safety"
|
||||
text="отработка плана мероприятий по локализации и ликвидации последствий аварий. "
|
||||
title="обучение правилам промышленной безопасности и охраны труда"
|
||||
index={2}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative bottom-0 lg:left-10 sm:left-6 left-4 lg:top-10 sm:top-6 top-4">
|
||||
<motion.div
|
||||
ref={imgRef}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={imgInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 1.5 }}
|
||||
className="relative bottom-0 lg:left-10 sm:left-6 left-4 lg:top-10 sm:top-6 top-4"
|
||||
>
|
||||
<img
|
||||
src="/images/products/trainings/trainings_desktop.png"
|
||||
className="object-cover lg:w-[calc(1000/1600*100vw)] xl:max-w-[calc(1152/1600*100vw)] max-lg:hidden"
|
||||
@@ -86,7 +116,7 @@ export function IndustrialTab() {
|
||||
className="object-center aobject-cover sm:hidden"
|
||||
alt="тренажеры"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
function SimulatorsItem({ text }: { text: string }) {
|
||||
import { motion, useInView } from 'framer-motion';
|
||||
import { useRef } from 'react';
|
||||
|
||||
function SimulatorsItem({ text, index }: { text: string; index: number }) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
const isInView = useInView(ref, { once: true, amount: 'all' });
|
||||
|
||||
return (
|
||||
<div className="l-text bg-[#3D425C4D] rounded-[44px] w-fit sm:px-5 sm:py-2 px-4 py-1.5">
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={isInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 0.8 + index / 4 }}
|
||||
ref={ref}
|
||||
className="l-text bg-[#3D425C4D] rounded-[44px] w-fit sm:px-5 sm:py-2 px-4 py-1.5"
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export function SimulatorsTab() {
|
||||
const titleRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const titleInView = useInView(titleRef, { once: true, amount: 'all' });
|
||||
|
||||
const imgRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const imgInView = useInView(imgRef, { once: true, amount: 'all' });
|
||||
|
||||
return (
|
||||
<div
|
||||
itemScope
|
||||
@@ -14,30 +35,42 @@ export function SimulatorsTab() {
|
||||
itemType="http://schema.org/Simulators"
|
||||
className="bg-[#14161F] lg:px-10 lg:py-10 sm:px-6 sm:py-6 px-4 py-4 sm:space-y-10 space-y-6 border-t border-[#3D425C]"
|
||||
>
|
||||
<div className="flex justify-between gap-x-2">
|
||||
<motion.div
|
||||
ref={titleRef}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={titleInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 0.5 }}
|
||||
className="flex justify-between gap-x-2"
|
||||
>
|
||||
<h2 className="font-medium h2">Симуляторы управления техникой</h2>
|
||||
<p className="text-[#3D425C] h3 font-medium">02</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
<div
|
||||
itemProp="simulatorsTypes"
|
||||
itemScope
|
||||
itemType="http://schema.org/SimulatorsTypes"
|
||||
className="flex flex-wrap gap-2 lg:max-w-[1000px]"
|
||||
>
|
||||
<SimulatorsItem text="авиационные симуляторы" />
|
||||
<SimulatorsItem text="погрузчики – ричстракеры" />
|
||||
<SimulatorsItem text="тяговые составы железной дороги" />
|
||||
<SimulatorsItem text="грузовые краны" />
|
||||
<SimulatorsItem text="вертолетная техника" />
|
||||
<SimulatorsItem text="горные самосвалы и экскаваторы" />
|
||||
<SimulatorsItem text="авиационные симуляторы" index={0} />
|
||||
<SimulatorsItem text="погрузчики – ричстракеры" index={1} />
|
||||
<SimulatorsItem text="тяговые составы железной дороги" index={2} />
|
||||
<SimulatorsItem text="грузовые краны" index={3} />
|
||||
<SimulatorsItem text="вертолетная техника" index={4} />
|
||||
<SimulatorsItem text="горные самосвалы и экскаваторы" index={5} />
|
||||
</div>
|
||||
<div
|
||||
itemProp="simulatorsModel"
|
||||
itemScope
|
||||
itemType="http://schema.org/SimulatorsModel"
|
||||
className="sm:flex max-sm:space-y-6 gap-x-2"
|
||||
ref={imgRef}
|
||||
>
|
||||
<div className="space-y-[10px] lg:w-[calc(400/1600*100vw)] sm:w-[calc(331/768*100vw)]">
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={imgInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 2.5 }}
|
||||
className="space-y-[10px] lg:w-[calc(400/1600*100vw)] sm:w-[calc(331/768*100vw)]"
|
||||
>
|
||||
<img
|
||||
src="/images/products/simulators/rzhd2.jpg"
|
||||
className="object-cover sm:max-lg:aspect-[331/292] max-sm:aspect-[328/172]"
|
||||
@@ -47,8 +80,13 @@ export function SimulatorsTab() {
|
||||
В основу симуляторов заложена математическая модель, полностью
|
||||
соответствующая работе настоящего оборудования
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-[10px] lg:w-[calc(400/1600*100vw)] sm:w-[calc(331/768*100vw)]">
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={imgInView ? { opacity: 1 } : {}}
|
||||
transition={{ duration: 1.5, delay: 3 }}
|
||||
className="space-y-[10px] lg:w-[calc(400/1600*100vw)] sm:w-[calc(331/768*100vw)]"
|
||||
>
|
||||
<img
|
||||
src="/images/products/simulators/rzhd.jpg"
|
||||
className="object-cover sm:max-lg:aspect-[331/292] max-sm:aspect-[328/172] object-[bottom_-1px_left_-1px]"
|
||||
@@ -59,7 +97,7 @@ export function SimulatorsTab() {
|
||||
отслеживать безопасность работы устройств и симулировать внештатные
|
||||
ситуации.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -90,7 +90,7 @@ function TeachingFeaturesForDesktop() {
|
||||
/>
|
||||
<img
|
||||
src="/images/teaching/pinned_windows.jpg"
|
||||
className="rounded-tl-lg absolute max-w-[calc(281/752*100%)] right-0 bottom-0 z-10"
|
||||
className="rounded-tl-xl absolute max-w-[calc(281/752*100%)] right-0 bottom-0 z-10 object-[top_-1px_left_0px]"
|
||||
alt="Видеозапись обучения"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user