new fixes, animated text appearance

This commit is contained in:
2024-07-09 19:16:32 +05:00
parent e14c5cef52
commit c737808a71
7 changed files with 162 additions and 73 deletions
+1
View File
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"framer-motion": "^11.2.14",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1",
+30 -9
View File
@@ -1,6 +1,20 @@
import AppearanceText from '../../ui/AppearanceText';
import { MiniTitle } from '../../ui/MiniTitle';
import { Title } from '../../ui/Title';
const splits = [
'В одном ',
'цифровом ',
'пространстве ',
'могут работать ',
'сотрудники, ',
'находящиеся ',
'в разных ',
'помещениях, ',
'зданиях ',
'или городах',
];
export function Availables() {
return (
<div className="desktop:py-[70px] desktop:px-10 mobile:py-14 tablet:px-6 mobile:px-4">
@@ -21,7 +35,7 @@ export function Availables() {
<div className="flex mobile:max-desktop:flex-col items-start desktop:w-fit tablet:pt-5 tablet:border-t border-[#3D425C]">
<MiniTitle text="возможности" />
<div className="tablet:max-desktop-figma:mt-4 mobile:max-tablet:mt-[9px]">
<div className="grid tablet:grid-cols-3 mobile:max-tablet:gap-y-2 desktop:gap-x-4 tablet:max-desktop:gap-x-3 border-b border-[#3D425C] tablet:pb-5 mobile:pb-2 mb-6 justify-stretch mobile:max-tablet:border-t mobile:max-tablet:pt-2">
<div className="flex mobile:max-tablet:flex-col mobile:max-tablet:gap-y-2 desktop:gap-x-4 tablet:max-desktop:gap-x-3 border-b border-[#3D425C] tablet:pb-5 mobile:pb-2 mb-6 mobile:max-tablet:border-t mobile:max-tablet:pt-2">
<MultiUserFeature
img="src/assets/processes.svg"
text="отработка производственных процессов, в которых участвует группа людей"
@@ -35,12 +49,19 @@ export function Availables() {
text="координация действий между несколькими сотрудниками"
/>
</div>
<h3 className="text-[#ffffff] font-medium tablet-figma:max-w-[668px] desktop-figma:max-w-[39.25vw] h3">
В одном цифровом пространстве{' '}
<span className="opacity-60">
могут работать сотрудники, находящиеся в разных помещениях,
зданиях или городах
</span>
<h3
className={
'text-[#ffffff] font-medium tablet-figma:max-w-[668px] desktop-figma:max-w-[39.25vw] h3 '
}
>
{splits.map((text, index) => (
<AppearanceText
text={text}
key={text}
opacity={index > 2 ? 60 : 100}
duration={3 + index}
/>
))}
</h3>
</div>
</div>
@@ -50,9 +71,9 @@ export function Availables() {
function MultiUserFeature({ text, img }: { text: string; img: string }) {
return (
<div className="flex flex-col justify-between items-start p-6 bg-[#3D425C4D] rounded-2xl desktop:max-w-[30vw] desktop:min-h-[214px] tablet:min-h-[240px] mobile:min-h-[220px]">
<div className="flex flex-col desktop-figma:max-w-[22vw] w-full justify-between items-start p-6 bg-[#3D425C4D] rounded-2xl desktop:min-h-[214px] tablet:min-h-[240px] mobile:min-h-[220px]">
<img src={img} alt="" className="mb-14" />
<p className="l-text text-[#ffffff]">{text}</p>
<p className="l-text text-[#ffffff] desktop-figma:max-w-[70%]">{text}</p>
</div>
);
}
+35 -10
View File
@@ -1,12 +1,28 @@
import { MiniTitle } from '../../ui/MiniTitle';
import AppearanceText from '../../ui/AppearanceText';
const splits = [
'В тренажере человек ',
'принимает решения ',
'так же, ',
'как в реальном мире, ',
'активируя ',
'те же нейронные ',
'цепочки в мозгу. ',
'Это позволяет ',
'добиться ',
'реальной ',
'производительности ',
'в работе. ',
];
export function Effeciency() {
return (
<div className="desktop:py-[70px] mobile:py-14 desktop:px-10 tablet:px-6 mobile:px-4">
<div className="flex mobile:max-desktop:flex-col tablet:border-t border-[#3D425C] pt-5 tablet:gap-4">
<div className="flex mobile:max-desktop:flex-col tablet:border-t border-[#3D425C] pt-5 tablet:max-desktop:gap-4">
<MiniTitle text={'экономическая эффективность'} />
<div className="mobile:max-tablet:mt-4">
<div className="flex mobile:max-tablet:flex-col desktop-figma:w-[70.8vw] desktop:max-desktop-figma:w-[clamp(728px,728px+(100vw-1024px)/576*405,1133px)] justify-stretch items-stretch gap-x-4 gap-y-2 mobile:max-tablet:py-5 tablet:pb-5 border-b border-[#3D425C] mb-9 tablet:border-t-0 mobile:border-t">
<div className="flex mobile:max-tablet:flex-col desktop:max-desktop-figma:w-[clamp(728px,728px+(100vw-1024px)/576*405,1133px)] justify-stretch gap-x-4 gap-y-2 mobile:max-tablet:py-5 tablet:pb-5 border-b border-[#3D425C] mb-9 tablet:border-t-0 mobile:border-t">
<Figure
variance={'left'}
percents={50}
@@ -23,12 +39,19 @@ export function Effeciency() {
title={'готовность к опасным ситуациямние выше на'}
/>
</div>
<h3 className="text-[#ffffff] font-medium h3 max-w-[752px] desktop-figma:max-w-[47vw]">
В тренажере человек принимает решения так же, как в реальном мире,{' '}
<span className="opacity-60">
активируя те же нейронные цепочки в мозгу. Это позволяет добиться
реальной производительность в работе.
</span>
<h3
className={
'text-[#ffffff] font-medium h3 max-w-[752px] desktop-figma:max-w-[47vw] '
}
>
{splits.map((text, index) => (
<AppearanceText
key={text}
text={text}
opacity={index > 3 ? 60 : 100}
duration={3 + index}
/>
))}
</h3>
</div>
</div>
@@ -48,14 +71,16 @@ function Figure({
return (
<div
className={
'flex px-6 bg-[#3D425C4D] w-full rounded-2xl pt-6 bg-no-repeat bg-auto xl:bg-[bottom_right_24px] tablet:max-xl:bg-[bottom_right_12px] mobile:bg-[bottom_right_24px] h-[262px]'
'flex px-6 bg-[#3D425C4D] desktop-figma:max-w-[22vw] w-full rounded-2xl pt-6 bg-no-repeat bg-auto xl:bg-[bottom_right_24px] tablet:max-xl:bg-[bottom_right_12px] mobile:bg-[bottom_right_24px] h-[262px]'
}
style={{
backgroundImage: `url(src/assets/${variance}_variance_figure.svg)`,
}}
>
<div className="text-[#ffffff] flex flex-col justify-between py-6 mobile:max-tablet:max-w-[50vw]">
<h6 className="desktop:font-medium l-text">{title}</h6>
<h6 className="desktop:font-medium l-text desktop-figma:max-w-[70%]">
{title}
</h6>
<h1 className="font-medium flex items-center tablet-figma:text-[clamp(64px,64px+(100vw-768px)/832*32,96px)] tablet-figma:leading-[clamp(57.6px,57.6px+(100vw-768px)/832*28.8,86.4px)] mobile:text-[64px] mobile:leading-[57.6px]">
{percents}
<span className="tablet-figma:text-[clamp(32px,32px+(100vw-768px)/832*32,64px)] tablet-figma:leading-[clamp(32px,32px+(100vw-768px)/832*25.6,57.6px)] mobile:text-[32px] mobile:leading-8">
+55 -53
View File
@@ -28,52 +28,54 @@ export function Products() {
продуктами GRAFF.training
</span>
</Title>
<MiniTitle className="desktop:hidden" text="Продукты" />
<div
className="flex gax-y-4 bg-[#3D425C4D] bg-opacity-3 scrollbar-none rounded-xl p-1 mb-2 w-fit max-w-full overflow-auto tablet:max-desktop:mt-[13px] mobile:mt-6 mobile:max-[912px]:[-webkit-mask-image:_linear-gradient(to_left,rgba(32,35,50,0)_0%,rgba(32,35,50,1)_20%)]"
ref={ref}
>
<TabButton
className={curTab === 0 ? 'bg-[#798FFF]' : ''}
onClick={e => {
ref.current?.scrollTo({
left: e.currentTarget.offsetLeft - 16,
behavior: 'smooth',
});
setCurTab(0);
}}
text="Промышленные тренажеры"
/>
<TabButton
className={curTab === 1 ? 'bg-[#798FFF]' : ''}
onClick={e => {
ref.current?.scrollTo({
left: e.currentTarget.offsetLeft - 16,
behavior: 'smooth',
});
setCurTab(1);
}}
text="Симуляторы управления техникой"
/>
<TabButton
className={curTab === 2 ? 'bg-[#798FFF]' : ''}
onClick={e => {
ref.current?.scrollTo({
left: e.currentTarget.offsetLeft - 16,
behavior: 'smooth',
});
setCurTab(2);
}}
text="Тренажеры для учебных заведений"
/>
<div className="desktop-figma:pl-64">
<MiniTitle className="desktop:hidden" text="Продукты" />
<div
className="flex gax-y-4 bg-[#3D425C4D] bg-opacity-3 scrollbar-none rounded-xl p-1 mb-2 w-fit max-w-full overflow-auto tablet:max-desktop:mt-[13px] mobile:mt-6 mobile:max-[912px]:[-webkit-mask-image:_linear-gradient(to_left,rgba(32,35,50,0)_0%,rgba(32,35,50,1)_20%)]"
ref={ref}
>
<TabButton
className={curTab === 0 ? 'bg-[#798FFF]' : ''}
onClick={e => {
ref.current?.scrollTo({
left: e.currentTarget.offsetLeft - 16,
behavior: 'smooth',
});
setCurTab(0);
}}
text="Промышленные тренажеры"
/>
<TabButton
className={curTab === 1 ? 'bg-[#798FFF]' : ''}
onClick={e => {
ref.current?.scrollTo({
left: e.currentTarget.offsetLeft - 16,
behavior: 'smooth',
});
setCurTab(1);
}}
text="Симуляторы управления техникой"
/>
<TabButton
className={curTab === 2 ? 'bg-[#798FFF]' : ''}
onClick={e => {
ref.current?.scrollTo({
left: e.currentTarget.offsetLeft - 16,
behavior: 'smooth',
});
setCurTab(2);
}}
text="Тренажеры для учебных заведений"
/>
</div>
{curTab === 0 ? (
<TrainingsTab />
) : curTab === 1 ? (
<SimulatorsTab />
) : (
<ForTeachingTab />
)}
</div>
{curTab === 0 ? (
<TrainingsTab />
) : curTab === 1 ? (
<SimulatorsTab />
) : (
<ForTeachingTab />
)}
</div>
);
}
@@ -129,7 +131,7 @@ function TeachingItem({
function TrainingsTab() {
return (
<div className="bg-[#3D425C4D] rounded-xl desktop:bg-[url('src/assets/mask_group.png')] desktop-figma:bg-cover desktop-figma:bg-[30vw_bottom] bg-right-bottom bg-[length:55%] desktop:p-10 tablet:max-desktop:p-7 mobile:max-tablet:p-5 bg-no-repeat">
<div className="bg-[#3D425C4D] rounded-xl desktop:bg-[url('src/assets/mask_group.png')] desktop-figma:bg-[length:70%] bg-right-bottom desktop:bg-[length:55%] desktop:p-10 tablet:max-desktop:p-7 mobile:max-tablet:p-5 bg-no-repeat">
<div className="desktop:max-w-[455px]">
<div className="tablet:max-desktop:border-b border-[#3D425C] pb-5 tablet:max-desktop:bg-[url('src/assets/mask_group.png')] bg-no-repeat bg-contain bg-right-bottom tablet:max-tablet-figma:bg-[length:40%]">
<div className="tablet:max-desktop:max-w-[326px] mobile:max-tablet:border-b border-[#3D425C]">
@@ -246,7 +248,7 @@ function SimulatorsTab() {
<div className="self-center tablet:max-desktop:max-w-[234px]">
<div {...handlers}>
<div
className="flex desktop:justify-end select-none mobile:max-tablet:relative xl:max-desktop-figma:max-w-[clamp(553px,553px+(100vw-1280px)/320*160,713px)] desktop-figma:max-w-[44.5vw] desktop:max-xl:max-w-[300px] tablet:max-desktop:flex-col tablet:flex-wrap gap-2 tablet:max-desktop:mb-10 mobile:max-tablet:duration-1000"
className="flex desktop:justify-end select-none mobile:max-tablet:relative xl:max-desktop-figma:max-w-[clamp(553px,553px+(100vw-1280px)/320*160,713px)] desktop-figma:max-w-[calc((100vw-256px)*0.53)] desktop:max-xl:max-w-[300px] tablet:max-desktop:flex-col tablet:flex-wrap gap-2 tablet:max-desktop:mb-10 mobile:max-tablet:duration-1000"
style={
width < 640
? {
@@ -270,27 +272,27 @@ function SimulatorsTab() {
<>
<img
src="src/assets/train.png"
className="rounded-lg xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[14.5vw] tablet:max-xl:hidden"
className="rounded-lg xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] tablet:max-xl:hidden"
alt=""
/>
<img
src="src/assets/dispatcher.png"
className="xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[14.5vw] tablet:max-xl:hidden"
className="xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] tablet:max-xl:hidden"
alt=""
/>
<img
src="src/assets/winda.png"
className="xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[14.5vw] tablet:max-xl:hidden"
className="xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] tablet:max-xl:hidden"
alt=""
/>
<img
src="src/assets/rzhd.png"
className="xl:max-desktop-figma:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[22vw]"
className="xl:max-desktop-figma:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[calc((100vw-256px)*0.22)]"
alt=""
/>
<img
src="src/assets/rzhd2.png"
className="xl:max-desktop-figma:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[22vw]"
className="xl:max-desktop-figma:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[calc((100vw-256px)*0.22)]"
alt=""
/>
</>
@@ -318,7 +320,7 @@ function SimulatorsItem({ text }: { text: string }) {
function ForTeachingTab() {
return (
<div className="desktop:bg-[url('src/assets/mask_group2.png')] bg-[#3D425C4D] bg-no-repeat desktop:p-10 tablet:p-7 mobile:p-5 rounded-xl 2xl:bg-cover 2xl:bg-[30vw] bg-[right] desktop:max-2xl:bg-[length:50%]">
<div className="desktop:bg-[url('src/assets/mask_group2.png')] bg-[#3D425C4D] bg-no-repeat desktop:p-10 tablet:p-7 mobile:p-5 rounded-xl 2xl:bg-contain bg-[right] desktop:max-2xl:bg-[length:50%]">
<div className='tablet:max-desktop:bg-[url("src/assets/mask_group2.png")] bg-no-repeat bg-right bg-[length:50%] tablet:max-desktop:pb-[55px] mobile:max-desktop:border-b border-[#3D425C] tablet:mb-8 mobile:mb-4'>
<h3 className="text-[#ffffff] font-medium desktop:max-w-[455px] tablet:max-w-[326px] mobile:max-tablet:mb-5 h3">
Интерактивные тренажеры для учебных заведений
+1 -1
View File
@@ -67,7 +67,7 @@ function TeachingFeaturesForDesktop() {
</div>
<img
src="src/assets/modal.svg"
className="rounded-lg w-[calc(468/880*100%)] object-cover object-left"
className="rounded-lg w-[calc(468/880*100%)] object-fill object-right"
alt=""
/>
</div>
+28
View File
@@ -0,0 +1,28 @@
import { useInView, motion } from 'framer-motion';
import { useRef } from 'react';
export default function AppearanceText({
text,
opacity,
duration,
}: {
text: string;
opacity: number;
duration: number;
}) {
const ref = useRef<HTMLSpanElement>(null);
const isInView = useInView(ref);
return (
<motion.span
ref={ref}
style={{ transition: duration + 's' }}
className={
// `duration-[${duration}s]` +
isInView ? ` opacity-${opacity}` : ' opacity-0'
}
>
{text}
</motion.span>
);
}
+12
View File
@@ -1242,6 +1242,13 @@ fraction.js@^4.3.7:
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
framer-motion@^11.2.14:
version "11.2.14"
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.2.14.tgz#739aa2eb7bcd4fe49f4cd9b88d352eb85d6cda8b"
integrity sha512-0Nwg++Jymj4Yn7LFKH/nKuGrgVZTEIgIbLjl+LBBFBEzNd4rX+n3z/doqjEbvjk1xcmsim9h7du2+LTYdQTULw==
dependencies:
tslib "^2.4.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -2123,6 +2130,11 @@ ts-interface-checker@^0.1.9:
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
tslib@^2.4.0:
version "2.6.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"