upd
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 193 KiB |
|
Before Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 264 KiB |
|
Before Width: | Height: | Size: 267 KiB |
|
Before Width: | Height: | Size: 242 KiB |
|
Before Width: | Height: | Size: 194 KiB |
|
Before Width: | Height: | Size: 265 KiB |
|
Before Width: | Height: | Size: 287 KiB |
|
Before Width: | Height: | Size: 441 KiB |
|
Before Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 250 KiB |
|
Before Width: | Height: | Size: 241 KiB |
|
Before Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 5.0 MiB After Width: | Height: | Size: 540 KiB |
|
Before Width: | Height: | Size: 8.5 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 8.1 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 7.6 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 8.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 7.9 MiB After Width: | Height: | Size: 944 KiB |
|
Before Width: | Height: | Size: 7.9 MiB After Width: | Height: | Size: 1010 KiB |
|
Before Width: | Height: | Size: 7.8 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 7.4 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 7.5 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 7.4 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 7.8 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 7.7 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 7.8 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 7.8 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 7.9 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 7.9 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 8.2 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 7.5 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 8.7 MiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 7.4 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 7.8 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 8.6 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 526 KiB After Width: | Height: | Size: 480 KiB |
|
Before Width: | Height: | Size: 340 KiB After Width: | Height: | Size: 429 KiB |
@@ -16,8 +16,6 @@ function PointButton({ icon, label, onClick }: PointButtonProps) {
|
||||
{label}
|
||||
</div>
|
||||
)}
|
||||
{/* <div className="absolute h-20 w-0.5 bg-white top-[100%]"></div> */}
|
||||
{/* <div className="absolute top-[120px] w-1.5 h-1.5 bg-white rounded-full"></div> */}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ interface Props {
|
||||
onMouseLeave?: () => void;
|
||||
}
|
||||
|
||||
function MarkApartArea1({ x, y, onClick, onMouseEnter, onMouseLeave }: Props) {
|
||||
function MarkApartArea2({ x, y, onClick, onMouseEnter, onMouseLeave }: Props) {
|
||||
return (
|
||||
<svg
|
||||
x={x}
|
||||
@@ -82,4 +82,4 @@ function MarkApartArea1({ x, y, onClick, onMouseEnter, onMouseLeave }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
export default MarkApartArea1;
|
||||
export default MarkApartArea2;
|
||||
@@ -1,7 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
function Floor23() {
|
||||
return <div>Floor23</div>;
|
||||
}
|
||||
|
||||
export default Floor23;
|
||||
@@ -1,7 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
function Floor24() {
|
||||
return <div>Floor24</div>;
|
||||
}
|
||||
|
||||
export default Floor24;
|
||||
@@ -1,7 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
function Floor25() {
|
||||
return <div>Floor25</div>;
|
||||
}
|
||||
|
||||
export default Floor25;
|
||||
@@ -1,54 +0,0 @@
|
||||
interface Props {
|
||||
x: number;
|
||||
y: number;
|
||||
onClick: () => void;
|
||||
}
|
||||
function Floor26({ x, y, onClick }: Props) {
|
||||
return (
|
||||
<svg
|
||||
x={x}
|
||||
y={y}
|
||||
onClick={onClick}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={464}
|
||||
height={80}
|
||||
data-name="\u0421\u043B\u043E\u0439 2"
|
||||
className="group cursor-pointer"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M1 24c36.33 14.33 72.67 28.67 109 43 97.67 4.33 195.33 8.67 293 13 .67-9.33 1.33-18.67 2-28L109 37C72.67 24.67 36.33 12.33 0 0c.33 8 .67 16 1 24Z"
|
||||
style={{
|
||||
opacity: 0.5,
|
||||
}}
|
||||
className="fill-transparent group-hover:fill-[#0079c2] transition-all duration-300"
|
||||
/>
|
||||
<rect
|
||||
width={52}
|
||||
height={18}
|
||||
x={412}
|
||||
y={58}
|
||||
rx={4}
|
||||
ry={4}
|
||||
style={{
|
||||
fill: "#002347",
|
||||
}}
|
||||
/>
|
||||
<text
|
||||
style={{
|
||||
fill: "#fff",
|
||||
fontFamily: "Inter",
|
||||
fontSize: 10,
|
||||
}}
|
||||
transform="translate(416.68 71.2)"
|
||||
>
|
||||
<tspan x={0} y={0}>
|
||||
{"26 этаж"}
|
||||
</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default Floor26;
|
||||
@@ -1,54 +0,0 @@
|
||||
interface Props {
|
||||
x: number;
|
||||
y: number;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
function Floor27({ x, y, onClick }: Props) {
|
||||
return (
|
||||
<svg
|
||||
x={x}
|
||||
y={y}
|
||||
onClick={onClick}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={468}
|
||||
height={76}
|
||||
className="group cursor-pointer"
|
||||
>
|
||||
<path
|
||||
d="M2 24c36.33 12.33 72.67 24.67 109 37l296 15c.67-11.67 1.33-23.33 2-35-99.67-3.33-199.33-6.67-299-10C73.33 20.67 36.67 10.33 0 0c.67 8 1.33 16 2 24Z"
|
||||
data-name={27}
|
||||
style={{
|
||||
opacity: 0.5,
|
||||
}}
|
||||
className="fill-transparent group-hover:fill-[#0079c2] transition-all duration-300"
|
||||
/>
|
||||
<rect
|
||||
width={52}
|
||||
height={18}
|
||||
x={416}
|
||||
y={51}
|
||||
rx={4}
|
||||
ry={4}
|
||||
style={{
|
||||
fill: "#002347",
|
||||
strokeWidth: 0,
|
||||
}}
|
||||
/>
|
||||
<text
|
||||
style={{
|
||||
fill: "#fff",
|
||||
fontFamily: "Inter",
|
||||
fontSize: 10,
|
||||
}}
|
||||
transform="translate(420.68 64.2)"
|
||||
>
|
||||
<tspan x={0} y={0}>
|
||||
{"27 этаж"}
|
||||
</tspan>
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default Floor27;
|
||||
@@ -1,53 +0,0 @@
|
||||
interface Props {
|
||||
x: number;
|
||||
y: number;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
function Floor28({ x, y, onClick }: Props) {
|
||||
return (
|
||||
<svg
|
||||
x={x}
|
||||
y={y}
|
||||
onClick={onClick}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={472.19}
|
||||
height={73.29}
|
||||
className="group cursor-pointer"
|
||||
>
|
||||
<path
|
||||
d="M3.09 31.26c36.67 10.33 73.33 20.67 110 31 99.33 3.33 198.67 6.67 298 10 .67-13 1.33-26 2-39-100-2.67-200-5.33-300-8-37.34-8-74.67-16-112-24 .67 10 1.33 20 2 30Z"
|
||||
style={{
|
||||
opacity: 0.5,
|
||||
}}
|
||||
className="fill-transparent group-hover:fill-[#0079c2] transition-all duration-300"
|
||||
/>
|
||||
<rect
|
||||
width={52}
|
||||
height={18}
|
||||
x={420.19}
|
||||
y={45.6}
|
||||
rx={4}
|
||||
ry={4}
|
||||
style={{
|
||||
fill: "#002347",
|
||||
strokeWidth: 0,
|
||||
}}
|
||||
/>
|
||||
<text
|
||||
style={{
|
||||
fill: "#fff",
|
||||
fontFamily: "Inter",
|
||||
fontSize: 10,
|
||||
}}
|
||||
transform="translate(426 58)"
|
||||
>
|
||||
<tspan x={0} y={0}>
|
||||
{"28 этаж"}
|
||||
</tspan>
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default Floor28;
|
||||
@@ -1,15 +1,15 @@
|
||||
interface Point {
|
||||
id: string;
|
||||
id: string | number;
|
||||
mapPosition: [number, number];
|
||||
}
|
||||
|
||||
interface DvorMapProps {
|
||||
interface Props {
|
||||
points: Point[];
|
||||
selectedPointId?: string;
|
||||
onClick: (pointId: string) => void;
|
||||
selectedPointId?: string | number;
|
||||
onClick: (pointId: string | number) => void;
|
||||
}
|
||||
|
||||
function DvorMap({ points, selectedPointId, onClick }: DvorMapProps) {
|
||||
function DvorMap({ points, selectedPointId, onClick }: Props) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -175,7 +175,6 @@ function DvorMap({ points, selectedPointId, onClick }: DvorMapProps) {
|
||||
<g>
|
||||
{points.map((point) => (
|
||||
<circle
|
||||
id={point.id}
|
||||
cx={point.mapPosition[0]}
|
||||
cy={point.mapPosition[1]}
|
||||
r={4}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
interface Point {
|
||||
id: string;
|
||||
id: string | number;
|
||||
mapPosition: [number, number];
|
||||
}
|
||||
|
||||
interface DvorMapProps {
|
||||
points: Point[];
|
||||
selectedPointId?: string;
|
||||
onClick: (pointId: string) => void;
|
||||
selectedPointId?: string | number;
|
||||
onClick: (pointId: string | number) => void;
|
||||
}
|
||||
|
||||
function OuterDvorMap({ points, selectedPointId, onClick }: DvorMapProps) {
|
||||
@@ -34,7 +34,6 @@ function OuterDvorMap({ points, selectedPointId, onClick }: DvorMapProps) {
|
||||
<g>
|
||||
{points.map((point) => (
|
||||
<circle
|
||||
id={point.id}
|
||||
cx={point.mapPosition[0]}
|
||||
cy={point.mapPosition[1]}
|
||||
r={4}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
interface Point {
|
||||
id: string | number;
|
||||
mapPosition: [number, number];
|
||||
mapLabel?: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
points: Point[];
|
||||
selectedPointId?: string | number;
|
||||
onClick: (pointId: string | number) => void;
|
||||
}
|
||||
|
||||
function RHataMap({ points, selectedPointId, onClick }: Props) {
|
||||
return <div>RHataMap</div>;
|
||||
}
|
||||
|
||||
export default RHataMap;
|
||||
@@ -1,140 +1,168 @@
|
||||
[
|
||||
{
|
||||
"id": "R_Hata_0",
|
||||
"id": 0,
|
||||
"src": "/images/R_Hata/0.jpg",
|
||||
"position": [62.6, 0, 61.3],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 9 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_1",
|
||||
"id": 1,
|
||||
"src": "/images/R_Hata/1.jpg",
|
||||
"position": [97.6, 0, 31.6],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [
|
||||
{ "toId": 9 },
|
||||
{ "toId": 8 },
|
||||
{ "toId": 12 },
|
||||
{ "toId": 6 },
|
||||
{ "toId": 10 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_2",
|
||||
"id": 2,
|
||||
"src": "/images/R_Hata/2.jpg",
|
||||
"position": [68.4, 0, 10.5],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 8 }, { "toId": 3 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_3",
|
||||
"id": 3,
|
||||
"src": "/images/R_Hata/3.jpg",
|
||||
"position": [58.3, 0, 5.9],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 2 }, { "toId": 5 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_4",
|
||||
"id": 4,
|
||||
"src": "/images/R_Hata/4.jpg",
|
||||
"position": [133.1, 0, 30.8],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 6 }, { "toId": 13 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_5",
|
||||
"id": 5,
|
||||
"src": "/images/R_Hata/5.jpg",
|
||||
"position": [48.6, 0, -22.1],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 3 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_6",
|
||||
"id": 6,
|
||||
"src": "/images/R_Hata/6.jpg",
|
||||
"position": [115.1, 0, 28.1],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 1 }, { "toId": 10 }, { "toId": 12 }, { "toId": 4 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_7",
|
||||
"id": 7,
|
||||
"src": "/images/R_Hata/7.jpg",
|
||||
"position": [57.2, 0, 41],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 8 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_8",
|
||||
"id": 8,
|
||||
"src": "/images/R_Hata/8.jpg",
|
||||
"position": [74.9, 0, 30.5],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 1 }, { "toId": 7 }, { "toId": 2 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_9",
|
||||
"id": 9,
|
||||
"src": "/images/R_Hata/9.jpg",
|
||||
"position": [84.3, 0, 50.6],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 0 }, { "toId": 1 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_10",
|
||||
"id": 10,
|
||||
"src": "/images/R_Hata/10.jpg",
|
||||
"position": [111, 0, 42.2],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 11 }, { "toId": 1 }, { "toId": 6 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_11",
|
||||
"id": 11,
|
||||
"src": "/images/R_Hata/11.jpg",
|
||||
"position": [117.9, 0, 57.1],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 10 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_12",
|
||||
"id": 12,
|
||||
"src": "/images/R_Hata/12.jpg",
|
||||
"position": [103.9, 0, 11.5],
|
||||
"links": []
|
||||
"links": [{ "toId": 6 }, { "toId": 1 }, { "toId": 15 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_13",
|
||||
"id": 13,
|
||||
"src": "/images/R_Hata/13.jpg",
|
||||
"position": [149.7, 0, 38.3],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 4 }, { "toId": 14 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_14",
|
||||
"id": 14,
|
||||
"src": "/images/R_Hata/14.jpg",
|
||||
"position": [156.4, 0, 21],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 13 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_15",
|
||||
"id": 15,
|
||||
"src": "/images/R_Hata/15.jpg",
|
||||
"position": [89.4, 0, -2.5],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 12 }, { "toId": 16 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_16",
|
||||
"id": 16,
|
||||
"src": "/images/R_Hata/16.jpg",
|
||||
"position": [85.6, 0, -22.1],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 15 }, { "toId": 17 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_17",
|
||||
"id": 17,
|
||||
"src": "/images/R_Hata/17.jpg",
|
||||
"position": [106.4, 0, -26.3],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 16 }, { "toId": 18 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_18",
|
||||
"id": 18,
|
||||
"src": "/images/R_Hata/18.jpg",
|
||||
"position": [127.3, 0, -30.2],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 17 }, { "toId": 19 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_19",
|
||||
"id": 19,
|
||||
"src": "/images/R_Hata/19.jpg",
|
||||
"position": [138.9, 0, -16.2],
|
||||
"links": []
|
||||
"mapPosition": [0, 0],
|
||||
"links": [{ "toId": 18 }]
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_20",
|
||||
"id": 20,
|
||||
"src": "/images/R_Hata/20.jpg",
|
||||
"position": [118.1, 0, -10.2],
|
||||
"mapPosition": [0, 0],
|
||||
"links": []
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_21",
|
||||
"id": 21,
|
||||
"src": "/images/R_Hata/21.jpg",
|
||||
"position": [124.5, 0, 7.5],
|
||||
"mapPosition": [0, 0],
|
||||
"links": []
|
||||
},
|
||||
{
|
||||
"id": "R_Hata_22",
|
||||
"id": 22,
|
||||
"src": "/images/R_Hata/22.jpg",
|
||||
"position": [143.2, 0, 0.9],
|
||||
"mapPosition": [0, 0],
|
||||
"links": []
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,111 +1,201 @@
|
||||
[
|
||||
{
|
||||
"id": "L_Hata_0",
|
||||
"src": "/images/L_Hata/L_Hata_0.webp",
|
||||
"position": [-103.69, 0, -44.75],
|
||||
"links": [{ "toId": "L_Hata_9", "label": "Коридор" }]
|
||||
"id": 0,
|
||||
"src": "/images/L_Hata/0.jpg",
|
||||
"position": [-949.8, 0, -455],
|
||||
"mapPosition": [-4.4, 269.3],
|
||||
"links": [{ "toId": 9 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_1",
|
||||
"src": "/images/L_Hata/L_Hata_1.webp",
|
||||
"position": [-100.25, 0, -42.89],
|
||||
"id": 1,
|
||||
"src": "/images/L_Hata/1.jpg",
|
||||
"position": [-986.7, 0, -441.8],
|
||||
"mapPosition": [61.6, 257],
|
||||
"links": [{ "toId": 2 }, { "toId": 9 }]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"src": "/images/L_Hata/2.jpg",
|
||||
"position": [-1003.8, 0, -431.1],
|
||||
"mapPosition": [93.5, 243.2],
|
||||
"mapLabel": "Коридор",
|
||||
"links": [
|
||||
{ "toId": "L_Hata_9", "label": "Коридор" },
|
||||
{ "toId": "L_Hata_8", "label": "Санузел" },
|
||||
{ "toId": "L_Hata_7", "label": "Комната" },
|
||||
{ "toId": "L_Hata_2", "label": "Коридор" },
|
||||
{ "toId": "L_Hata_6", "label": "Комната" },
|
||||
{ "toId": "L_Hata_11", "label": "Комната" }
|
||||
{ "toId": 11 },
|
||||
{ "toId": 13 },
|
||||
{ "toId": 10 },
|
||||
{ "toId": 1 },
|
||||
{ "toId": 8 },
|
||||
{ "toId": 4 },
|
||||
{ "toId": 3 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_2",
|
||||
"src": "/images/L_Hata/L_Hata_2.webp",
|
||||
"position": [-98.79, 0, -40.85],
|
||||
"links": [
|
||||
{ "toId": "L_Hata_1", "label": "Коридор" },
|
||||
{ "toId": "L_Hata_3", "label": "Кухня" }
|
||||
]
|
||||
"id": 3,
|
||||
"src": "/images/L_Hata/3.jpg",
|
||||
"position": [-986.4, 0, -421.6],
|
||||
"mapPosition": [67.2, 221.7],
|
||||
"links": [{ "toId": 2 }, { "toId": 7 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_3",
|
||||
"src": "/images/L_Hata/L_Hata_3.webp",
|
||||
"position": [-95.06, 0, -38.66],
|
||||
"links": [
|
||||
{ "toId": "L_Hata_2", "label": "Коридор" },
|
||||
{ "toId": "L_Hata_4", "label": "Кухня" }
|
||||
]
|
||||
"id": 4,
|
||||
"src": "/images/L_Hata/4.jpg",
|
||||
"position": [-993.1, 0, -413.9],
|
||||
"mapPosition": [80.5, 210.3],
|
||||
"links": [{ "toId": 2 }, { "toId": 6 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_4",
|
||||
"src": "/images/L_Hata/L_Hata_4.webp",
|
||||
"position": [-95.07, 0, -35.38],
|
||||
"links": [
|
||||
{ "toId": "L_Hata_3", "label": "Кухня" },
|
||||
{ "toId": "L_Hata_5", "label": "Балкон" }
|
||||
]
|
||||
"id": 5,
|
||||
"src": "/images/L_Hata/5.jpg",
|
||||
"position": [-959.7, 0, -391.5],
|
||||
"mapPosition": [30.7, 162.2],
|
||||
"links": [{ "toId": 6 }, { "toId": 15 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_5",
|
||||
"src": "/images/L_Hata/L_Hata_5.webp",
|
||||
"position": [-92.78, 0, -31.67],
|
||||
"links": [{ "toId": "L_Hata_4", "label": "Комната" }]
|
||||
"id": 6,
|
||||
"src": "/images/L_Hata/6.jpg",
|
||||
"position": [-977.2, 0, -401.5],
|
||||
"mapPosition": [57.3, 184.7],
|
||||
"links": [{ "toId": 5 }, { "toId": 4 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_6",
|
||||
"src": "/images/L_Hata/L_Hata_6.webp",
|
||||
"position": [-95.91, 0, -42],
|
||||
"links": [{ "toId": "L_Hata_1", "label": "Коридор" }]
|
||||
"id": 7,
|
||||
"src": "/images/L_Hata/7.jpg",
|
||||
"position": [-966.3, 0, -421.8],
|
||||
"mapPosition": [33.4, 216.5],
|
||||
"mapLabel": "Спальня",
|
||||
"links": [{ "toId": 3 }, { "toId": 14 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_7",
|
||||
"src": "/images/L_Hata/L_Hata_7.webp",
|
||||
"position": [-97.47, 0, -44.71],
|
||||
"links": [{ "toId": "L_Hata_1", "label": "Коридор" }]
|
||||
"id": 8,
|
||||
"src": "/images/L_Hata/8.jpg",
|
||||
"position": [-1011.5, 0, -412.3],
|
||||
"mapPosition": [110.8, 212.8],
|
||||
"links": [{ "toId": 2 }, { "toId": 22 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_8",
|
||||
"src": "/images/L_Hata/L_Hata_8.webp",
|
||||
"position": [-100.68, 0, -45.16],
|
||||
"links": [{ "toId": "L_Hata_1", "label": "Коридор" }]
|
||||
"id": 9,
|
||||
"src": "/images/L_Hata/9.jpg",
|
||||
"position": [-966.6, 0, -443.7],
|
||||
"mapPosition": [26.2, 253.8],
|
||||
"mapLabel": "Спальня",
|
||||
"links": [{ "toId": 1 }, { "toId": 0 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_9",
|
||||
"src": "/images/L_Hata/L_Hata_9.webp",
|
||||
"position": [-102.13, 0, -43.45],
|
||||
"links": [
|
||||
{ "toId": "L_Hata_0", "label": "Прихожая" },
|
||||
{ "toId": "L_Hata_1", "label": "Коридор" }
|
||||
]
|
||||
"id": 10,
|
||||
"src": "/images/L_Hata/10.jpg",
|
||||
"position": [-1004.7, 0, -451.1],
|
||||
"mapPosition": [89.2, 277.9],
|
||||
"mapLabel": "Санузел",
|
||||
"links": [{ "toId": 2 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_10",
|
||||
"src": "/images/L_Hata/L_Hata_10.webp",
|
||||
"position": [-102.73, 0, -42.12],
|
||||
"links": []
|
||||
"id": 11,
|
||||
"src": "/images/L_Hata/11.jpg",
|
||||
"position": [-1025.2, 0, -439.3],
|
||||
"mapPosition": [127.2, 263.3],
|
||||
"links": [{ "toId": 12 }, { "toId": 2 }, { "toId": 13 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_11",
|
||||
"src": "/images/L_Hata/L_Hata_11.webp",
|
||||
"position": [-101.47, 0, -39.36],
|
||||
"links": [
|
||||
{ "toId": "L_Hata_1", "label": "Коридор" },
|
||||
{ "toId": "L_Hata_12", "label": "Комната" }
|
||||
]
|
||||
"id": 12,
|
||||
"src": "/images/L_Hata/12.jpg",
|
||||
"position": [-1044.1, 0, -454.4],
|
||||
"mapPosition": [154.6, 295],
|
||||
"links": [{ "toId": 11 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_12",
|
||||
"src": "/images/L_Hata/L_Hata_12.webp",
|
||||
"position": [-101.25, 0, -36.96],
|
||||
"links": [
|
||||
{ "toId": "L_Hata_11", "label": "Комната" },
|
||||
{ "toId": "L_Hata_13", "label": "Санузел" }
|
||||
]
|
||||
"id": 13,
|
||||
"src": "/images/L_Hata/13.jpg",
|
||||
"position": [-1027.7, 0, -422.2],
|
||||
"mapPosition": [136.3, 234.7],
|
||||
"links": [{ "toId": 11 }, { "toId": 2 }]
|
||||
},
|
||||
{
|
||||
"id": "L_Hata_13",
|
||||
"src": "/images/L_Hata/L_Hata_13.webp",
|
||||
"position": [-98.86, 0, -37.99],
|
||||
"links": [{ "toId": "L_Hata_12", "label": "Комната" }]
|
||||
"id": 14,
|
||||
"src": "/images/L_Hata/14.jpg",
|
||||
"position": [-946.4, 0, -423.2],
|
||||
"mapPosition": [-0.9, 213.3],
|
||||
"links": [{ "toId": 7 }]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"src": "/images/L_Hata/15.jpg",
|
||||
"position": [-952.5, 0, -372.7],
|
||||
"mapPosition": [23.8, 128],
|
||||
"mapLabel": "Гостиная",
|
||||
"links": [{ "toId": 5 }, { "toId": 19 }, { "toId": 16 }]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"src": "/images/L_Hata/16.jpg",
|
||||
"position": [-943.4, 0, -355.6],
|
||||
"mapPosition": [13.5, 95.9],
|
||||
"links": [{ "toId": 15 }, { "toId": 19 }, { "toId": 20 }, { "toId": 17 }]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"src": "/images/L_Hata/17.jpg",
|
||||
"position": [-933.1, 0, -339],
|
||||
"mapPosition": [1, 64.3],
|
||||
"links": [{ "toId": 16 }, { "toId": 20 }, { "toId": 18 }]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"src": "/images/L_Hata/18.jpg",
|
||||
"position": [-927.7, 0, -316.3],
|
||||
"mapPosition": [-1.4, 23.7],
|
||||
"mapLabel": "Лоджия",
|
||||
"links": [{ "toId": 17 }]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"src": "/images/L_Hata/19.jpg",
|
||||
"position": [-963.6, 0, -355.8],
|
||||
"mapPosition": [47.5, 101.9],
|
||||
"links": [{ "toId": 15 }, { "toId": 16 }, { "toId": 21 }, { "toId": 20 }]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"src": "/images/L_Hata/20.jpg",
|
||||
"position": [-952.4, 0, -334.2],
|
||||
"mapPosition": [34.9, 61.5],
|
||||
"mapLabel": "Кухня",
|
||||
"links": [{ "toId": 21 }, { "toId": 19 }, { "toId": 16 }, { "toId": 17 }]
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"src": "/images/L_Hata/21.jpg",
|
||||
"position": [-977.9, 0, -342],
|
||||
"mapPosition": [75.7, 82.1],
|
||||
"links": [{ "toId": 19 }, { "toId": 20 }]
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"src": "/images/L_Hata/22.jpg",
|
||||
"position": [-1016.7, 0, -391.4],
|
||||
"mapPosition": [126.9, 178.4],
|
||||
"mapLabel": "Спальня",
|
||||
"links": [{ "toId": 8 }, { "toId": 23 }]
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"src": "/images/L_Hata/23.jpg",
|
||||
"position": [-1015, 0, -369.6],
|
||||
"mapPosition": [130.2, 140.4],
|
||||
"links": [{ "toId": 22 }, { "toId": 24 }]
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"src": "/images/L_Hata/24.jpg",
|
||||
"position": [-994.2, 0, -373],
|
||||
"mapPosition": [94.2, 140.3],
|
||||
"links": [{ "toId": 23 }, { "toId": 25 }]
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"src": "/images/L_Hata/25.jpg",
|
||||
"position": [-985.6, 0, -384.3],
|
||||
"mapPosition": [76.3, 157.3],
|
||||
"mapLabel": "Санузел",
|
||||
"links": [{ "toId": 24 }]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Button from "../components/Button";
|
||||
import SequenceSlider from "../components/SequenceSlider";
|
||||
import { useFullscreen } from "ahooks";
|
||||
import InfrastructureIcon from "../components/icons/InfrastructureIcon";
|
||||
import { useRef } from "react";
|
||||
import FullscreenIcon from "../components/icons/FullscreenIcon";
|
||||
import WindowModeIcon from "../components/icons/WindowModeIcon";
|
||||
|
||||
function MainPage() {
|
||||
const fullscreenRef = useRef(null);
|
||||
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="h-screen touch-none">
|
||||
<div ref={fullscreenRef} className="h-screen touch-none select-none">
|
||||
<SequenceSlider
|
||||
path="/images/seq"
|
||||
onChange={(selectedImageIndex) =>
|
||||
@@ -14,13 +21,18 @@ function MainPage() {
|
||||
}
|
||||
/>
|
||||
|
||||
<div className="absolute xl:left-8 left-4 xl:bottom-8 bottom-4 z-50">
|
||||
<div className="absolute top-6 right-6 z-50">
|
||||
<div className="flex gap-3">
|
||||
<Button
|
||||
text="Инфраструктура"
|
||||
// icon={<InfrastructureIcon />}
|
||||
icon={<InfrastructureIcon />}
|
||||
onClick={() => navigate("/infra2")}
|
||||
/>
|
||||
<Button
|
||||
text="Во весь экран"
|
||||
icon={isFullscreen ? <WindowModeIcon /> : <FullscreenIcon />}
|
||||
onClick={toggleFullscreen}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useEffect, useState } from "react";
|
||||
import ArrowLeftIcon from "../components/icons/ArrowLeftIcon";
|
||||
import Button from "../components/Button";
|
||||
import { Transition } from "react-transition-group";
|
||||
import Tower1FloorPlan from "../components/Tower1FloorPlan";
|
||||
|
||||
function Tower1Page() {
|
||||
const [width, setWidth] = useState<number>();
|
||||
@@ -40,6 +41,22 @@ function Tower1Page() {
|
||||
className={`absolute select-none pointer-events-none`}
|
||||
onLoad={() => setIsLoaded(true)}
|
||||
/>
|
||||
|
||||
<svg
|
||||
width="1920"
|
||||
height="1920"
|
||||
viewBox="0 0 1920 1920"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute z-50 top-0 left-0 w-full h-full"
|
||||
>
|
||||
<Tower1FloorPlan
|
||||
x={730}
|
||||
y={565}
|
||||
// onClick={(floor) => console.log("floor", floor)}
|
||||
onClick={() => navigate("select")}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -142,28 +142,48 @@ function Tower1SelectPage() {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute z-50 top-0 left-0 w-full h-full"
|
||||
>
|
||||
{marks.map((mark) => {
|
||||
switch (mark.type) {
|
||||
case "lock":
|
||||
return (
|
||||
<MarkLockIcon x={mark.x as number} y={mark.y as number} />
|
||||
);
|
||||
case "apart":
|
||||
return (
|
||||
<MarkApartIcon
|
||||
x={mark.x as number}
|
||||
y={mark.y as number}
|
||||
text={mark.text as string}
|
||||
text2={mark.text2 as string}
|
||||
onClick={() => navigate(mark.url!)}
|
||||
/>
|
||||
);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
})}
|
||||
<MarkApartArea1
|
||||
x={1378}
|
||||
y={798}
|
||||
onClick={() => navigate("1")}
|
||||
onMouseEnter={() => setSelectedArea(1)}
|
||||
onMouseLeave={() => setSelectedArea(null)}
|
||||
/>
|
||||
<MarkLockIcon x={380} y={875} />
|
||||
<MarkLockIcon x={585} y={855} />
|
||||
<MarkLockIcon x={725} y={855} />
|
||||
<MarkLockIcon x={1140} y={855} />
|
||||
<MarkLockIcon x={1280} y={855} />
|
||||
<MarkLockIcon x={585} y={1100} />
|
||||
<MarkLockIcon x={800} y={1120} />
|
||||
<MarkLockIcon x={1070} y={1120} />
|
||||
<MarkLockIcon x={1280} y={1100} />
|
||||
</svg>
|
||||
|
||||
<div
|
||||
className={`w-[202px] h-[200px] bg-[#002347] absolute z-50 pointer-events-none p-5 flex flex-col gap-4 transition-opacity ${
|
||||
selectedArea ? "opacity-100" : "opacity-0"
|
||||
}`}
|
||||
style={{
|
||||
top: mousePos[1] + top - 200,
|
||||
left: mousePos[0],
|
||||
}}
|
||||
>
|
||||
<h2 className="font-tenor text-2xl leading-[26.4px]">
|
||||
3-комнатные апартаменты
|
||||
</h2>
|
||||
<p className="flex gap-1 text-sm">
|
||||
<span className="font-medium">Площадь</span>
|
||||
<span className="text-[#9595A2]">116.8 м²</span>
|
||||
</p>
|
||||
<hr className="border-[#0079C2] opacity-40" />
|
||||
<div className="flex flex-col">
|
||||
<p className="text-[#9595A2] text-sm">Стоимость</p>
|
||||
<p className="font-tenor text-xl">
|
||||
{/* {(7500600).toLocaleString("ru")} руб. */}- руб.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute left-8 bottom-8 z-50">
|
||||
<Button
|
||||
|
||||
@@ -5,6 +5,7 @@ import Button from "../components/Button";
|
||||
import { Transition } from "react-transition-group";
|
||||
import MarkTower1ApartSelectIcon from "../components/icons/marks/MarkTower1ApartSelectIcon";
|
||||
import MarkApartPoint from "../components/icons/marks/MarkApartPoint";
|
||||
import LHataMap from "../components/maps/LHataMap";
|
||||
|
||||
function Tower2ApartLauout() {
|
||||
const [width, setWidth] = useState<number>();
|
||||
@@ -24,77 +25,163 @@ function Tower2ApartLauout() {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="scene absolute w-full h-full overflow-hidden">
|
||||
<div
|
||||
className="absolute left-0"
|
||||
style={{
|
||||
width: `${width}px`,
|
||||
height: `${width}px`,
|
||||
top: `-${top}px`,
|
||||
}}
|
||||
>
|
||||
<img
|
||||
width={`${width}px`}
|
||||
height={`${width}px`}
|
||||
src="/images/Tower2/ApartLayout.jpg"
|
||||
alt=""
|
||||
className={`absolute select-none pointer-events-none`}
|
||||
onLoad={() => setIsLoaded(true)}
|
||||
/>
|
||||
<div className="scene absolute w-full h-full overflow-hidden">
|
||||
<div className="absolute top-0 left-0 w-[260px] min-h-screen bg-[#002347] bg-opacity-90 z-[99999999] p-7 flex flex-col justify-between">
|
||||
<div className="flex flex-col">
|
||||
<h2 className="font-tenor text-2xl mb-4">3-комнатные апартаменты</h2>
|
||||
<div className="flex flex-col mb-7">
|
||||
<p>
|
||||
<span className="font-medium">Башня</span>{" "}
|
||||
<span className="text-[#9595A2]">1</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Этаж</span>{" "}
|
||||
<span className="text-[#9595A2]">7-28</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Площадь</span>{" "}
|
||||
<span className="text-[#9595A2]">116.8 м²</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="self-center mb-7">
|
||||
<LHataMap />
|
||||
</div>
|
||||
<div className="mb-7">
|
||||
<p className="text-[#9595A2] text-sm leading-[18.2px]">
|
||||
Стоимость:
|
||||
</p>
|
||||
<p className="font-tenor text-lg leading-[23.4px]">- руб.</p>
|
||||
</div>
|
||||
<div className="mb-7">
|
||||
<p className="text-[#9595A2] text-sm leading-[18.2px]">Статус:</p>
|
||||
<p className="font-tenor text-lg leading-[23.4px]">В продаже</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<svg
|
||||
width="1920"
|
||||
height="1920"
|
||||
viewBox="0 0 1920 1920"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute z-50 top-0 left-0 w-full h-full"
|
||||
>
|
||||
<MarkTower1ApartSelectIcon
|
||||
x={486}
|
||||
y={716}
|
||||
onMouseEnter={function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
}}
|
||||
onMouseLeave={function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
}}
|
||||
/>
|
||||
<MarkApartPoint x={550} y={800} text="Спальня" text2="13.1 м²" />
|
||||
<MarkApartPoint x={705} y={790} text="Спальня" text2="14.2 м²" />
|
||||
<MarkApartPoint x={970} y={785} text="Гостиная" text2="31.5 м²" />
|
||||
<MarkApartPoint x={1100} y={805} text="Кухня" text2="31.5 м²" />
|
||||
<MarkApartPoint x={1270} y={720} text="Лоджия" text2="4.0 м²" />
|
||||
<MarkApartPoint x={515} y={985} text="Санузел" text2="5.2 м²" />
|
||||
<MarkApartPoint x={645} y={995} text="Коридор" text2="15.0 м²" />
|
||||
<MarkApartPoint x={870} y={980} text="Санузел" text2="5.8 м²" />
|
||||
<MarkApartPoint x={790} y={1115} text="Спальня" text2="17.4 м²" />
|
||||
</svg>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Button
|
||||
text="Начать 3D тур"
|
||||
widthFull
|
||||
onClick={() => navigate("/virtual-tour-4?id=2")}
|
||||
/>
|
||||
<Button
|
||||
text="Этажный план"
|
||||
icon={<ArrowLeftIcon />}
|
||||
widthFull
|
||||
onClick={() => navigate(-1)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="absolute left-8 bottom-8 z-50">
|
||||
<Button
|
||||
text="Этажный план"
|
||||
icon={<ArrowLeftIcon />}
|
||||
widthFull
|
||||
onClick={() => navigate(-1)}
|
||||
<div
|
||||
className="absolute left-0"
|
||||
style={{
|
||||
width: `${width}px`,
|
||||
height: `${width}px`,
|
||||
top: `-${top}px`,
|
||||
}}
|
||||
>
|
||||
<img
|
||||
width={`${width}px`}
|
||||
height={`${width}px`}
|
||||
src="/images/Tower2/ApartLayout.jpg"
|
||||
alt=""
|
||||
className={`absolute select-none pointer-events-none`}
|
||||
onLoad={() => setIsLoaded(true)}
|
||||
/>
|
||||
|
||||
<svg
|
||||
width="1920"
|
||||
height="1920"
|
||||
viewBox="0 0 1920 1920"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute z-50 top-0 left-0 w-full h-full"
|
||||
>
|
||||
<MarkTower1ApartSelectIcon
|
||||
x={486}
|
||||
y={716}
|
||||
onMouseEnter={function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
}}
|
||||
onMouseLeave={function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
}}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={550}
|
||||
y={800}
|
||||
text="Спальня"
|
||||
text2="13.1 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=9")}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={705}
|
||||
y={790}
|
||||
text="Спальня"
|
||||
text2="14.2 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=7")}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={970}
|
||||
y={785}
|
||||
text="Гостиная"
|
||||
text2="31.5 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=15")}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={1100}
|
||||
y={805}
|
||||
text="Кухня"
|
||||
text2="31.5 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=20")}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={1270}
|
||||
y={720}
|
||||
text="Лоджия"
|
||||
text2="4.0 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=18")}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={515}
|
||||
y={985}
|
||||
text="Санузел"
|
||||
text2="5.2 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=10")}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={645}
|
||||
y={995}
|
||||
text="Коридор"
|
||||
text2="15.0 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=2")}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={870}
|
||||
y={980}
|
||||
text="Санузел"
|
||||
text2="5.8 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=25")}
|
||||
/>
|
||||
<MarkApartPoint
|
||||
x={790}
|
||||
y={1115}
|
||||
text="Спальня"
|
||||
text2="17.4 м²"
|
||||
onClick={() => navigate("/virtual-tour-4?id=22")}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<Transition in={!isLoaded} timeout={300} mountOnEnter unmountOnExit>
|
||||
{(state) => (
|
||||
<div
|
||||
className={`absolute top-0 left-0 w-full h-full flex items-center justify-center bg-neutral-950 z-50 transition-opacity duration-300 ${state}`}
|
||||
>
|
||||
{/* <h2 className="text-2xl font-tenor text-white whitespace-nowrap">
|
||||
Загрузка...
|
||||
</h2> */}
|
||||
</div>
|
||||
className={`absolute w-full h-full bg-black z-[99999999] transition-opacity duration-300 ${state}`}
|
||||
></div>
|
||||
)}
|
||||
</Transition>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,20 +4,7 @@ import { useEffect, useState } from "react";
|
||||
import ArrowLeftIcon from "../components/icons/ArrowLeftIcon";
|
||||
import Button from "../components/Button";
|
||||
import { Transition } from "react-transition-group";
|
||||
import Floor28 from "../components/icons/marks/Tower2/Floor28";
|
||||
import Floor27 from "../components/icons/marks/Tower2/Floor27";
|
||||
import Floor26 from "../components/icons/marks/Tower2/Floor26";
|
||||
|
||||
// const marks: Mark[] = [
|
||||
// {
|
||||
// id: "1",
|
||||
// label: "Перейти к планировке",
|
||||
// icon: "layout",
|
||||
// x: 1000,
|
||||
// y: 800,
|
||||
// url: "/tower2/select",
|
||||
// },
|
||||
// ];
|
||||
import Tower2FloorPlan from "../components/Tower2FloorPlan";
|
||||
|
||||
function Tower2Page() {
|
||||
const [width, setWidth] = useState<number>();
|
||||
@@ -64,9 +51,12 @@ function Tower2Page() {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute z-50 top-0 left-0 w-full h-full"
|
||||
>
|
||||
<Floor28 x={729} y={663} onClick={() => navigate("select")} />
|
||||
<Floor27 x={730} y={693} onClick={() => navigate("select")} />
|
||||
<Floor26 x={732} y={717} onClick={() => navigate("select")} />
|
||||
<Tower2FloorPlan
|
||||
x={747}
|
||||
y={633}
|
||||
// onClick={(floor) => console.log("floor", floor)}
|
||||
onClick={() => navigate("select")}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ import ArrowLeftIcon from "../components/icons/ArrowLeftIcon";
|
||||
import Button from "../components/Button";
|
||||
import { Transition } from "react-transition-group";
|
||||
import MarkLockIcon from "../components/icons/marks/MarkLockIcon";
|
||||
import MarkApartArea1 from "../components/icons/marks/MarkApartArea1";
|
||||
import MarkApartArea2 from "../components/icons/marks/MarkApartArea2";
|
||||
|
||||
function Tower2SelectPage() {
|
||||
const [width, setWidth] = useState<number>(0);
|
||||
@@ -38,97 +38,95 @@ function Tower2SelectPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="scene absolute w-full h-full overflow-hidden">
|
||||
<div className="scene absolute w-full h-full overflow-hidden">
|
||||
<div
|
||||
className="absolute left-0"
|
||||
style={{
|
||||
width: `${width}px`,
|
||||
height: `${width}px`,
|
||||
top: `-${top}px`,
|
||||
}}
|
||||
>
|
||||
<img
|
||||
width={`${width}px`}
|
||||
height={`${width}px`}
|
||||
src="/images/Split_LTower.jpg"
|
||||
alt=""
|
||||
className=""
|
||||
onLoad={handleOnImageLoad}
|
||||
/>
|
||||
|
||||
<svg
|
||||
width="1920"
|
||||
height="1920"
|
||||
viewBox="0 0 1920 1920"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute z-50 top-0 left-0 w-full h-full"
|
||||
>
|
||||
<MarkApartArea2
|
||||
x={1378}
|
||||
y={798}
|
||||
onClick={() => navigate("1")}
|
||||
onMouseEnter={() => setSelectedArea(1)}
|
||||
onMouseLeave={() => setSelectedArea(null)}
|
||||
/>
|
||||
<MarkLockIcon x={380} y={875} />
|
||||
<MarkLockIcon x={585} y={855} />
|
||||
<MarkLockIcon x={725} y={855} />
|
||||
<MarkLockIcon x={1140} y={855} />
|
||||
<MarkLockIcon x={1280} y={855} />
|
||||
<MarkLockIcon x={585} y={1100} />
|
||||
<MarkLockIcon x={800} y={1120} />
|
||||
<MarkLockIcon x={1070} y={1120} />
|
||||
<MarkLockIcon x={1280} y={1100} />
|
||||
</svg>
|
||||
|
||||
<div
|
||||
className="absolute left-0"
|
||||
className={`w-[202px] h-[200px] bg-[#002347] absolute z-50 pointer-events-none p-5 flex flex-col gap-4 transition-opacity ${
|
||||
selectedArea ? "opacity-100" : "opacity-0"
|
||||
}`}
|
||||
style={{
|
||||
width: `${width}px`,
|
||||
height: `${width}px`,
|
||||
top: `-${top}px`,
|
||||
top: mousePos[1] + top - 200,
|
||||
left: mousePos[0],
|
||||
}}
|
||||
>
|
||||
<img
|
||||
width={`${width}px`}
|
||||
height={`${width}px`}
|
||||
src="/images/Split_LTower.jpg"
|
||||
alt=""
|
||||
className=""
|
||||
onLoad={handleOnImageLoad}
|
||||
/>
|
||||
|
||||
<svg
|
||||
width="1920"
|
||||
height="1920"
|
||||
viewBox="0 0 1920 1920"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute z-50 top-0 left-0 w-full h-full"
|
||||
>
|
||||
<MarkApartArea1
|
||||
x={1378}
|
||||
y={798}
|
||||
onClick={() => navigate("1")}
|
||||
onMouseEnter={() => setSelectedArea(1)}
|
||||
onMouseLeave={() => setSelectedArea(null)}
|
||||
/>
|
||||
<MarkLockIcon x={380} y={875} />
|
||||
<MarkLockIcon x={585} y={855} />
|
||||
<MarkLockIcon x={725} y={855} />
|
||||
<MarkLockIcon x={1140} y={855} />
|
||||
<MarkLockIcon x={1280} y={855} />
|
||||
<MarkLockIcon x={585} y={1100} />
|
||||
<MarkLockIcon x={800} y={1120} />
|
||||
<MarkLockIcon x={1070} y={1120} />
|
||||
<MarkLockIcon x={1280} y={1100} />
|
||||
</svg>
|
||||
|
||||
<div
|
||||
className={`w-[202px] h-[200px] bg-[#002347] absolute z-50 pointer-events-none p-5 flex flex-col gap-4 transition-opacity ${
|
||||
selectedArea ? "opacity-100" : "opacity-0"
|
||||
}`}
|
||||
style={{
|
||||
top: mousePos[1] + top - 200,
|
||||
left: mousePos[0],
|
||||
}}
|
||||
>
|
||||
<h2 className="font-tenor text-2xl leading-[26.4px]">
|
||||
2-комнатные апартаменты
|
||||
</h2>
|
||||
<p className="flex gap-1 text-sm">
|
||||
<span className="font-medium">Площадь</span>
|
||||
<span className="text-[#9595A2]">80 м²</span>
|
||||
<h2 className="font-tenor text-2xl leading-[26.4px]">
|
||||
3-комнатные апартаменты
|
||||
</h2>
|
||||
<p className="flex gap-1 text-sm">
|
||||
<span className="font-medium">Площадь</span>
|
||||
<span className="text-[#9595A2]">116.8 м²</span>
|
||||
</p>
|
||||
<hr className="border-[#0079C2] opacity-40" />
|
||||
<div className="flex flex-col">
|
||||
<p className="text-[#9595A2] text-sm">Стоимость</p>
|
||||
<p className="font-tenor text-xl">
|
||||
{/* {(7500600).toLocaleString("ru")} руб. */}- руб.
|
||||
</p>
|
||||
<hr className="border-[#0079C2] opacity-40" />
|
||||
<div className="flex flex-col">
|
||||
<p className="text-[#9595A2] text-sm">Стоимость</p>
|
||||
<p className="font-tenor text-xl">
|
||||
{(7500600).toLocaleString("ru")} руб.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute left-8 bottom-8 z-50">
|
||||
<Button
|
||||
text="Выбор этажа"
|
||||
icon={<ArrowLeftIcon />}
|
||||
widthFull
|
||||
onClick={() => navigate(-1)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute left-8 bottom-8 z-50">
|
||||
<Button
|
||||
text="Выбор этажа"
|
||||
icon={<ArrowLeftIcon />}
|
||||
widthFull
|
||||
onClick={() => navigate(-1)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Transition in={!isLoaded} timeout={300} mountOnEnter unmountOnExit>
|
||||
{(state) => (
|
||||
<div
|
||||
className={`absolute top-0 left-0 w-full h-full flex items-center justify-center bg-neutral-950 z-50 transition-opacity duration-300 ${state}`}
|
||||
>
|
||||
{/* <h2 className="text-2xl font-tenor text-white whitespace-nowrap">
|
||||
<Transition in={!isLoaded} timeout={300} mountOnEnter unmountOnExit>
|
||||
{(state) => (
|
||||
<div
|
||||
className={`absolute top-0 left-0 w-full h-full flex items-center justify-center bg-neutral-950 z-50 transition-opacity duration-300 ${state}`}
|
||||
>
|
||||
{/* <h2 className="text-2xl font-tenor text-white whitespace-nowrap">
|
||||
Загрузка...
|
||||
</h2> */}
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@ import OuterDvorMap from "../components/maps/OuterDvorMap";
|
||||
const images = _images as Image[];
|
||||
|
||||
function VirtualTour2Page() {
|
||||
const [selectedImageId, setSelectedImageId] = useState<string>(images[0].id);
|
||||
const [selectedImageId, setSelectedImageId] = useState<string | number>(images[0].id);
|
||||
const orbitRef = useRef<OrbitControlsImpl>(null);
|
||||
const fullscreenRef = useRef<HTMLDivElement>(null);
|
||||
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
|
||||
const navigate = useNavigate();
|
||||
const [selectedPointId, setSelectedPointId] = useState<string>(images[0].id);
|
||||
const [selectedPointId, setSelectedPointId] = useState<string | number>(selectedImageId);
|
||||
|
||||
function handleSelectImageId(toId: string) {
|
||||
function handleSelectImageId(toId: string | number) {
|
||||
setSelectedImageId(toId);
|
||||
setSelectedPointId(toId);
|
||||
console.log(toId);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { Html, OrbitControls } from "@react-three/drei";
|
||||
import { Suspense, useEffect, useRef, useState } from "react";
|
||||
import { Suspense, useRef, useState } from "react";
|
||||
import { OrbitControls as OrbitControlsImpl } from "three-stdlib";
|
||||
import { useFullscreen } from "ahooks";
|
||||
import SphereTour from "../components/SphereTour";
|
||||
@@ -14,32 +14,54 @@ import _images from "../images3.json";
|
||||
import Image from "../types/Image";
|
||||
import ElevatorIcon from "../components/icons/ElevatorIcon";
|
||||
import Loader from "../components/Loader";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { isIOS } from "react-device-detect";
|
||||
import RHataMap from "../components/maps/RHataMap";
|
||||
|
||||
const images = _images as unknown as Image[];
|
||||
|
||||
function VirtualTour3Page() {
|
||||
const [selectedImageId, setSelectedImageId] = useState<string>(images[19].id);
|
||||
const { search } = useLocation();
|
||||
const [selectedImageId, setSelectedImageId] = useState<string | number>(
|
||||
Number(new URLSearchParams(search).get("id")) || 9
|
||||
);
|
||||
const orbitRef = useRef<OrbitControlsImpl>(null);
|
||||
const fullscreenRef = useRef<HTMLDivElement>(null);
|
||||
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
|
||||
const navigate = useNavigate();
|
||||
const [selectedPointId, setSelectedPointId] = useState<string | number>(
|
||||
selectedImageId
|
||||
);
|
||||
|
||||
function handleSelectImageId(toId: string) {
|
||||
function handleSelectImageId(toId: string | number) {
|
||||
setSelectedImageId(toId);
|
||||
setSelectedPointId(toId);
|
||||
console.log(toId);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
orbitRef.current?.setAzimuthalAngle(-0.7);
|
||||
}, 200);
|
||||
}, [orbitRef]);
|
||||
// useEffect(() => {
|
||||
// setTimeout(() => {
|
||||
// orbitRef.current?.setAzimuthalAngle(-0.7);
|
||||
// }, 200);
|
||||
// }, [orbitRef]);
|
||||
|
||||
return (
|
||||
<div ref={fullscreenRef} className="h-screen bg-black select-none">
|
||||
<div className="absolute xl:left-8 left-4 xl:bottom-8 bottom-4 z-[99999999]">
|
||||
<div className="absolute top-0 left-0 w-[260px] min-h-screen bg-[#002347] bg-opacity-90 z-[99999999] p-7 flex flex-col justify-between">
|
||||
<div className="flex flex-col gap-9">
|
||||
<h2 className="font-tenor text-2xl">2-комнатные апартаменты</h2>
|
||||
<div className="self-center">
|
||||
<RHataMap
|
||||
points={images.map((image) => ({
|
||||
id: image.id,
|
||||
mapPosition: image.mapPosition,
|
||||
}))}
|
||||
selectedPointId={selectedPointId}
|
||||
onClick={(pointId) => handleSelectImageId(pointId)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
text="Генплан"
|
||||
icon={<ArrowLeftIcon />}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { Html, OrbitControls } from "@react-three/drei";
|
||||
import { Suspense, useEffect, useRef, useState } from "react";
|
||||
import { Suspense, useRef, useState } from "react";
|
||||
import { OrbitControls as OrbitControlsImpl } from "three-stdlib";
|
||||
import { useFullscreen } from "ahooks";
|
||||
import SphereTour from "../components/SphereTour";
|
||||
@@ -14,38 +15,78 @@ import _images from "../images4.json";
|
||||
import Image from "../types/Image";
|
||||
import ElevatorIcon from "../components/icons/ElevatorIcon";
|
||||
import Loader from "../components/Loader";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { isIOS } from "react-device-detect";
|
||||
import LHataMap from "../components/maps/LHataMap";
|
||||
|
||||
const images = _images as Image[];
|
||||
const images = _images as unknown as Image[];
|
||||
|
||||
function VirtualTour4Page() {
|
||||
const [selectedImageId, setSelectedImageId] = useState<string>(images[0].id);
|
||||
const { search } = useLocation();
|
||||
const [selectedImageId, setSelectedImageId] = useState<string | number>(
|
||||
Number(new URLSearchParams(search).get("id")) || 12
|
||||
);
|
||||
const orbitRef = useRef<OrbitControlsImpl>(null);
|
||||
const canvasRef = useRef(null);
|
||||
const fullscreenRef = useRef<HTMLDivElement>(null);
|
||||
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
|
||||
const navigate = useNavigate();
|
||||
const [selectedPointId, setSelectedPointId] = useState<string | number>(
|
||||
selectedImageId
|
||||
);
|
||||
|
||||
function handleSelectImageId(toId: string) {
|
||||
function handleSelectImageId(toId: string | number) {
|
||||
setSelectedImageId(toId);
|
||||
setSelectedPointId(toId);
|
||||
console.log(toId);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
orbitRef.current?.setAzimuthalAngle(-2.3);
|
||||
}, 200);
|
||||
}, [orbitRef]);
|
||||
|
||||
return (
|
||||
<div ref={fullscreenRef} className="h-screen bg-black select-none">
|
||||
<div className="absolute xl:left-8 left-4 xl:bottom-8 bottom-4 z-[99999999]">
|
||||
<div className="absolute top-0 left-0 w-[260px] min-h-screen bg-[#002347] bg-opacity-90 z-[99999999] p-7 flex flex-col justify-between">
|
||||
<div className="flex flex-col">
|
||||
<h2 className="font-tenor text-2xl mb-4">3-комнатные апартаменты</h2>
|
||||
<div className="flex flex-col mb-7">
|
||||
<p>
|
||||
<span className="font-medium">Башня</span>{" "}
|
||||
<span className="text-[#9595A2]">1</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Этаж</span>{" "}
|
||||
<span className="text-[#9595A2]">7-28</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-medium">Площадь</span>{" "}
|
||||
<span className="text-[#9595A2]">116.8 м²</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="self-center mb-7">
|
||||
<LHataMap
|
||||
points={images.map((image) => ({
|
||||
id: image.id,
|
||||
mapPosition: image.mapPosition,
|
||||
mapLabel: image.mapLabel,
|
||||
}))}
|
||||
selectedPointId={selectedPointId}
|
||||
onClick={(pointId) => handleSelectImageId(pointId)}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-7">
|
||||
<p className="text-[#9595A2] text-sm leading-[18.2px]">
|
||||
Стоимость:
|
||||
</p>
|
||||
<p className="font-tenor text-lg leading-[23.4px]">- руб.</p>
|
||||
</div>
|
||||
<div className="mb-7">
|
||||
<p className="text-[#9595A2] text-sm leading-[18.2px]">Статус:</p>
|
||||
<p className="font-tenor text-lg leading-[23.4px]">В продаже</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
text="Генплан"
|
||||
text="Вид сверху"
|
||||
icon={<ArrowLeftIcon />}
|
||||
widthFull
|
||||
onClick={() => navigate("/")}
|
||||
onClick={() => navigate(-1)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -59,7 +100,7 @@ function VirtualTour4Page() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Canvas ref={canvasRef} camera={{ fov: 65 }}>
|
||||
<Canvas camera={{ fov: 65 }}>
|
||||
<Suspense fallback={<Loader />}>
|
||||
<ambientLight intensity={2.5} />
|
||||
|
||||
|
||||
@@ -21,14 +21,18 @@ import DvorMap from "../components/maps/DvorMap";
|
||||
const images = _images as Image[];
|
||||
|
||||
function VirtualTourPage() {
|
||||
const [selectedImageId, setSelectedImageId] = useState<string>(images[0].id);
|
||||
const [selectedImageId, setSelectedImageId] = useState<string | number>(
|
||||
images[0].id
|
||||
);
|
||||
const orbitRef = useRef<OrbitControlsImpl>(null);
|
||||
const fullscreenRef = useRef<HTMLDivElement>(null);
|
||||
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
|
||||
const navigate = useNavigate();
|
||||
const [selectedPointId, setSelectedPointId] = useState<string>(images[0].id);
|
||||
const [selectedPointId, setSelectedPointId] = useState<string | number>(
|
||||
selectedImageId
|
||||
);
|
||||
|
||||
function handleSelectImageId(toId: string) {
|
||||
function handleSelectImageId(toId: string | number) {
|
||||
setSelectedImageId(toId);
|
||||
setSelectedPointId(toId);
|
||||
console.log(toId);
|
||||
@@ -44,6 +48,7 @@ function VirtualTourPage() {
|
||||
points={images.map((image) => ({
|
||||
id: image.id,
|
||||
mapPosition: image.mapPosition,
|
||||
mapLabel: image.mapLabel,
|
||||
}))}
|
||||
selectedPointId={selectedPointId}
|
||||
onClick={(pointId) => handleSelectImageId(pointId)}
|
||||
|
||||
@@ -2,10 +2,11 @@ import { Vector3 } from "@react-three/fiber";
|
||||
import Link from "./Link";
|
||||
|
||||
interface Image {
|
||||
id: string;
|
||||
id: string | number;
|
||||
src: string;
|
||||
position: Vector3;
|
||||
mapPosition: [number, number];
|
||||
mapLabel?: string;
|
||||
icon?: string;
|
||||
links?: Link[];
|
||||
}
|
||||
|
||||