feat: float detail box
This commit is contained in:
parent
719a2eac00
commit
cfc19a42a2
|
|
@ -13,7 +13,6 @@ export function BuildingHeights({ area }: { area: any }) {
|
|||
const appendAreas = useAreaStore((state) => state.appendAreas);
|
||||
|
||||
const requestBuildings = () => {
|
||||
console.log(area);
|
||||
const south = area[1].lat;
|
||||
const west = area[1].lng;
|
||||
const north = area[0].lat;
|
||||
|
|
@ -50,7 +49,29 @@ export function BuildingHeights({ area }: { area: any }) {
|
|||
position: "relative",
|
||||
})}
|
||||
>
|
||||
<button onClick={requestBuildings}>request</button>
|
||||
<button
|
||||
css={css({
|
||||
color: "#ffffff",
|
||||
|
||||
backgroundColor: "#007bffe8",
|
||||
backdropFilter: "blur(8px)",
|
||||
border: "none",
|
||||
padding: "0.5rem 1rem",
|
||||
borderRadius: "8px",
|
||||
outline: "#086ad4c2 solid 0.1rem",
|
||||
cursor: "pointer",
|
||||
transition: "0.2s",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "0.5rem",
|
||||
":hover": {
|
||||
backgroundColor: "#085fbd",
|
||||
},
|
||||
})}
|
||||
onClick={requestBuildings}
|
||||
>
|
||||
request
|
||||
</button>
|
||||
<ul
|
||||
css={css({
|
||||
overflow: "scroll",
|
||||
|
|
|
|||
|
|
@ -1,9 +1,76 @@
|
|||
import React, { useRef, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { useAreaStore } from "@/state/areaStore";
|
||||
import { OrbitControls } from "@react-three/drei";
|
||||
import { OrbitControls, Html } from "@react-three/drei";
|
||||
import * as THREE from "three";
|
||||
|
||||
function Building({
|
||||
shape,
|
||||
extrudeSettings,
|
||||
tags,
|
||||
}: {
|
||||
shape: THREE.Shape;
|
||||
extrudeSettings: any;
|
||||
tags: any;
|
||||
}) {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const [clicked, setClicked] = useState(false);
|
||||
const [hoverPos, setHoverPos] = useState<THREE.Vector3 | null>(null);
|
||||
|
||||
return (
|
||||
<mesh
|
||||
onPointerOver={(e) => {
|
||||
setHovered(true);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onPointerOut={(e) => {
|
||||
setHovered(false);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onPointerMove={(e) => {
|
||||
setHoverPos(e.point.clone());
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onClick={(e) => {
|
||||
setClicked(!clicked);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
rotation={[-Math.PI / 2, 0, 0]}
|
||||
>
|
||||
<extrudeGeometry args={[shape, extrudeSettings]} />
|
||||
<meshStandardMaterial
|
||||
color={hovered || clicked ? "#007bff" : "#9da0a3"}
|
||||
/>
|
||||
{(hovered || clicked) && hoverPos && (
|
||||
<Html
|
||||
position={[
|
||||
hoverPos.x,
|
||||
hoverPos.y + extrudeSettings.depth + 0.5,
|
||||
hoverPos.z,
|
||||
]}
|
||||
center
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
color: "#000000",
|
||||
backgroundColor: "#ffffff96",
|
||||
backdropFilter: "blur(8px)",
|
||||
border: "none",
|
||||
padding: "0.5rem 1rem",
|
||||
borderRadius: "8px",
|
||||
fontWeight: "300",
|
||||
fontSize: "12px",
|
||||
outline: "rgba(240, 240, 244, 0.51) solid 0.1rem",
|
||||
}}
|
||||
>
|
||||
<div>{JSON.stringify(tags)}</div>
|
||||
</div>
|
||||
</Html>
|
||||
)}
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
|
||||
export function Space() {
|
||||
const areas = useAreaStore((state) => state.areas);
|
||||
const center = useAreaStore((state) => state.center);
|
||||
|
|
@ -18,8 +85,12 @@ export function Space() {
|
|||
return new THREE.Vector2(x, y);
|
||||
}
|
||||
|
||||
const areaMap = () => {
|
||||
const result = [];
|
||||
const areaData = () => {
|
||||
const result: Array<{
|
||||
shape: THREE.Shape;
|
||||
extrudeSettings: any;
|
||||
tags: any;
|
||||
}> = [];
|
||||
areas.forEach((bld: any) => {
|
||||
if (!bld.geometry || bld.geometry.length < 3) return;
|
||||
const shapePoints = bld.geometry.map((pt: any) =>
|
||||
|
|
@ -30,20 +101,25 @@ export function Space() {
|
|||
}
|
||||
const shape = new THREE.Shape(shapePoints);
|
||||
let heightValue = parseFloat(bld.tags.height || "");
|
||||
const heightLevels = parseFloat(bld.tags["building:levels"] || "");
|
||||
if (isNaN(heightValue)) {
|
||||
heightValue = 10;
|
||||
}
|
||||
if (!isNaN(heightLevels)) {
|
||||
heightValue = heightLevels * 2.2;
|
||||
}
|
||||
const extrudeSettings = {
|
||||
steps: 1,
|
||||
depth: heightValue,
|
||||
bevelEnabled: false,
|
||||
};
|
||||
result.push([shape, extrudeSettings]);
|
||||
result.push({ shape, extrudeSettings, tags: bld.tags });
|
||||
});
|
||||
console.log(result);
|
||||
return result;
|
||||
};
|
||||
|
||||
const buildingsData = areaData();
|
||||
|
||||
return (
|
||||
<Canvas camera={{ fov: 90, near: 0.1, far: 4000 }}>
|
||||
<ambientLight intensity={Math.PI / 2} />
|
||||
|
|
@ -54,12 +130,13 @@ export function Space() {
|
|||
decay={0}
|
||||
intensity={Math.PI}
|
||||
/>
|
||||
|
||||
{areaMap().map((item, index) => (
|
||||
<mesh key={index} rotation={[-Math.PI / 2, 0, 0]}>
|
||||
<extrudeGeometry args={[item[0], item[1]]} />
|
||||
<meshStandardMaterial color="gray" />
|
||||
</mesh>
|
||||
{buildingsData.map((item, index) => (
|
||||
<Building
|
||||
key={index}
|
||||
shape={item.shape}
|
||||
extrudeSettings={item.extrudeSettings}
|
||||
tags={item.tags}
|
||||
/>
|
||||
))}
|
||||
<pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
|
||||
<OrbitControls />
|
||||
|
|
|
|||
Loading…
Reference in New Issue