fixed slider, teaching, trainings etc
This commit is contained in:
@@ -12,7 +12,7 @@ export function Availables() {
|
||||
<span className="text-gradient text-wrap">Многопользовательский </span>
|
||||
режим обучения
|
||||
</Title>
|
||||
<div className="grid grid-cols-3 lg:-mx-10 sm:-mx-6 -mx-4 max-sm:flex-col justify-stretch max-sm:gap-y-2 sm:pb-5 pb-2 max-sm:pt-2 lg:col-start-1 col-span-full">
|
||||
<div className="grid sm:grid-cols-3 lg:-mx-10 sm:-mx-6 -mx-4 sm:pb-5 pb-2 max-sm:pt-2 lg:col-start-1 col-span-full">
|
||||
<MultiUserFeature
|
||||
type="processes"
|
||||
text="отработка производственных процессов, в которых участвует группа людей"
|
||||
@@ -27,7 +27,7 @@ export function Availables() {
|
||||
/>
|
||||
</div>
|
||||
<AppearanceText
|
||||
className="col-start-1 lg:col-span-6 col-span-7"
|
||||
className="col-start-1 lg:col-span-6 col-span-7 max-lg:mt-6"
|
||||
splits={[
|
||||
'В одном ',
|
||||
'цифровом ',
|
||||
@@ -61,7 +61,7 @@ function MultiUserFeature({
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className="bg-right-bottom bg-no-repeat flex flex-col bg-[url(src/assets/availables/highlight.png)] bg-[length:0%] hover:bg-[length:100%] transition-all duration-300 aspect-[532.67/280] w-full justify-between items-start px-10 py-6 border-y border-r last:border-r-0 border-[#3D425C] lg:min-h-[214px] sm:min-h-[240px] min-h-[220px]"
|
||||
className="bg-right-bottom bg-no-repeat flex flex-col bg-[url(src/assets/availables/highlight.png)] bg-[length:0%_0%] hover:bg-[length:100%_100%] transition-all duration-300 lg:aspect-[532.67/280] sm:aspect-[255.33/280] aspect-[3/2'] w-full justify-between items-start px-10 py-6 sm:border-y border-t max-sm:last:border-b sm:border-r last:border-r-0 border-[#3D425C] lg:min-h-[214px] sm:min-h-[240px] min-h-[220px]"
|
||||
>
|
||||
{getIcon(type, hovered, 'mb-4 max-sm:hidden w-14 h-14')}
|
||||
{getIcon(type, isInView, 'mb-4 sm:hidden w-14 h-14')}
|
||||
|
||||
@@ -10,6 +10,7 @@ export function Products() {
|
||||
const [curTab, setCurTab] = useState<0 | 1 | 2>(0);
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const container = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleClick = (
|
||||
e: React.MouseEvent<HTMLButtonElement>,
|
||||
@@ -25,6 +26,7 @@ export function Products() {
|
||||
return (
|
||||
<div
|
||||
id="products"
|
||||
ref={container}
|
||||
className="lg:py-[70px] sm:max-lg:pt-14 sm:max-lg:pb-8 max-sm:py-14 relative z-10"
|
||||
>
|
||||
<Title className="2xl:mb-[77px] mb-14 max-lg:hidden">
|
||||
|
||||
@@ -44,7 +44,7 @@ import { IProject, Media } from '../../type/Project';
|
||||
// }
|
||||
|
||||
export const Project = forwardRef<HTMLDivElement, IProject<Media>>(
|
||||
({ src, title, tags, media }, ref) => {
|
||||
({ src, title, tags, media, year }, ref) => {
|
||||
const [buffering, setBuffering] = useState(true);
|
||||
|
||||
return (
|
||||
@@ -72,7 +72,10 @@ export const Project = forwardRef<HTMLDivElement, IProject<Media>>(
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col justify-between gap-2 my-4">
|
||||
<h4 className="font-medium h4">{title}</h4>
|
||||
<div className="flex justify-between">
|
||||
<h4 className="font-medium h4">{title}</h4>
|
||||
<p className="h4 font-medium">{year}</p>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
{tags.map(tag => (
|
||||
<p key={tag} className="font-medium m-caption text-[#737AA1]">
|
||||
|
||||
@@ -2,10 +2,13 @@ import { SliderWithScaling } from '../../ui/SliderWithScaling';
|
||||
import { Title } from '../../ui/Title';
|
||||
import { projects } from '../../consts/projects';
|
||||
import { Project } from './Projects';
|
||||
import { useWindowWidth } from '../../hooks/useWindowWidth';
|
||||
|
||||
export function ProjectsSlider() {
|
||||
const width = useWindowWidth();
|
||||
|
||||
return (
|
||||
<div className="space-y-14 lg:pt-[100px] border-b border-[#3D425C]">
|
||||
<div className="lg:space-y-14 space-y-6 lg:pt-[100px] sm:py-[70px] py-14 border-b border-[#3D425C]">
|
||||
<Title>
|
||||
<span className="text-gradient">Большой опыт в работе</span> с
|
||||
промышленными предприятиями и учебными заведениями
|
||||
@@ -13,8 +16,14 @@ export function ProjectsSlider() {
|
||||
<SliderWithScaling
|
||||
slides={projects}
|
||||
SlideElement={Project}
|
||||
slideSizes={['31.69vw', '31.56vw', '48vw', '48vw']}
|
||||
className="pb-10"
|
||||
slideSizes={
|
||||
width >= 1024
|
||||
? ['31.69vw', '31.56vw', '48vw', '48vw']
|
||||
: width >= 640
|
||||
? ['66.01vw', '66vw', '93.75vw', '93.75vw']
|
||||
: ['91.11vw', '91.11vw', '91.11vw', '91.11vw']
|
||||
}
|
||||
className="pb-10 max-sm:pb-20"
|
||||
childClassName="flex flex-col justify-stretch h-full"
|
||||
controlsPosition={'bottom'}
|
||||
/>
|
||||
|
||||
@@ -3,16 +3,16 @@ import { ArrowRightIcon } from '../../components/icons/ArrowRightIcon';
|
||||
|
||||
export function SliderControls({
|
||||
slidesCount = 6,
|
||||
height = 66,
|
||||
width = 132,
|
||||
height,
|
||||
width,
|
||||
slide = 0,
|
||||
onLeftClick,
|
||||
onRightClick,
|
||||
className,
|
||||
}: {
|
||||
slidesCount?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
width: number;
|
||||
height: number;
|
||||
slide: number;
|
||||
onLeftClick: () => void;
|
||||
onRightClick: () => void;
|
||||
@@ -22,7 +22,7 @@ export function SliderControls({
|
||||
|
||||
return (
|
||||
<div className={'flex items-center gap-2 ' + className}>
|
||||
<div className="relative flex justify-center">
|
||||
<div className="relative flex justify-center max-sm:order-2">
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
@@ -41,7 +41,7 @@ export function SliderControls({
|
||||
strokeLinecap="butt"
|
||||
/>
|
||||
<rect
|
||||
className={'transition-all duration-300'}
|
||||
className="transition-all duration-300"
|
||||
x="1"
|
||||
y="1"
|
||||
width={width - 2}
|
||||
@@ -50,7 +50,7 @@ export function SliderControls({
|
||||
stroke="white"
|
||||
strokeLinecap="butt"
|
||||
strokeDasharray={`calc(${length}/${slidesCount}*${slide + 1}) ${length - (length / slidesCount) * (slide + 1)}`}
|
||||
strokeDashoffset={'-33'}
|
||||
strokeDashoffset={`-${height / 2}`}
|
||||
/>
|
||||
</svg>
|
||||
<p className="h4 font-medium absolute self-center">
|
||||
@@ -59,13 +59,13 @@ export function SliderControls({
|
||||
</div>
|
||||
<button
|
||||
onClick={onLeftClick}
|
||||
className="rounded-full p-5 border border-[#3D425C] bg-[#14161F]"
|
||||
className="rounded-full sm:p-5 p-4 border border-[#3D425C] bg-[#14161F]"
|
||||
>
|
||||
<ArrowLeftIcon />
|
||||
</button>
|
||||
<button
|
||||
onClick={onRightClick}
|
||||
className="rounded-full p-5 border border-[#3D425C] bg-[#14161F]"
|
||||
className="rounded-full sm:p-5 p-4 border border-[#3D425C] bg-[#14161F] max-sm:order-2"
|
||||
>
|
||||
<ArrowRightIcon />
|
||||
</button>
|
||||
|
||||
@@ -123,7 +123,7 @@ function TeachingFeaturesForOtherScreens() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="overflow-hidden relative flex sm:aspect-[768/240] aspect-[36/34] sm:order-2 order-3 border-t border-[#3D425C] sm:bg-[url(src/assets/teaching/highlight_tablet.png)] bg-[url(src/assets/teaching/highlight_mobile.png)] bg-[length:0%] hover:bg-[length:100%] bg-no-repeat bg-right-top transition-all sm:pt-6 sm:px-6 pt-5 px-5">
|
||||
<div className="overflow-hidden relative flex sm:aspect-[768/240] aspect-[36/30] sm:order-2 order-3 border-t border-[#3D425C] sm:bg-[url(src/assets/teaching/highlight_tablet.png)] bg-[url(src/assets/teaching/highlight_mobile.png)] bg-[length:0%] hover:bg-[length:100%] bg-no-repeat bg-bottom transition-all sm:pt-6 sm:px-6 pt-5 px-5">
|
||||
<div className="space-y-1">
|
||||
<TeachingFeatureTitle>Видеозапись обучения</TeachingFeatureTitle>
|
||||
<TeachingFeatureDescription className="sm:max-w-[calc(305/768*100vw)]">
|
||||
@@ -143,7 +143,7 @@ function TeachingFeaturesForOtherScreens() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex relative sm:aspect-[768/240] aspect-[6/5] border-t border-[#3D425C] order-2 sm:order-3 sm:bg-[url(src/assets/teaching/highlight_tablet.png)] bg-[url(src/assets/teaching/highlight_mobile.png)] bg-[length:0%] hover:bg-[length:100%] bg-no-repeat bg-right-top transition-all sm:pt-6 sm:px-6 pt-5 px-5 overflow-hidden">
|
||||
<div className="flex relative sm:aspect-[768/240] aspect-[6/5] border-t border-[#3D425C] order-2 sm:order-3 sm:bg-[url(src/assets/teaching/highlight_tablet.png)] bg-[url(src/assets/teaching/highlight_mobile.png)] bg-[length:0%] hover:bg-[length:100%] bg-no-repeat bg-bottom transition-all sm:pt-6 sm:px-6 pt-5 px-5 overflow-hidden">
|
||||
<div className="space-y-1">
|
||||
<TeachingFeatureTitle>Управление процессом</TeachingFeatureTitle>
|
||||
<TeachingFeatureDescription>
|
||||
@@ -164,7 +164,7 @@ function TeachingFeaturesForOtherScreens() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-start relative sm:aspect-[768/240] aspect-[36/32] border-y order-4 border-[#3D425C] sm:bg-[url(src/assets/teaching/highlight_tablet.png)] bg-[url(src/assets/teaching/highlight_mobile.png)] bg-[length:0%] hover:bg-[length:100%] bg-no-repeat bg-right-top transition-all sm:py-6 sm:px-6 py-5 px-5 overflow-hidden">
|
||||
<div className="flex justify-between items-start relative sm:aspect-[768/240] aspect-[36/30] border-y order-4 border-[#3D425C] sm:bg-[url(src/assets/teaching/highlight_tablet.png)] bg-[url(src/assets/teaching/highlight_mobile.png)] bg-[length:0%] hover:bg-[length:100%] bg-no-repeat bg-bottom transition-all sm:py-6 sm:px-6 py-5 px-5 overflow-hidden">
|
||||
<div className="space-y-1">
|
||||
<TeachingFeatureTitle>Статистика обучения</TeachingFeatureTitle>
|
||||
<TeachingFeatureDescription>
|
||||
@@ -174,7 +174,7 @@ function TeachingFeaturesForOtherScreens() {
|
||||
</div>
|
||||
<img
|
||||
src="src/assets/teaching/stats.jpg"
|
||||
className="rounded-lg absolute sm:right-6 sm:max-w-[calc(166/768*100vw)] max-w-[calc(166/360*100vw)] max-sm:left-[calc(142/360*100vw)] max-sm:top-[calc(112/320*100%)]"
|
||||
className="rounded-lg absolute sm:right-6 sm:max-w-[calc(166/768*100vw)] max-w-[calc(166/360*100vw)] max-sm:left-[calc(142/360*100vw)] max-sm:bottom-[calc(34/320*100%)]"
|
||||
alt="Статистика обучения"
|
||||
/>
|
||||
<img
|
||||
|
||||
@@ -58,12 +58,12 @@ function TrainingsFeature({
|
||||
ref={ref}
|
||||
className="lg:first:h-[200px] lg:last:h-[200px] lg:h-[176px] sm:flex max-sm:space-y-[42px] items-stretch justify-between sm:py-10 max-sm:pt-5"
|
||||
>
|
||||
<div className="sm:space-y-4 w-1/3 col-span-1">
|
||||
<div className="sm:space-y-4 lg:w-1/3 sm:w-1/2 col-span-1">
|
||||
<h3 className="font-medium max-sm:mb-2 h3">{title}</h3>
|
||||
<p className="opacity-60 l-text">{text}</p>
|
||||
</div>
|
||||
<div className="flex sm:hidden justify-between items-end">
|
||||
<p className="text-[#52587A] m-text mb-5">{order}</p>
|
||||
<p className="text-[#52587A] m-text mb-5">[0{order}]</p>
|
||||
<div className="flex flex-col items-center">
|
||||
<img src={src} alt={title} className="relative z-30 w-[50vw]" />
|
||||
<VrBacklightIcon className="absolute w-[36vw] h-fit" />
|
||||
|
||||
@@ -6,8 +6,10 @@ export const projects: IProject<Media>[] = [
|
||||
tags: ['Симулятор'],
|
||||
title: 'Симулятор погрузчика',
|
||||
media: Media.img,
|
||||
year: '2024',
|
||||
},
|
||||
{
|
||||
year: '2024',
|
||||
media: Media.video,
|
||||
src: [
|
||||
'src/assets/projects/operator.mp4',
|
||||
@@ -20,16 +22,19 @@ export const projects: IProject<Media>[] = [
|
||||
src: 'src/assets/projects/plane.png',
|
||||
tags: ['Симулятор', 'VR-приложение'],
|
||||
title: 'L 410 NG Aircraft',
|
||||
year: '2024',
|
||||
media: Media.img,
|
||||
},
|
||||
{
|
||||
src: 'src/assets/projects/hangar.png',
|
||||
year: '2024',
|
||||
tags: ['Симулятор', 'VR-приложение'],
|
||||
title: 'Сборка-разборка вертолётного двигателя',
|
||||
media: Media.img,
|
||||
},
|
||||
{
|
||||
src: 'src/assets/projects/trains.png',
|
||||
year: '2024',
|
||||
tags: ['Симулятор', 'VR-приложение'],
|
||||
title: 'Тренажер РЖД: ЭП2Д, Иволга, ЭП20, ТЭ33А, ТЭМ2',
|
||||
media: Media.img,
|
||||
@@ -38,10 +43,12 @@ export const projects: IProject<Media>[] = [
|
||||
src: 'src/assets/projects/laboratory.png',
|
||||
tags: ['Симулятор', 'VR-приложение'],
|
||||
title: 'Учебная лаборатория определения жирности молока',
|
||||
year: '2024',
|
||||
media: Media.img,
|
||||
},
|
||||
{
|
||||
src: 'src/assets/projects/train_big.jpg',
|
||||
year: '2024',
|
||||
tags: ['Симулятор'],
|
||||
title: 'Симулятор машиниста',
|
||||
media: Media.img,
|
||||
|
||||
@@ -7,5 +7,6 @@ export interface IProject<TMedia extends Media> {
|
||||
src: TMedia extends Media.img ? string : string[];
|
||||
title: string;
|
||||
tags: string[];
|
||||
year: string;
|
||||
media: TMedia;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,10 @@ export function SliderWithScaling<T extends { title: string }>({
|
||||
controlsPosition: 'top' | 'bottom';
|
||||
}) {
|
||||
const width = useWindowWidth();
|
||||
const baseoffset = (-width / 1600) * 507 + 8;
|
||||
const baseoffset =
|
||||
width >= 1024
|
||||
? (-width / 1600) * 507 + 8
|
||||
: (-width * +minWidth.slice(0, -2)) / 100 + 8;
|
||||
|
||||
const [slide, setSlide] = useState(0);
|
||||
const [sliderOffset, setSliderOffset] = useState(baseoffset);
|
||||
@@ -150,11 +153,13 @@ export function SliderWithScaling<T extends { title: string }>({
|
||||
onLeftClick={prevSlide}
|
||||
onRightClick={nextSlide}
|
||||
slidesCount={slides.length}
|
||||
width={width >= 640 ? 132 : ((width - 32) / 328) * 196}
|
||||
height={width >= 640 ? 66 : 58}
|
||||
className={
|
||||
'absolute right-0 ' +
|
||||
'absolute ' +
|
||||
(controlsPosition === 'top'
|
||||
? 'top-[75px]'
|
||||
: 'bottom-[100px] self-end')
|
||||
: 'bottom-0 sm:self-end self-center')
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user