fix
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 3.0 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 778 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
+75
-56
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
// import { createRef, useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||
// import { useSwipeable } from "react-swipeable";
|
||||
// import { motion } from "framer-motion";
|
||||
@@ -5,7 +6,7 @@
|
||||
// import ArrowLeftIcon from "./icons/ArrowLeftIcon";
|
||||
// import ArrowRightIcon from "./icons/ArrowRightIcon";
|
||||
// import { Video } from "../types/Video";
|
||||
import { createRef, useEffect, useState } from "react";
|
||||
import { createRef, useEffect, useLayoutEffect, useState } from "react";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { useSwipeable } from "react-swipeable";
|
||||
import { Video } from "../types/Video";
|
||||
@@ -13,30 +14,70 @@ import ArrowLeftIcon from "./icons/ArrowLeftIcon";
|
||||
import ArrowRightIcon from "./icons/ArrowRightIcon";
|
||||
import { Transition } from "react-transition-group";
|
||||
|
||||
const VIDEOS: Video[] = [
|
||||
type Review = {
|
||||
id: string;
|
||||
avatar: string;
|
||||
name: string;
|
||||
position: string;
|
||||
desc: string;
|
||||
video: string;
|
||||
poster: string;
|
||||
};
|
||||
|
||||
const REVIEWS: Review[] = [
|
||||
{
|
||||
id: "1",
|
||||
value: "/videos/histories/1.mp4",
|
||||
title: "",
|
||||
desc: "Интерактивный комплекс GRAFF.estate для ЖК Upside Towers, Москва",
|
||||
poster: "",
|
||||
avatar: "/images/reviews/avatars/1.png",
|
||||
name: "Егор бобров",
|
||||
position: "Коммерческий директор авторского квартала «Машаров»",
|
||||
desc: "Эффективность инструмента была подтверждена буквально в первый день после его внедрения. Например, один из клиентов, посетив офис и увидев свою будущую квартиру с помощью интерактивной панели, сразу решил купить недвижимость в этом проекте, отказавшись от других вариантов",
|
||||
poster: "/images/reviews/1.png",
|
||||
video: "",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
value: "/videos/histories/2.mp4",
|
||||
title: "",
|
||||
desc: "Graff.estate на выставке 100+ TechnoBuild",
|
||||
poster: "",
|
||||
avatar: "/images/reviews/avatars/2.png",
|
||||
name: "Олег Бондорев",
|
||||
position: "Ведущий менеджер компании «ЭНКО»",
|
||||
desc: "Клиенты особенно ценят возможность легко выбрать квартиру с помощью 3D-модель жилого комплекса. Так же инструмент продаж позволяет клиенту увидеть расположение дома, в какое время свет будет попадать в окна, даже зайти в лифт и холл, а также оценить инфраструктуру района и «прочувствовать» его, прогулявшись по двору",
|
||||
poster: "/images/reviews/1.png",
|
||||
video: "",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
value: "/videos/histories/3.mp4",
|
||||
title: "",
|
||||
desc: "Интерактивная инсталляция graff.estate для ЖК DNS City в г.Владивосток",
|
||||
poster: "",
|
||||
avatar: "/images/reviews/avatars/3.png",
|
||||
name: "Алина Веселова",
|
||||
position: "Ведущий специалист отдела продаж",
|
||||
desc: "Одним из преимуществ инструмента является возможность посмотреть 3D-модель квартиры с готовым дизайнерским ремонтом и оценить видовые характеристиками, изменяя время суток (день или ночь). Это важно для клиента, так как позволяет реалистично представить, как будет выглядеть будущее жилье.",
|
||||
poster: "/images/reviews/2.png",
|
||||
video: "",
|
||||
},
|
||||
];
|
||||
|
||||
// const REVIEWS: Video[] = [
|
||||
// {
|
||||
// id: "1",
|
||||
// value: "/images/reviews/1.png",
|
||||
// title: "",
|
||||
// desc: "Интерактивный комплекс GRAFF.estate для ЖК Upside Towers, Москва",
|
||||
// poster: "",
|
||||
// },
|
||||
// {
|
||||
// id: "2",
|
||||
// value: "/images/reviews/2.png",
|
||||
// title: "",
|
||||
// desc: "Graff.estate на выставке 100+ TechnoBuild",
|
||||
// poster: "",
|
||||
// },
|
||||
// {
|
||||
// id: "3",
|
||||
// value: "/videos/histories/3.mp4",
|
||||
// title: "",
|
||||
// desc: "Интерактивная инсталляция graff.estate для ЖК DNS City в г.Владивосток",
|
||||
// poster: "",
|
||||
// },
|
||||
// ];
|
||||
|
||||
// const Reviews = () => {
|
||||
// const [isViewportEntered, setIsViewportEntered] = useState<boolean>(false);
|
||||
|
||||
@@ -208,9 +249,8 @@ const VIDEOS: Video[] = [
|
||||
// };
|
||||
function Reviews() {
|
||||
const [selectedVideoIndex, setSelectedVideoIndex] = useState(0);
|
||||
const videoRefs = VIDEOS.map(() => createRef<HTMLVideoElement>());
|
||||
const videoRefs = REVIEWS.map(() => createRef<HTMLImageElement>());
|
||||
const [videoWidth, setVideoWidth] = useState<number>(0);
|
||||
const [videoHeigth, setVideoHeigth] = useState<number>(0);
|
||||
const { ref, inView } = useInView();
|
||||
const [isEntered, setIsEntered] = useState(false);
|
||||
const handlers = useSwipeable({
|
||||
@@ -219,13 +259,12 @@ function Reviews() {
|
||||
trackMouse: true,
|
||||
});
|
||||
|
||||
function handleEnded() {
|
||||
if (selectedVideoIndex === VIDEOS.length - 1) {
|
||||
setSelectedVideoIndex(0);
|
||||
} else {
|
||||
setSelectedVideoIndex((prev) => prev + 1);
|
||||
useEffect(() => {
|
||||
if (videoRefs[0].current) {
|
||||
const width = videoRefs[0].current.clientWidth;
|
||||
setVideoWidth(width);
|
||||
}
|
||||
}
|
||||
}, [videoRefs]);
|
||||
|
||||
function prev() {
|
||||
if (selectedVideoIndex === 0) return;
|
||||
@@ -233,7 +272,7 @@ function Reviews() {
|
||||
}
|
||||
|
||||
function next() {
|
||||
if (selectedVideoIndex === VIDEOS.length - 1) return;
|
||||
if (selectedVideoIndex === REVIEWS.length - 1) return;
|
||||
setSelectedVideoIndex((prev) => prev + 1);
|
||||
}
|
||||
|
||||
@@ -248,7 +287,7 @@ function Reviews() {
|
||||
ref={ref}
|
||||
className="container mx-auto 2xl:max-w-screen-2xl mb-[120px]"
|
||||
>
|
||||
<div className="flex 2xl:h-[760px] xl:h-[687px] sm:h-[500px] h-[875px] sm:border-b border-b-[#3D425C] sm:flex-row flex-col">
|
||||
<div className="flex 2xl:h-[594px] xl:h-[484px] sm:h-[784px] h-[552px] sm:border-b border-b-[#3D425C] xl:flex-row sm:flex-col-reverse flex-col ">
|
||||
<div className="left 2xl:min-w-[496px] xl:min-w-[395px] sm:min-w-[354px] flex flex-col sm:pb-10 pb-6">
|
||||
<h2 className="font-medium 2xl:text-[64px] xl:text-5xl text-[40px] sm:mb-10 mb-6 font-gilroy leading-10">
|
||||
<p className="from-[#798FFF] to-[#D375FF] bg-gradient-to-r bg-clip-text text-transparent">
|
||||
@@ -257,7 +296,7 @@ function Reviews() {
|
||||
<p>клиентов</p>
|
||||
</h2>
|
||||
<div className="relative bg-white sm:block hidden">
|
||||
{VIDEOS.map((item, index) => (
|
||||
{REVIEWS.map((item, index) => (
|
||||
<Transition
|
||||
key={index}
|
||||
in={Boolean(index === selectedVideoIndex)}
|
||||
@@ -267,9 +306,9 @@ function Reviews() {
|
||||
<div
|
||||
className={`absolute transition-opacity duration-300 pr-10 ${state}`}
|
||||
>
|
||||
{item.title ? (
|
||||
{item.name ? (
|
||||
<p className="font-semibold mb-4 2xl:text-xl xl:text-[16px]">
|
||||
{item.title}
|
||||
{item.name}
|
||||
</p>
|
||||
) : (
|
||||
<></>
|
||||
@@ -304,10 +343,11 @@ function Reviews() {
|
||||
clipPath: `rect(auto auto auto 0)`,
|
||||
}}
|
||||
>
|
||||
{VIDEOS.map((video, index) => (
|
||||
{REVIEWS.map((video, index) => (
|
||||
<div
|
||||
key={video.id}
|
||||
className="relative sm:aspect-[16/9] aspect-auto bg-black transition-transform duration-300 sm:h-auto sm:min-w-0 h-[546px]"
|
||||
className="relative sm:aspect-[16/9] aspect-auto bg-black transition-transform duration-300 sm:h-full sm:min-w-0 h-[546px]"
|
||||
// className="relative sm:aspect-[16/9] aspect-auto bg-black transition-transform duration-300 sm:h-full sm:min-w-0 h-[546px]"
|
||||
style={{
|
||||
transform: `translateX(-${
|
||||
videoWidth * selectedVideoIndex + 16 * selectedVideoIndex
|
||||
@@ -315,37 +355,16 @@ function Reviews() {
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={isEntered ? video.value : undefined}
|
||||
alt={video.title}
|
||||
src={isEntered ? video.poster : undefined}
|
||||
alt={video.desc}
|
||||
ref={videoRefs[index]}
|
||||
className="aspect-[16/9] object-cover w-full h-full min-w-screen"
|
||||
onLoadedData={() =>
|
||||
setTimeout(() => {
|
||||
setVideoWidth(videoRefs[0].current!.clientWidth);
|
||||
setVideoHeigth(videoRefs[0].current!.clientHeight);
|
||||
}, 200)
|
||||
}
|
||||
/>
|
||||
{/* <video
|
||||
ref={videoRefs[index]}
|
||||
src={isEntered ? video.value : undefined}
|
||||
poster={video.poster}
|
||||
muted
|
||||
playsInline
|
||||
className="aspect-[16/9] object-cover w-full h-full min-w-screen"
|
||||
onEnded={handleEnded}
|
||||
onLoadedData={() =>
|
||||
setTimeout(() => {
|
||||
setVideoWidth(videoRefs[0].current!.clientWidth);
|
||||
setVideoHeigth(videoRefs[0].current!.clientHeight);
|
||||
}, 200)
|
||||
}
|
||||
/> */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="relative block sm:hidden h-[100%] bg-[#212431] p-6">
|
||||
{VIDEOS.map((item, index) => (
|
||||
{REVIEWS.map((item, index) => (
|
||||
<Transition
|
||||
key={index}
|
||||
in={Boolean(index === selectedVideoIndex)}
|
||||
@@ -355,9 +374,9 @@ function Reviews() {
|
||||
<div
|
||||
className={`absolute transition-opacity duration-300 pr-10 ${state}`}
|
||||
>
|
||||
{item.title ? (
|
||||
{item.name ? (
|
||||
<p className="font-semibold mb-4 2xl:text-xl xl:text-[16px]">
|
||||
{item.title}
|
||||
{item.name}
|
||||
</p>
|
||||
) : (
|
||||
<></>
|
||||
@@ -371,7 +390,7 @@ function Reviews() {
|
||||
))}
|
||||
</div>
|
||||
<div className="mx-auto flex gap-2 min-h-2 sm:hidden relative mt-6">
|
||||
{VIDEOS.map((video, index) => (
|
||||
{REVIEWS.map((video, index) => (
|
||||
<div
|
||||
key={video.id}
|
||||
className="h-full w-2 rounded-full transition-all duration-300"
|
||||
|
||||
Reference in New Issue
Block a user