upd
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 807 KiB |
|
Before Width: | Height: | Size: 412 KiB |
|
Before Width: | Height: | Size: 421 KiB |
|
Before Width: | Height: | Size: 546 KiB |
|
Before Width: | Height: | Size: 539 KiB |
|
Before Width: | Height: | Size: 544 KiB |
|
Before Width: | Height: | Size: 417 KiB |
|
After Width: | Height: | Size: 479 KiB |
|
After Width: | Height: | Size: 590 KiB |
|
After Width: | Height: | Size: 560 KiB |
|
After Width: | Height: | Size: 475 KiB |
|
After Width: | Height: | Size: 493 KiB |
|
After Width: | Height: | Size: 513 KiB |
|
After Width: | Height: | Size: 835 KiB |
|
After Width: | Height: | Size: 830 KiB |
|
After Width: | Height: | Size: 957 KiB |
|
After Width: | Height: | Size: 1012 KiB |
|
After Width: | Height: | Size: 824 KiB |
|
After Width: | Height: | Size: 822 KiB |
|
After Width: | Height: | Size: 994 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB |
@@ -19,7 +19,13 @@ function Button({
|
||||
}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
<span className={`${iconOrderLast ? "order-last" : ""} ${widthFull ? "" : ""}`}>{icon}</span>
|
||||
<span
|
||||
className={`${iconOrderLast ? "order-last" : ""} ${
|
||||
widthFull ? "" : ""
|
||||
}`}
|
||||
>
|
||||
{icon}
|
||||
</span>
|
||||
<span>{text}</span>
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ const InfrastructureFilters = ({
|
||||
selectedRange,
|
||||
marks,
|
||||
}: InfrastructureFiltersProps) => {
|
||||
const [filter, setFilter] = useState("");
|
||||
const [filter, setFilter] = useState("shop");
|
||||
function handleOnFilterClick(
|
||||
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
|
||||
): void {
|
||||
@@ -34,7 +34,6 @@ const InfrastructureFilters = ({
|
||||
const filteredMarks = marks.filter(
|
||||
(mark) => mark.icon === filter && mark.distance <= selectedRange
|
||||
);
|
||||
console.log("filteredMarks", filteredMarks);
|
||||
|
||||
setFilteredMarks(filteredMarks);
|
||||
}, [selectedRange, filter, marks, setFilteredMarks]);
|
||||
@@ -42,9 +41,12 @@ const InfrastructureFilters = ({
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<h2 className="font-tenor text-2xl mb-8">Инфраструктура</h2>
|
||||
<h3 className="text-[18px] mb-5">Окружение:</h3>
|
||||
<div className="flex flex-col gap-2 mb-8 border-b border-[#9595A2] pb-8">
|
||||
{/* <h2 className="font-tenor 2xl:text-2xl text-xl 2xl:mb-8 mb-5"> */}
|
||||
<h2 className="font-tenor text-xl mb-5">Инфраструктура</h2>
|
||||
{/* <h3 className="text-[18px] 2xl:mb-5 mb-3">Окружение:</h3> */}
|
||||
<h3 className="text-[18px] mb-3">Окружение:</h3>
|
||||
{/* <div className="flex flex-col 2xl:gap-2 gap-[6px] 2xl:mb-8 mb-5 border-b border-[#9595A2] 2xl:pb-8 pb-5"> */}
|
||||
<div className="flex flex-col 2xl:gap-2 gap-[6px] mb-5 border-b border-[#9595A2] pb-5">
|
||||
{environments.map((env) => (
|
||||
<button
|
||||
data-set={env.type}
|
||||
@@ -54,15 +56,15 @@ const InfrastructureFilters = ({
|
||||
filter !== env.type
|
||||
? "opacity-60 border-b-2 border-b-transparent"
|
||||
: "border-b-2 border-b-[#0079C2]"
|
||||
} flex gap-2 font-medium text-sm px-[2px] py-2 transition-all duration-300 ease-in-out`}
|
||||
} flex gap-2 font-medium 2xl:text-sm xl:text-xs px-[2px] py-2 transition-all duration-300 ease-in-out`}
|
||||
>
|
||||
{env.icon}
|
||||
<div>{env.label}</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 border-b border-[#9595A2] pb-8">
|
||||
<h3 className="text-[18px] mb-5">Транспорт:</h3>
|
||||
<div className="flex flex-col gap-2 border-b border-[#9595A2] 2xl:pb-8 pb-5">
|
||||
<h3 className="text-[18px] 2xl:mb-5 mb-3">Транспорт:</h3>
|
||||
{transports.map((trans) => (
|
||||
<button
|
||||
data-set={trans.type}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { isMobile } from "react-device-detect";
|
||||
import { Mark } from "../types/Mark";
|
||||
import MarkEducationIcon from "./icons/marks/MarkEducationIcon";
|
||||
import MarkFoodIcon from "./icons/marks/MarkFoodIcon";
|
||||
import MarkHeathyIcon from "./icons/marks/MarkHeathyIcon";
|
||||
import MarkShopIcon from "./icons/marks/MarkShopIcon";
|
||||
import { MarkSportIcon } from "./icons/marks/MarkSportIcon";
|
||||
|
||||
const markIcons: { [key: string]: React.ReactNode } = {
|
||||
shop: <MarkShopIcon />,
|
||||
food: <MarkFoodIcon />,
|
||||
heathy: <MarkHeathyIcon />,
|
||||
education: <MarkEducationIcon />,
|
||||
sport: <MarkSportIcon />,
|
||||
};
|
||||
|
||||
interface MarksContainerProps {
|
||||
@@ -21,8 +24,8 @@ interface MarksContainerProps {
|
||||
function MarksContainer({
|
||||
marks,
|
||||
filteredMarks,
|
||||
markWidth = 52,
|
||||
markHeigth = 52,
|
||||
markWidth = isMobile ? 64 : 48,
|
||||
markHeigth = isMobile ? 64 : 48,
|
||||
}: MarksContainerProps) {
|
||||
return (
|
||||
<svg
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { useEffect, useState } from "react";
|
||||
import gsap from "gsap";
|
||||
// import gsap from "gsap";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import Button from "./Button";
|
||||
import { Transition } from "react-transition-group";
|
||||
import PointButton from "./PointButton";
|
||||
import WalkIcon from "./icons/WalkIcon";
|
||||
import MarksContainer from "./MarksContainer";
|
||||
// import Button from "./Button";
|
||||
// import { Transition } from "react-transition-group";
|
||||
|
||||
interface SequenceSliderProps {
|
||||
path: string;
|
||||
@@ -20,39 +17,39 @@ function SequenceSlider({ path }: SequenceSliderProps) {
|
||||
const [touchPositionX, setTouchPositionX] = useState<number>();
|
||||
const [loadedImages, setLoadedImages] = useState<number>(0);
|
||||
|
||||
function animate() {
|
||||
const obj = { selectedImageIndex };
|
||||
// function animate() {
|
||||
// const obj = { selectedImageIndex };
|
||||
|
||||
function getDirection() {
|
||||
const targetFrame =
|
||||
obj.selectedImageIndex < arrayLength / 2 ? "left" : "right";
|
||||
// function getDirection() {
|
||||
// const targetFrame =
|
||||
// obj.selectedImageIndex < arrayLength / 2 ? "left" : "right";
|
||||
|
||||
return targetFrame;
|
||||
}
|
||||
// return targetFrame;
|
||||
// }
|
||||
|
||||
function getDuration() {
|
||||
const direction = getDirection();
|
||||
let duration;
|
||||
// function getDuration() {
|
||||
// const direction = getDirection();
|
||||
// let duration;
|
||||
|
||||
if (direction === "left") {
|
||||
duration = selectedImageIndex / 90;
|
||||
} else {
|
||||
duration = (arrayLength - selectedImageIndex) / 90;
|
||||
}
|
||||
// if (direction === "left") {
|
||||
// duration = selectedImageIndex / 90;
|
||||
// } else {
|
||||
// duration = (arrayLength - selectedImageIndex) / 90;
|
||||
// }
|
||||
|
||||
return duration;
|
||||
}
|
||||
// return duration;
|
||||
// }
|
||||
|
||||
gsap.to(obj, {
|
||||
selectedImageIndex: getDirection() === "left" ? 0 : arrayLength,
|
||||
duration: getDuration(),
|
||||
ease: "power1.inOut",
|
||||
onUpdate: () => {
|
||||
console.log("data", obj.selectedImageIndex);
|
||||
setSelectedImageIndex(Math.round(obj.selectedImageIndex));
|
||||
},
|
||||
});
|
||||
}
|
||||
// gsap.to(obj, {
|
||||
// selectedImageIndex: getDirection() === "left" ? 0 : arrayLength,
|
||||
// duration: getDuration(),
|
||||
// ease: "power1.inOut",
|
||||
// onUpdate: () => {
|
||||
// console.log("data", obj.selectedImageIndex);
|
||||
// setSelectedImageIndex(Math.round(obj.selectedImageIndex));
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedImageIndex === 360) {
|
||||
@@ -115,9 +112,9 @@ function SequenceSlider({ path }: SequenceSliderProps) {
|
||||
}
|
||||
}, [movementX]);
|
||||
|
||||
const [width, setWidth] = useState<number>();
|
||||
const [, setWidth] = useState<number>();
|
||||
// const [heigth, setHeigth] = useState<number>();
|
||||
const [top, setTop] = useState<number>();
|
||||
const [, setTop] = useState<number>();
|
||||
|
||||
function handleResize() {
|
||||
setWidth(window.innerWidth);
|
||||
@@ -144,31 +141,7 @@ function SequenceSlider({ path }: SequenceSliderProps) {
|
||||
/>
|
||||
))}
|
||||
|
||||
<div className="absolute w-full h-full">
|
||||
<Transition in={selectedImageIndex === 0} timeout={150}>
|
||||
{(state) => (
|
||||
<div className={` transition-opacity ${state}`}>
|
||||
<MarksContainer
|
||||
marks={[{ id: "tower_1", icon: "tower", x: 200, y: 200 }]}
|
||||
markWidth={128}
|
||||
markHeigth={128}
|
||||
/>
|
||||
<MarksContainer
|
||||
marks={[{ id: "tower_2", icon: "tower", x: 1800, y: 300 }]}
|
||||
markWidth={128}
|
||||
markHeigth={128}
|
||||
/>
|
||||
<MarksContainer
|
||||
marks={[{ id: "dvor", icon: "walk", x: 1000, y: 1100 }]}
|
||||
markWidth={128}
|
||||
markHeigth={128}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-8 w-full z-10 flex justify-center">
|
||||
{/* <div className="absolute bottom-8 w-full z-10 flex justify-center">
|
||||
<Transition in={selectedImageIndex !== 0} timeout={150}>
|
||||
{(state) => (
|
||||
<div className={`transition-opacity ${state}`}>
|
||||
@@ -176,10 +149,10 @@ function SequenceSlider({ path }: SequenceSliderProps) {
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div
|
||||
className="absolute top-0 left-0 w-full h-full"
|
||||
className="absolute top-0 left-0 w-full h-full cursor-e-resize"
|
||||
onMouseMove={handleMouseMove}
|
||||
onTouchMove={handleTouchMove}
|
||||
onTouchStart={handleTouchStart}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
function ComplexIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={64}
|
||||
height={64}
|
||||
fill="none"
|
||||
// {...props}
|
||||
>
|
||||
<rect
|
||||
width={61.333}
|
||||
height={61.333}
|
||||
x={1.333}
|
||||
y={1.333}
|
||||
fill="#0079C2"
|
||||
rx={30.667}
|
||||
/>
|
||||
<rect
|
||||
width={61.333}
|
||||
height={61.333}
|
||||
x={1.333}
|
||||
y={1.333}
|
||||
stroke="#fff"
|
||||
strokeWidth={2.667}
|
||||
rx={30.667}
|
||||
/>
|
||||
<path
|
||||
fill="#fff"
|
||||
fillRule="evenodd"
|
||||
d="m18.78 43.465 3.16-.368h7.697l3.16.368v.933l-3.16-.18H21.94l-3.16.18v-.933Zm1.856-3.073v1.469l-1.092.13v-1.393l1.092-.206Zm0-1.952v1.47l-1.092.205v-1.388l1.092-.287Zm0-1.951v1.469l-1.092.276v-1.398l1.092-.347Zm0-1.947v1.475l-1.092.347V34.97l1.092-.429Zm0-1.951v.905l-1.092.488v-.905l1.092-.488Zm0-1.952v.911l-1.092.542v-.9l1.092-.553Zm0-1.951v.91l-1.092.63v-.906l1.092-.634Zm0-1.946v1.192l-1.092.634v-1.122l1.092-.704Zm0-1.947v1.188l-1.092.704v-1.116l1.092-.776Zm0-1.957v1.198l-1.092.776v-1.123l1.092-.85ZM30.734 33.41v-.91l-1.092-.494h-3.155l.382-1.116h2.773l1.092.542v-.906l-1.092-.542H27.18l.382-1.122h2.08l1.092.629v-.905l-1.092-.635h-1.768l.256-.758h1.512l1.092.634v-1.21l-1.092-.704H28.55l.257-.753h.819l1.091.704v-1.23l-1.091-.775h-.388l.257-.754h.13l1.092.775v-1.198l-1.091-.85h-7.697l-1.091.85v1.214l1.091-.775h.131l.257.754h-.388l-1.091.775v1.203l1.091-.704h.819l.257.753h-1.092l-1.092.705v1.209l1.092-.634h1.512l.256.759h-1.768l-1.092.634v.905l1.092-.629h2.08l.382 1.122h-2.462l-1.092.543v.905l1.092-.542h2.773l.382 1.116h-3.155l-1.092.494v.91l1.092-.487h3.482l.383 1.122.382-1.122h3.466l1.108.498Zm0 2.532v-1.48l-1.092-.417h-7.696l-1.092.417v1.48l1.092-.347h7.696l1.092.347Zm0 1.968v-1.486l-1.092-.346h-7.696l-1.092.346v1.486l1.092-.277h7.696l1.092.277Zm0 1.962v-1.48l-1.092-.276h-7.696l-1.092.276v1.48l1.092-.206h7.696l1.092.206Zm0 1.963v-1.48l-1.092-.206h-7.696l-1.092.206v1.48l1.092-.13h7.696l1.092.13Zm.207-1.442v1.469l1.092.13v-1.393l-1.092-.206Zm0-1.952v1.47l1.092.205v-1.388l-1.092-.287Zm0-1.951v1.469l1.092.276v-1.398l-1.092-.347Zm0-1.947v1.475l1.092.347V34.97l-1.092-.429Zm0-1.951v.905l1.092.488v-.905l-1.092-.488Zm0-1.952v.911l1.092.542v-.9l-1.092-.553Zm0-1.951v.91l1.092.63v-.906l-1.092-.634Zm0-1.946v1.192l1.092.634v-1.122l-1.092-.704Zm0-1.947v1.188l1.092.704v-1.116l-1.092-.776Zm0-1.957v1.198l1.092.776v-1.123l-1.092-.85Zm0-3.724v3.253l1.092.845v-4.255l.202-.033v4.451l1.091.846v.482l-1.091-.845v1.11l1.091.776v.754l-1.091-.776v1.085l1.091.704v.76l-1.091-.706v1.112l1.091.629v.748l-1.091-.634v.905l1.091.629v.894l-1.091-.542v.916l1.091.542v.9l-1.091-.493v.905l1.091.483v.916l-1.091-.423v1.382l1.091.353v.482l-1.091-.352v1.388l1.091.276v.477l-1.091-.27v1.381l1.091.201v.483l-1.091-.201v1.382l1.091.13v.483l-3.711-.445h-7.697l-3.711.445v-.483l1.091-.13v-1.382l-1.091.2v-.498l1.091-.2V38.77l-1.091.27v-.476l1.091-.277v-1.387l-1.091.352v-.483l1.091-.352v-1.382l-1.091.422v-.9l1.091-.482v-.905l-1.091.493v-.9l1.091-.542v-.905l-1.091.542v-.884l1.091-.629v-.905l-1.091.635v-.76l1.091-.628v-1.112l-1.091.705v-.759l1.091-.704v-1.085l-1.091.776v-.792l1.091-.775V23.83l-1.091.845v-.482l1.091-.846v-4.45l.202.032v4.255l1.092-.845v-3.253l.202.033v3.052l1.092-.852h7.696l1.092.852V19.12l.267-.006ZM45.777 29.36h-2.085l.497-.33h1.588v.33Zm0 1.388h-4.181l.775-.515h3.406v.515Zm0 1.377h-6.255l.775-.543h5.458l.022.543ZM16.52 45.867l9.192-.542L47 46.002v.494H16.52v-.63Zm21.888-12.355v.624h7.369v.759h-7.369v.623h7.369v.764h-7.369v.619h7.369v.742h-7.369v1.084h7.369v.331h-7.369v1.057h7.369v.33h-7.369v1.085h7.369v.325h-7.369v1.057h7.369v.331h-7.369v.618h7.014v.765h-7.21l-1.354.065v-.673l1.36-.179v-.618l-1.36.185v-.342l1.36-.184v-1.063l-1.36.282v-.325l1.36-.282v-1.084l-1.36.38v-.326l1.36-.385V39.02l-1.36.483v-.331l1.36-.482v-1.047l-1.36.602v-.672l1.36-.672v-.619l-1.36.678v-.672l1.36-.77v-.623l-1.36.78v-.672l1.36-.867v-1.139h7.564v.542l-7.374-.027Zm-14.95-14.761h4.667v.542h-4.662l-.005-.542Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fill="#fff"
|
||||
fillRule="evenodd"
|
||||
d="m26.362 32.363-.382 1.122h-.383l-.382-1.122h1.147Zm.671-2.038-.382 1.122h-1.747l-.382-1.122h2.511Zm.693-2.033-.382 1.122H24.19l-.382-1.122h3.92Zm.502-1.49-.256.758h-4.41l-.263-.759h4.93Zm.694-2.034-.257.754h-5.78l-.257-.754h6.294Zm-10.715-3.664 2.238-2.017-2.238-.336v2.353Zm15.12 1.794-3.712-3.1h-7.696l-3.712 3.1v-.482l3.712-3.101h7.696l3.712 3.1v.483Zm0-1.794-2.238-2.017 2.238-.336v2.353Zm-3.712 1.626-.257.759h-7.161l-.257-.759h7.675Zm-2.79 12.37h-2.117v.483h2.118v-.482Zm0 2.04h-2.117v.503h2.118v-.504Zm0 2.032h-2.117v.482h2.118v-.482Zm18.93-11.21h-7.543l-1.354 1.284v-.325l1.36-1.274h7.565l-.028.314Zm-7.565.894h6.223l-.492.325H38.19l-1.332 1.187v-.314l1.332-1.198Zm0 1.111h4.547l-.775.515H38.19l-1.36 1.084v-.542l1.36-1.057Zm0 1.892-1.36.976v-.515l1.36-.976h2.489l-.775.542-1.714-.027Zm0 1.382-1.332.89v-.516l1.36-.878-.028.504Zm0-7.746 3.597 1.014H38.19l-1.332 1.43v-.932l1.332-1.512Zm-11.364 15.72h-2.118v.483h2.118v-.482Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default ComplexIcon;
|
||||
@@ -0,0 +1,28 @@
|
||||
function InfrastructureIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={20}
|
||||
height={20}
|
||||
fill="none"
|
||||
// {...props}
|
||||
>
|
||||
<g clipPath="url(#a)">
|
||||
<path
|
||||
stroke="#fff"
|
||||
strokeLinecap="square"
|
||||
strokeWidth={1.5}
|
||||
d="M2 17.53h1m0 0h8m-8 0V4.5h5.75M11 17.53h5v-3.89h-5m0 3.89v-3.89m0-4.39v4.39M5.5 7.5h2M5.5 10.5h3M5.5 13.5h3M9.804 3.315A3.548 3.548 0 0 0 9.5 4.75c0 3.5 4 6.25 4 6.25s4-2.75 4-6.25c0-.492-.104-.98-.305-1.435a3.743 3.743 0 0 0-.867-1.217 4.027 4.027 0 0 0-1.297-.813 4.232 4.232 0 0 0-3.062 0 4.027 4.027 0 0 0-1.297.813 3.743 3.743 0 0 0-.868 1.217Z"
|
||||
/>
|
||||
<circle cx={13.5} cy={5} r={1.5} fill="#fff" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path fill="#fff" d="M0 0h20v20H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default InfrastructureIcon;
|
||||
@@ -0,0 +1,20 @@
|
||||
function ParkIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={20}
|
||||
height={20}
|
||||
fill="none"
|
||||
// {...props}
|
||||
>
|
||||
<path
|
||||
stroke="#fff"
|
||||
strokeLinecap="square"
|
||||
strokeWidth={1.5}
|
||||
d="M10 19v-6.5m0 0L7.5 10m2.5 2.5v-2m0 0V5m0 5.5 2-2m-2.511 6.427a2.335 2.335 0 0 1-.415.392 3.5 3.5 0 0 1-4.942-4.826c.175-.249.149-.604-.096-.784l-.065-.047A3 3 0 0 1 6.037 4.92c.26-.032.485-.221.513-.482l.009-.077a3.5 3.5 0 0 1 5.755-1.988c.517.456.911 1.334 1.098 2.089.062.247.281.427.534.456a3 3 0 0 1 2.108 4.707l-.106.081c-.238.183-.26.531-.087.777a3.487 3.487 0 0 1 .626 1.716 3.5 3.5 0 0 1-5.561 3.12 2.336 2.336 0 0 1-.415-.393.676.676 0 0 0-1.022 0Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default ParkIcon;
|
||||
@@ -0,0 +1,27 @@
|
||||
function StylobateIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={20}
|
||||
height={20}
|
||||
fill="none"
|
||||
// {...props}
|
||||
>
|
||||
<path
|
||||
stroke="#fff"
|
||||
strokeLinecap="square"
|
||||
strokeWidth={1.5}
|
||||
d="M6 16.53H2V2l4 2v12.53Zm0 0h7.752m0-11.086L18 4.5v12.03h-4.248m0 0V12.5"
|
||||
/>
|
||||
<path
|
||||
stroke="#fff"
|
||||
strokeLinecap="square"
|
||||
strokeWidth={1.5}
|
||||
d="M8.266 7.083A3.27 3.27 0 0 0 8 8.375C8 11.525 11.5 14 11.5 14S15 11.525 15 8.375c0-.443-.09-.882-.266-1.292a3.37 3.37 0 0 0-.76-1.094 3.512 3.512 0 0 0-1.135-.732 3.613 3.613 0 0 0-2.678 0c-.425.17-.81.418-1.136.732a3.37 3.37 0 0 0-.759 1.094Z"
|
||||
/>
|
||||
<circle cx={11.5} cy={8.5} r={1.5} fill="#fff" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default StylobateIcon;
|
||||
@@ -0,0 +1,28 @@
|
||||
const MarkSportIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
x={9.5}
|
||||
y={9.5}
|
||||
width="45"
|
||||
height="45"
|
||||
viewBox="0 0 45 45"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_177_12572)">
|
||||
<path
|
||||
d="M18.5222 26.4775L26.4772 18.5226M34.631 10.3688L36.6198 8.38002M8.37968 36.6201L10.3684 34.6314M18.5222 8.97656L24.8862 2.61267L42.3871 20.1136L36.0231 26.4775L18.5222 8.97656ZM2.61233 24.8865L8.97629 18.5226L26.4772 36.0235L20.1132 42.3874L2.61233 24.8865Z"
|
||||
stroke="white"
|
||||
stroke-width="2.8125"
|
||||
stroke-linecap="square"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_177_12572">
|
||||
<rect width="45" height="45" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
export { MarkSportIcon };
|
||||
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"id": "Dvor_0",
|
||||
"src": "/images/Dvor/Panoram_Dvor.0001.jpg",
|
||||
"src": "/images/Dvor/Panoram_Dvor.0000.jpg",
|
||||
"position": [-23.12, 0, -13.4],
|
||||
"links": [
|
||||
{ "toId": "Dvor_16", "label": "" },
|
||||
@@ -121,8 +121,8 @@
|
||||
"src": "/images/Dvor/Panoram_Dvor.0012.jpg",
|
||||
"position": [-122.41, 0, -66.02],
|
||||
"links": [
|
||||
{ "toId": "Dvor_11", "label": "" },
|
||||
{ "toId": "Dvor_13", "label": "" }
|
||||
{ "toId": "Dvor_13", "label": "" },
|
||||
{ "toId": "Hall_5", "label": "Лифты" }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -180,13 +180,13 @@
|
||||
{
|
||||
"id": "Hall_0",
|
||||
"icon": "Elevator",
|
||||
"src": "/images/Hall/NKS_360_Hall00.jpg",
|
||||
"src": "/images/Hall/NKS_360_Lobby_0.jpg",
|
||||
"position": [-103.29, 0, -67.74],
|
||||
"links": [{ "toId": "Hall_5", "label": "Лифты" }]
|
||||
},
|
||||
{
|
||||
"id": "Hall_2",
|
||||
"src": "/images/Hall/NKS_360_Hall02.jpg",
|
||||
"src": "/images/Hall/NKS_360_Lobby_2.jpg",
|
||||
"position": [-104.21, 0, -76.41],
|
||||
"links": [
|
||||
{ "toId": "Hall_4", "label": "Лифты" },
|
||||
@@ -196,7 +196,7 @@
|
||||
{
|
||||
"id": "Hall_4",
|
||||
"icon": "Elevator",
|
||||
"src": "/images/Hall/NKS_360_Hall04.jpg",
|
||||
"src": "/images/Hall/NKS_360_Lobby_4.jpg",
|
||||
"position": [-109.93, 0, -74.76],
|
||||
"links": [
|
||||
{ "toId": "Hall_5", "label": "Лифты" },
|
||||
@@ -206,16 +206,17 @@
|
||||
{
|
||||
"id": "Hall_5",
|
||||
"icon": "Elevator",
|
||||
"src": "/images/Hall/NKS_360_Hall05.jpg",
|
||||
"src": "/images/Hall/NKS_360_Lobby_5.jpg",
|
||||
"position": [-108.74, 0, -66.61],
|
||||
"links": [
|
||||
{ "toId": "Hall_0", "label": "Лифты" },
|
||||
{ "toId": "Hall_4", "label": "Лифты" }
|
||||
{ "toId": "Hall_4", "label": "Лифты" },
|
||||
{ "toId": "Dvor_12", "label": "" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Hall_1",
|
||||
"src": "/images/Hall/NKS_360_Hall01.jpg",
|
||||
"src": "/images/Hall/NKS_360_Lobby_1.jpg",
|
||||
"position": [-6.51, 0, 26.3],
|
||||
"links": [
|
||||
{ "toId": "Hall_3", "label": "Лифты" },
|
||||
@@ -225,7 +226,7 @@
|
||||
{
|
||||
"id": "Hall_3",
|
||||
"icon": "Elevator",
|
||||
"src": "/images/Hall/NKS_360_Hall03.jpg",
|
||||
"src": "/images/Hall/NKS_360_Lobby_3.jpg",
|
||||
"position": [7.94, 0, 23.95],
|
||||
"links": [{ "toId": "Hall_1", "label": "Лобби" }]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
[
|
||||
{
|
||||
"id": "Niz_Dvor_1",
|
||||
"src": "/images/NizDvor/NKS_360_NizDvor01.jpg",
|
||||
"position": [-135.4, 0, -62.6],
|
||||
"links": [
|
||||
{ "toId": "Niz_Dvor_6", "label": "" },
|
||||
{ "toId": "Niz_Dvor_2", "label": "" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Niz_Dvor_2",
|
||||
"src": "/images/NizDvor/NKS_360_NizDvor02.jpg",
|
||||
"position": [-46.7, 0, 7.7],
|
||||
"links": [
|
||||
{ "toId": "Niz_Dvor_1", "label": "" },
|
||||
{ "toId": "Niz_Dvor_3", "label": "" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Niz_Dvor_3",
|
||||
"src": "/images/NizDvor/NKS_360_NizDvor03.jpg",
|
||||
"position": [-0.8, 0, 54.2],
|
||||
"links": [
|
||||
{ "toId": "Niz_Dvor_2", "label": "" },
|
||||
{ "toId": "Niz_Dvor_4", "label": "" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Niz_Dvor_4",
|
||||
"src": "/images/NizDvor/NKS_360_NizDvor04.jpg",
|
||||
"position": [60.5, 0, 22.7],
|
||||
"links": [
|
||||
{ "toId": "Niz_Dvor_3", "label": "" },
|
||||
{ "toId": "Niz_Dvor_5", "label": "" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Niz_Dvor_5",
|
||||
"src": "/images/NizDvor/NKS_360_NizDvor05.jpg",
|
||||
"position": [3.3, 0, -24.9],
|
||||
"links": [
|
||||
{ "toId": "Niz_Dvor_4", "label": "" },
|
||||
{ "toId": "Niz_Dvor_0", "label": "" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Niz_Dvor_0",
|
||||
"src": "/images/NizDvor/NKS_360_NizDvor00.jpg",
|
||||
"position": [-61.9, 0, -76.4],
|
||||
"links": [
|
||||
{ "toId": "Niz_Dvor_5", "label": "" },
|
||||
{ "toId": "Niz_Dvor_6", "label": "" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Niz_Dvor_6",
|
||||
"src": "/images/NizDvor/NKS_360_NizDvor06.jpg",
|
||||
"position": [-119.7, 0, -121.6],
|
||||
"links": [
|
||||
{ "toId": "Niz_Dvor_0", "label": "" },
|
||||
{ "toId": "Niz_Dvor_1", "label": "" }
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -29,3 +29,37 @@ body {
|
||||
.exited {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
}
|
||||
::-webkit-scrollbar-button {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #e1e1e1;
|
||||
border: 0px none #ffffff;
|
||||
border-radius: 50px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #ffffff;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:active {
|
||||
background: #000000;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #666666;
|
||||
border: 0px none #ffffff;
|
||||
border-radius: 50px;
|
||||
}
|
||||
::-webkit-scrollbar-track:hover {
|
||||
background: #666666;
|
||||
}
|
||||
::-webkit-scrollbar-track:active {
|
||||
background: #333333;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||
import VirtualTourPage from "./pages/VirtualTourPage.tsx";
|
||||
import MainPage from "./pages/MainPage.tsx";
|
||||
import Infra2Page from "./pages/Infra2Page.tsx";
|
||||
import VirtualTour2Page from "./pages/VirtualTour2Page.tsx";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
@@ -14,6 +15,10 @@ const router = createBrowserRouter([
|
||||
path: "/virtual-tour",
|
||||
element: <VirtualTourPage />,
|
||||
},
|
||||
{
|
||||
path: "/virtual-tour-2",
|
||||
element: <VirtualTour2Page />,
|
||||
},
|
||||
{
|
||||
path: "/infra2",
|
||||
element: <Infra2Page />,
|
||||
|
||||
@@ -350,5 +350,205 @@
|
||||
"y": 1080,
|
||||
"icon": "education",
|
||||
"distance": 500
|
||||
},
|
||||
{
|
||||
"id": "education_6",
|
||||
"label": "Гимназия №9",
|
||||
"x": 1620,
|
||||
"y": 940,
|
||||
"icon": "education",
|
||||
"distance": 800
|
||||
},
|
||||
{
|
||||
"id": "education_7",
|
||||
"label": "УрФУ ИНЭУ",
|
||||
"x": 1360,
|
||||
"y": 1230,
|
||||
"icon": "education",
|
||||
"distance": 500
|
||||
},
|
||||
{
|
||||
"id": "education_8",
|
||||
"label": "Империя",
|
||||
"x": 1320,
|
||||
"y": 1280,
|
||||
"icon": "education",
|
||||
"distance": 500
|
||||
},
|
||||
{
|
||||
"id": "education_9",
|
||||
"label": "Гимназия №2",
|
||||
"x": 1080,
|
||||
"y": 1350,
|
||||
"icon": "education",
|
||||
"distance": 400
|
||||
},
|
||||
{
|
||||
"id": "education_10",
|
||||
"label": "Детский сад №472",
|
||||
"x": 730,
|
||||
"y": 1180,
|
||||
"icon": "education",
|
||||
"distance": 500
|
||||
},
|
||||
{
|
||||
"id": "education_11",
|
||||
"label": "Детский сад №251",
|
||||
"x": 760,
|
||||
"y": 1120,
|
||||
"icon": "education",
|
||||
"distance": 400
|
||||
},
|
||||
{
|
||||
"id": "education_12",
|
||||
"label": "Детский сад №252 Кораблик",
|
||||
"x": 550,
|
||||
"y": 1110,
|
||||
"icon": "education",
|
||||
"distance": 700
|
||||
},
|
||||
{
|
||||
"id": "education_13",
|
||||
"label": "Детский сад №414",
|
||||
"x": 640,
|
||||
"y": 1310,
|
||||
"icon": "education",
|
||||
"distance": 700
|
||||
},
|
||||
{
|
||||
"id": "sport_1",
|
||||
"label": "Clinch",
|
||||
"x": 700,
|
||||
"y": 1130,
|
||||
"icon": "sport",
|
||||
"distance": 500
|
||||
},
|
||||
{
|
||||
"id": "sport_2",
|
||||
"label": "Точка",
|
||||
"x": 970,
|
||||
"y": 1180,
|
||||
"icon": "sport",
|
||||
"distance": 250
|
||||
},
|
||||
{
|
||||
"id": "sport_3",
|
||||
"label": "Aversfit",
|
||||
"x": 1160,
|
||||
"y": 1220,
|
||||
"icon": "sport",
|
||||
"distance": 300
|
||||
},
|
||||
{
|
||||
"id": "sport_4",
|
||||
"label": "Локомотив-изумруд",
|
||||
"x": 1260,
|
||||
"y": 1320,
|
||||
"icon": "sport",
|
||||
"distance": 450
|
||||
},
|
||||
{
|
||||
"id": "sport_5",
|
||||
"label": "Powerhouse Gym",
|
||||
"x": 1470,
|
||||
"y": 1340,
|
||||
"icon": "sport",
|
||||
"distance": 700
|
||||
},
|
||||
{
|
||||
"id": "sport_6",
|
||||
"label": "Бассейн Дворца Молодежи",
|
||||
"x": 1030,
|
||||
"y": 1450,
|
||||
"icon": "sport",
|
||||
"distance": 550
|
||||
},
|
||||
{
|
||||
"id": "sport_7",
|
||||
"label": "Happy Gymnastic",
|
||||
"x": 660,
|
||||
"y": 1230,
|
||||
"icon": "sport",
|
||||
"distance": 600
|
||||
},
|
||||
{
|
||||
"id": "sport_8",
|
||||
"label": "Encore Fitness",
|
||||
"x": 1100,
|
||||
"y": 910,
|
||||
"icon": "sport",
|
||||
"distance": 250
|
||||
},
|
||||
{
|
||||
"id": "sport_9",
|
||||
"label": "Реформа",
|
||||
"x": 1090,
|
||||
"y": 790,
|
||||
"icon": "sport",
|
||||
"distance": 400
|
||||
},
|
||||
{
|
||||
"id": "sport_10",
|
||||
"label": "Topstretching",
|
||||
"x": 1010,
|
||||
"y": 820,
|
||||
"icon": "sport",
|
||||
"distance": 350
|
||||
},
|
||||
{
|
||||
"id": "sport_11",
|
||||
"label": "Динамо",
|
||||
"x": 1410,
|
||||
"y": 580,
|
||||
"icon": "sport",
|
||||
"distance": 850
|
||||
},
|
||||
{
|
||||
"id": "sport_12",
|
||||
"label": "ДИВС",
|
||||
"x": 1050,
|
||||
"y": 570,
|
||||
"icon": "sport",
|
||||
"distance": 650
|
||||
},
|
||||
{
|
||||
"id": "sport_13",
|
||||
"label": "New Fit",
|
||||
"x": 1250,
|
||||
"y": 990,
|
||||
"icon": "sport",
|
||||
"distance": 400
|
||||
},
|
||||
{
|
||||
"id": "sport_14",
|
||||
"label": "Облака",
|
||||
"x": 1360,
|
||||
"y": 1030,
|
||||
"icon": "sport",
|
||||
"distance": 450
|
||||
},
|
||||
{
|
||||
"id": "sport_15",
|
||||
"label": "Bright Fit",
|
||||
"x": 1540,
|
||||
"y": 1200,
|
||||
"icon": "sport",
|
||||
"distance": 700
|
||||
},
|
||||
{
|
||||
"id": "sport_15",
|
||||
"label": "Bright Fit",
|
||||
"x": 1540,
|
||||
"y": 1200,
|
||||
"icon": "sport",
|
||||
"distance": 700
|
||||
},
|
||||
{
|
||||
"id": "sport_16",
|
||||
"label": "Bright Fit",
|
||||
"x": 1540,
|
||||
"y": 1200,
|
||||
"icon": "sport",
|
||||
"distance": 700
|
||||
}
|
||||
]
|
||||
|
||||
@@ -6,15 +6,18 @@ import DistanceCircle from "../components/DistanceCircle";
|
||||
import Button from "../components/Button";
|
||||
import InfrastructureFilters from "../components/InfrastructurePage/InfrastructureFilters";
|
||||
import ArrowLeftIcon from "../components/icons/ArrowLeftIcon";
|
||||
import CrossIcon from "../components/icons/CrossIcon";
|
||||
// import CrossIcon from "../components/icons/CrossIcon";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import ComplexIcon from "../components/icons/ComplexIcon";
|
||||
|
||||
const marks = _marks as Mark[];
|
||||
|
||||
function Infra2Page() {
|
||||
const [selectedRange, setSelectedRange] = useState<number>(800);
|
||||
const [selectedRange, setSelectedRange] = useState<number>(850);
|
||||
const [width, setWidth] = useState<number>();
|
||||
const [top, setTop] = useState<number>();
|
||||
const [filteredMarks, setFilteredMarks] = useState(marks);
|
||||
const navigate = useNavigate();
|
||||
|
||||
function handleResize() {
|
||||
setWidth(window.innerWidth);
|
||||
@@ -44,11 +47,11 @@ function Infra2Page() {
|
||||
|
||||
<DistanceCircle selectedRange={selectedRange} />
|
||||
</div>
|
||||
<div className="absolute h-full top-0 left-0 z-[99999999] w-[260px] bg-[#002347] bg-opacity-90 select-none px-6 py-5 flex flex-col justify-between gap-8">
|
||||
<div className="absolute h-screen overflow-y-auto top-0 left-0 z-[99999999] w-[260px] bg-[#002347] bg-opacity-90 select-none px-6 py-5 flex flex-col justify-between gap-8">
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex justify-end">
|
||||
{/* <div className="flex justify-end">
|
||||
<CrossIcon />
|
||||
</div>
|
||||
</div> */}
|
||||
<InfrastructureFilters
|
||||
setFilteredMarks={setFilteredMarks}
|
||||
setSelectedRange={setSelectedRange}
|
||||
@@ -56,7 +59,15 @@ function Infra2Page() {
|
||||
selectedRange={selectedRange}
|
||||
/>
|
||||
</div>
|
||||
<Button text="Генплан" icon={<ArrowLeftIcon />} widthFull />
|
||||
<Button
|
||||
text="Генплан"
|
||||
icon={<ArrowLeftIcon />}
|
||||
widthFull
|
||||
onClick={() => navigate("/")}
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute top-0 left-0 w-full h-full flex items-center justify-center">
|
||||
<ComplexIcon />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,36 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Button from "../components/Button";
|
||||
import SequenceSlider from "../components/SequenceSlider";
|
||||
import InfrastructureIcon from "../components/icons/InfrastructureIcon";
|
||||
import ParkIcon from "../components/icons/ParkIcon";
|
||||
import StylobateIcon from "../components/icons/StylobateIcon";
|
||||
|
||||
function MainPage() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="h-screen touch-none">
|
||||
<SequenceSlider path="/images/seq" />
|
||||
|
||||
<div className="absolute xl:left-8 left-4 xl:bottom-8 bottom-4 z-10">
|
||||
<div className="flex gap-3">
|
||||
<Button
|
||||
text="Стилобат"
|
||||
icon={<StylobateIcon />}
|
||||
onClick={() => navigate("/virtual-tour")}
|
||||
/>
|
||||
<Button
|
||||
text="Двор комплекса"
|
||||
icon={<ParkIcon />}
|
||||
onClick={() => navigate("/virtual-tour-2")}
|
||||
/>
|
||||
<Button
|
||||
text="Инфраструктура"
|
||||
icon={<InfrastructureIcon />}
|
||||
onClick={() => navigate("/infra2")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { Html, OrbitControls } from "@react-three/drei";
|
||||
import { Suspense, useRef, useState } from "react";
|
||||
import { OrbitControls as OrbitControlsImpl } from "three-stdlib";
|
||||
import { useFullscreen } from "ahooks";
|
||||
import SphereTour from "../components/SphereTour";
|
||||
import PointButton from "../components/PointButton";
|
||||
import WalkIcon from "../components/icons/WalkIcon";
|
||||
import Button from "../components/Button";
|
||||
import ArrowLeftIcon from "../components/icons/ArrowLeftIcon";
|
||||
import FullscreenIcon from "../components/icons/FullscreenIcon";
|
||||
import WindowModeIcon from "../components/icons/WindowModeIcon";
|
||||
import _images from "../images2.json";
|
||||
import Image from "../types/Image";
|
||||
import ElevatorIcon from "../components/icons/ElevatorIcon";
|
||||
import Loader from "../components/Loader";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { isIOS } from "react-device-detect";
|
||||
|
||||
const images = _images as Image[];
|
||||
|
||||
function VirtualTour2Page() {
|
||||
const [selectedImageId, setSelectedImageId] = useState<string>(images[0].id);
|
||||
const orbitRef = useRef<OrbitControlsImpl>(null);
|
||||
const fullscreenRef = useRef<HTMLDivElement>(null);
|
||||
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
|
||||
const navigate = useNavigate();
|
||||
|
||||
function handleSelectImageId(toId: string) {
|
||||
setSelectedImageId(toId);
|
||||
console.log(toId);
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={fullscreenRef} className="h-screen bg-black">
|
||||
<div className="absolute xl:left-8 left-4 xl:bottom-8 bottom-4 z-[99999999]">
|
||||
<Button
|
||||
text="Генплан"
|
||||
icon={<ArrowLeftIcon />}
|
||||
widthFull
|
||||
onClick={() => navigate("/")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{!isIOS && (
|
||||
<div className="absolute xl:top-8 top-4 xl:right-8 right-4 z-[99999999] select-none">
|
||||
<Button
|
||||
text="Во весь экран"
|
||||
icon={isFullscreen ? <WindowModeIcon /> : <FullscreenIcon />}
|
||||
onClick={toggleFullscreen}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Canvas camera={{ fov: 65 }}>
|
||||
<Suspense fallback={<Loader />}>
|
||||
<ambientLight intensity={2.5} />
|
||||
|
||||
{images.map((image) => (
|
||||
<>
|
||||
{/* <SphereTour key={index} src={image.src} position={image.position} /> */}
|
||||
|
||||
{image.id === selectedImageId &&
|
||||
image.links?.map((link, index) => (
|
||||
<Html
|
||||
key={index}
|
||||
position={
|
||||
images.find((image) => image.id === link.toId)?.position
|
||||
}
|
||||
center
|
||||
>
|
||||
<PointButton
|
||||
icon={
|
||||
images.find((image) => image.id === link.toId)?.icon ===
|
||||
"Elevator" ? (
|
||||
<ElevatorIcon />
|
||||
) : (
|
||||
<WalkIcon />
|
||||
)
|
||||
}
|
||||
label={link.label}
|
||||
onClick={() => handleSelectImageId(link.toId)}
|
||||
/>
|
||||
</Html>
|
||||
))}
|
||||
</>
|
||||
))}
|
||||
|
||||
{images.map((image) => (
|
||||
<SphereTour
|
||||
src={image.src}
|
||||
position={image.position}
|
||||
opacity={Number(image.id === selectedImageId)}
|
||||
/>
|
||||
))}
|
||||
|
||||
<OrbitControls
|
||||
ref={orbitRef}
|
||||
maxDistance={0.001}
|
||||
enableZoom={false}
|
||||
rotateSpeed={0.5}
|
||||
reverseOrbit
|
||||
target={
|
||||
images.find((image) => image.id === selectedImageId)?.position
|
||||
}
|
||||
/>
|
||||
</Suspense>
|
||||
</Canvas>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default VirtualTour2Page;
|
||||
@@ -14,6 +14,8 @@ import _images from "../images.json";
|
||||
import Image from "../types/Image";
|
||||
import ElevatorIcon from "../components/icons/ElevatorIcon";
|
||||
import Loader from "../components/Loader";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { isIOS } from "react-device-detect";
|
||||
|
||||
const images = _images as Image[];
|
||||
|
||||
@@ -22,6 +24,7 @@ function VirtualTourPage() {
|
||||
const orbitRef = useRef<OrbitControlsImpl>(null);
|
||||
const fullscreenRef = useRef<HTMLDivElement>(null);
|
||||
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
|
||||
const navigate = useNavigate();
|
||||
|
||||
function handleSelectImageId(toId: string) {
|
||||
setSelectedImageId(toId);
|
||||
@@ -30,43 +33,26 @@ function VirtualTourPage() {
|
||||
|
||||
return (
|
||||
<div ref={fullscreenRef} className="h-screen bg-black">
|
||||
<div className="absolute h-full top-0 left-0 z-[99999999] w-[260px] bg-[#002347] bg-opacity-90 select-none p-8 flex flex-col justify-between gap-8">
|
||||
<div className="flex flex-col gap-8">
|
||||
{selectedImageId.includes("Dvor") && (
|
||||
<>
|
||||
<h2 className="font-tenor text-2xl">
|
||||
Внутренний
|
||||
<br />
|
||||
двор
|
||||
</h2>
|
||||
<img src="/images/maps/Stilobat.svg" alt="" />
|
||||
</>
|
||||
)}
|
||||
{selectedImageId.includes("Lobby_1") && (
|
||||
<>
|
||||
<h2 className="font-tenor text-2xl">Лобби</h2>
|
||||
<img src="/images/maps/Lobby.svg" alt="" />
|
||||
</>
|
||||
)}
|
||||
{selectedImageId.includes("Lobby_2") && (
|
||||
<>
|
||||
<h2 className="font-tenor text-2xl">Лобби</h2>
|
||||
<img src="/images/maps/Lobby.svg" alt="" />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<Button text="Генплан" icon={<ArrowLeftIcon />} widthFull />
|
||||
</div>
|
||||
|
||||
<div className="absolute top-0 right-0 z-[99999999] px-10 py-6 select-none">
|
||||
<div className="absolute xl:left-8 left-4 xl:bottom-8 bottom-4 z-[99999999]">
|
||||
<Button
|
||||
text="Во весь экран"
|
||||
icon={isFullscreen ? <WindowModeIcon /> : <FullscreenIcon />}
|
||||
onClick={toggleFullscreen}
|
||||
text="Генплан"
|
||||
icon={<ArrowLeftIcon />}
|
||||
widthFull
|
||||
onClick={() => navigate("/")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Canvas>
|
||||
{!isIOS && (
|
||||
<div className="absolute xl:top-8 top-4 xl:right-8 right-4 z-[99999999] select-none">
|
||||
<Button
|
||||
text="Во весь экран"
|
||||
icon={isFullscreen ? <WindowModeIcon /> : <FullscreenIcon />}
|
||||
onClick={toggleFullscreen}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Canvas camera={{ fov: 65 }}>
|
||||
<Suspense fallback={<Loader />}>
|
||||
<ambientLight intensity={2.5} />
|
||||
|
||||
|
||||