fixes slider

This commit is contained in:
2024-09-09 13:42:52 +05:00
parent 4d402f9abf
commit 4179714ebe
7 changed files with 185 additions and 102 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ import { clients } from '../consts/clients';
export function Clients() {
return (
<div className="mt-[100px] space-y-8">
<div className="mt-[100px] space-y-8 select-none">
<div className="flex items-center overflow-hidden w-screen mt-10 min-h-[117px]">
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
+1 -1
View File
@@ -12,7 +12,7 @@ export function Form() {
<div className="relative max-lg:flex items-center gap-x-[35px]">
<FeedbackForm />
<div className="max-sm:hidden absolute lg:bottom-0 lg:-right-[min(136px,calc(136/1600*100vw))] sm:-right-[min(196px,calc(196/768*100vw))] animate-[spin_10s_linear_infinite]">
<div className="relative lg:w-[calc(512/1600*100vw)] sm:w-[calc(512/768*100vw)] aspect-square flex justify-center transition-all duration-500 lg:hover:w-[calc(446/1600*100vw)] origin-center">
<div className="relative lg:w-[calc(512/1600*100vw)] sm:w-[calc(512/768*100vw)] aspect-square flex justify-center transition-all duration-500 lg::w-[calc(446/1600*100vw)] origin-center">
<div className="lg:w-[calc(116/1600*100vw)] sm:w-[calc(116/768*100vw)] flex flex-col justify-between h-full absolute">
<img src="/src/assets/form/1_1.png" alt="" />
<img src="/src/assets/form/1_2.png" alt="" />
+5 -9
View File
@@ -25,15 +25,11 @@ export function Header() {
return (
<header className="lg:px-6 px-4 flex max-lg:justify-between items-center lg:h-16 h-12 border-b border-[#3D425C] bg-[#14161F]">
<Link to={'/'}>
<ClassNameWrapper
element={<Logo />}
className="h-8 lg:h-10 max-sm:hidden"
/>
<ClassNameWrapper
element={<LogoWithoutText />}
className="h-8 sm:hidden"
/>
<Link to={'/'} className="max-sm:hidden">
<ClassNameWrapper element={<Logo />} className="h-8 lg:h-10" />
</Link>
<Link to={'/'} className="sm:hidden">
<ClassNameWrapper element={<LogoWithoutText />} className="h-8" />
</Link>
<nav className="flex self-stretch mx-auto max-lg:hidden">
{[
+10 -8
View File
@@ -1,8 +1,7 @@
import { AnimatePresence, motion } from 'framer-motion';
import { AnimatePresence, motion, useInView } from 'framer-motion';
import { Title } from './ui/Title';
import { promotionFeatures } from '../consts/promotionFeatures';
import { useRef, useState } from 'react';
import { useHover } from 'usehooks-ts';
import { useLocation } from 'react-router-dom';
import { hashes } from '../consts/motivationHashes';
import { ChevronUpIcon } from './icons/ChevronUpIcon';
@@ -59,7 +58,10 @@ function DesktopFeature({
const width = useWindowWidth();
const hovered = useHover(ref);
// const hovered = useHover(ref);
const inView = useInView(ref, {
margin: '0% 0% -67%',
});
return (
<div
@@ -71,7 +73,7 @@ function DesktopFeature({
className="flex justify-between gap-x-4 [clip-path:polygon(0%_0%,100%_0%,100%_calc(100%+28px),0%_calc(100%+28px))]"
transition={{ duration: 0.7 }}
animate={
hovered || hash.slice(1) === hashes.get(number)
inView || hash.slice(1) === hashes.get(number)
? { height: 0.265 * width }
: { height: 0.0875 * width }
}
@@ -82,11 +84,11 @@ function DesktopFeature({
<p className="text-[32px] leading-none mt-12 font-medium transition-all duration-700">
{title}
</p>
{(hovered || hash.slice(1) === hashes.get(number)) && (
{(inView || hash.slice(1) === hashes.get(number)) && (
<motion.p
className="font-medium h4 opacity-60"
animate={
hovered || hash.slice(1) === hashes.get(number)
inView || hash.slice(1) === hashes.get(number)
? { opacity: 0.6 }
: { opacity: 0 }
}
@@ -102,7 +104,7 @@ function DesktopFeature({
transition={{ duration: 1 }}
animate={{
translateX:
hovered || hash.slice(1) === hashes.get(number)
inView || hash.slice(1) === hashes.get(number)
? (images.length - 1) * width * 0.15 + (images.length - 2) * 8
: 0,
}}
@@ -117,7 +119,7 @@ function DesktopFeature({
className="h-full "
animate={{
maxHeight:
(hovered || hash.slice(1) === hashes.get(number)) &&
(inView || hash.slice(1) === hashes.get(number)) &&
index === 0
? 0.265 * width
: 0.0875 * width,
+1 -1
View File
@@ -21,7 +21,7 @@ export function Stands() {
<SliderWithScaling
slides={stands}
SlideElement={Stand}
className="pb-20 space-y-8"
className="pb-0 space-y-8 max-sm:pb-20"
slideSizes={
width >= 1024
? ['31.6vw', '31.8vw', '48vw', '48vw']
+148 -68
View File
@@ -1,74 +1,154 @@
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
import { ArrowLeftIcon } from '../icons/ArrowLeftIcon';
import { ArrowRightIcon } from '../icons/ArrowRightIcon';
export function SliderControls({
slidesCount = 6,
height,
width,
slide = 0,
onLeftClick,
onRightClick,
className,
}: {
slidesCount?: number;
width: number;
height: number;
slide: number;
onLeftClick: () => void;
onRightClick: () => void;
className?: string;
}) {
const length = 2 * Math.PI * (height / 2) + (width - height) * 2;
export const SliderControls = forwardRef<
{ left: () => void; right: () => void },
{
slidesCount: number;
width: number;
height: number;
slide: number;
onLeftClick: () => void;
onRightClick: () => void;
className?: string;
}
>(
(
{
slidesCount,
height,
width,
slide = 0,
onLeftClick,
onRightClick,
className,
},
ref,
) => {
const length = 2 * Math.PI * (height / 2) + (width - height) * 2;
return (
<div className={'flex items-center gap-2 ' + className}>
<div className="relative flex justify-center max-sm:order-2">
<svg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="bg-[#14161F] rounded-full"
const prevBtnRef = useRef<HTMLButtonElement>(null);
const nextBtnRef = useRef<HTMLButtonElement>(null);
const strokeRef = useRef<SVGRectElement>(null);
useEffect(() => {
const interval = setInterval(() => {
nextBtnRef.current?.click();
}, 5000);
return () => clearInterval(interval);
}, [onRightClick]);
useImperativeHandle(ref, () => ({
left: () => prevBtnRef.current?.click(),
right: () => nextBtnRef.current?.click(),
}));
return (
<div className={'flex items-center gap-2 ' + className}>
<div className="relative flex justify-center max-sm:order-2">
<svg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="bg-[#14161F] rounded-full"
>
<rect
x="1"
y="1"
width={width - 2}
height={height - 2}
rx={(height - 2) / 2}
stroke="#3D425C"
strokeLinecap="butt"
/>
<rect
className="transition-all duration-300"
ref={strokeRef}
x="1"
y="1"
width={width - 2}
height={height - 2}
rx={(height - 2) / 2}
stroke="white"
strokeLinecap="butt"
strokeDasharray={`calc(${length}/${slidesCount}*${slide + 1}) ${length - (length / slidesCount) * (slide + 1)}`}
strokeDashoffset={0}
/>
</svg>
<p className="absolute self-center font-medium h4">
{Math.round(slide) + 1} из {slidesCount}
</p>
</div>
<button
ref={prevBtnRef}
onClick={() => {
// if (slide === 0) {
// let timeout: number | undefined;
// strokeRef.current!.classList.remove(
// 'transition-all',
// 'duration-300',
// );
// strokeRef.current!.setAttribute(
// 'stroke-dasharray',
// `${length} 0`,
// );
// new Promise<void>(
// res =>
// (timeout = setTimeout(() => {
// strokeRef.current!.classList.add(
// 'transition-all',
// 'duration-300',
// );
// res();
// }, 1)),
// ).then(() => {
// onLeftClick();
// clearTimeout(timeout);
// });
// } else {}
onLeftClick();
}}
className="rounded-full sm:p-5 p-4 border border-[#3D425C] bg-[#14161F]"
>
<rect
x="1"
y="1"
width={width - 2}
height={height - 2}
rx={(height - 2) / 2}
stroke="#3D425C"
strokeLinecap="butt"
/>
<rect
className="transition-all duration-300"
x="1"
y="1"
width={width - 2}
height={height - 2}
rx={(height - 2) / 2}
stroke="white"
strokeLinecap="butt"
strokeDasharray={`calc(${length}/${slidesCount}*${slide + 1}) ${length - (length / slidesCount) * (slide + 1)}`}
strokeDashoffset={`-${height / 2}`}
/>
</svg>
<p className="h4 font-medium absolute self-center">
{Math.round(slide) + 1} из {slidesCount}
</p>
<ArrowLeftIcon />
</button>
<button
onClick={() => {
// if (slide + 1 === slidesCount) {
// let timeout: number | undefined;
// strokeRef.current!.classList.remove(
// 'transition-all',
// 'duration-300',
// );
// strokeRef.current!.setAttribute(
// 'stroke-dasharray',
// `0 ${length}`,
// );
// new Promise<void>(res => {
// timeout = setTimeout(() => {
// strokeRef.current!.classList.add(
// 'transition-all',
// 'duration-300',
// );
// res();
// }, 1);
// }).then(() => {
// onRightClick();
// clearTimeout(timeout);
// });
// } else
onRightClick();
}}
ref={nextBtnRef}
className="rounded-full sm:p-5 p-4 border border-[#3D425C] bg-[#14161F] max-sm:order-2"
>
<ArrowRightIcon />
</button>
</div>
<button
onClick={onLeftClick}
className="rounded-full sm:p-5 p-4 border border-[#3D425C] bg-[#14161F]"
>
<ArrowLeftIcon />
</button>
<button
onClick={onRightClick}
className="rounded-full sm:p-5 p-4 border border-[#3D425C] bg-[#14161F] max-sm:order-2"
>
<ArrowRightIcon />
</button>
</div>
);
}
);
},
);
+19 -14
View File
@@ -36,6 +36,10 @@ export function SliderWithScaling<T extends { img: string }>({
const sliderRef = useRef<HTMLDivElement>(null);
const itemRef = useRef<HTMLDivElement>(null);
const controlsRef = useRef<{ left: () => void; right: () => void }>({
left: () => {},
right: () => {},
});
const [order, dispatch] = useReducer(
(state: typeof slides, action: 'prev' | 'next') => {
@@ -70,20 +74,20 @@ export function SliderWithScaling<T extends { img: string }>({
setCurrentSliding(null);
});
};
}, []);
}, [slide]);
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(() => {
@@ -91,8 +95,8 @@ export function SliderWithScaling<T extends { img: string }>({
}, [baseoffset, order, slide]);
const handlers = useSwipeable({
onSwipedLeft: nextSlide,
onSwipedRight: prevSlide,
onSwipedLeft: () => controlsRef.current.right(),
onSwipedRight: () => controlsRef.current.left(),
trackMouse: true,
preventScrollOnSwipe: true,
touchEventOptions: { passive: false },
@@ -100,7 +104,7 @@ export function SliderWithScaling<T extends { img: string }>({
return (
<div className={'flex flex-col relative ' + className}>
<div className="overflow-hidden sm:-mx-6 -mx-4 h-full">
<div className="h-full -mx-4 overflow-hidden sm:-mx-6">
<div {...handlers} className="h-full">
<div
className={`flex items-${alignItems} gap-x-4 -mr-6 select-none`}
@@ -149,6 +153,7 @@ export function SliderWithScaling<T extends { img: string }>({
</div>
</div>
<SliderControls
ref={controlsRef}
slide={slide}
onLeftClick={prevSlide}
onRightClick={nextSlide}
@@ -158,8 +163,8 @@ export function SliderWithScaling<T extends { img: string }>({
className={
'absolute ' +
(controlsPosition === 'top'
? 'top-[75px]'
: 'bottom-0 sm:self-end self-center')
? 'top-[75px] sm:self-end'
: 'lg:bottom-32 bottom-0 sm:self-end self-center')
}
/>
</div>