Start working on UI

This commit is contained in:
Fuhrmann 2025-03-06 13:36:47 +01:00
parent 07208177fd
commit 8227b4141a
16 changed files with 701 additions and 581 deletions

84
app/components/Form.tsx Normal file
View file

@ -0,0 +1,84 @@
"use client";
import {
Accordion,
Button,
Checkbox,
Label,
TextInput,
ToggleSwitch,
} from "flowbite-react";
import { useContext, useState } from "react";
import {
MapSceneContext,
MapSceneContextType,
} from "../providers/map-scene-provider";
import { Mesh, MeshStandardMaterial } from "three";
export function Form() {
const [enabled, setEnabled] = useState<boolean>(true);
const { mapScene } = useContext(MapSceneContext) as MapSceneContextType;
function handleChange() {
if (!mapScene) return;
mapScene.toggleClippingBox();
setEnabled(!enabled);
}
function handleCheckboxChange(name: string) {
if (!mapScene) return;
const mesh = mapScene.model.getObjectByName(name);
if (mesh) {
mesh.visible = !mesh.visible;
}
}
return (
<div className="w-full flex flex-col gap-2 overflow-y-auto">
<div className="w-full flex flex-col gap-3 p-4 border border-gray-200 rounded shadow">
<ToggleSwitch
checked={enabled}
label="Toggle Slicing Box"
onChange={handleChange}
/>
<Accordion>
<Accordion.Panel>
<Accordion.Title>Layers</Accordion.Title>
<Accordion.Content>
<div className="mt-2">
{mapScene?.model.children.map((child) => {
const key = `toggle-visibility-${child.name}`;
const color = `#${(
(child as Mesh).material as MeshStandardMaterial
).color.getHexString()}`;
return (
<div key={key} className="flex items-center ml-2">
<span
className="inline-block w-4 h-4"
style={{
backgroundColor: color,
}}
></span>
<Checkbox
id={key}
defaultChecked
onChange={() => handleCheckboxChange(child.name)}
className="ml-2"
/>
<Label htmlFor={key} className="ml-2">
{child.name}
</Label>
</div>
);
})}
</div>
</Accordion.Content>
</Accordion.Panel>
</Accordion>
</div>
</div>
);
}

View file

@ -1,17 +1,31 @@
"use client";
import { useEffect, useRef } from "react";
import { init } from "../three/utils/init";
import { useContext, useEffect, useRef } from "react";
import { MapScene } from "../three/MapScene";
import {
MapSceneContext,
MapSceneContextType,
} from "../providers/map-scene-provider";
export function Map() {
const divRef = useRef<HTMLDivElement>(null);
const { setMapScene } = useContext(MapSceneContext) as MapSceneContextType;
useEffect(() => {
let ignore = false;
if (!divRef.current) return;
async function loadScene() {
if (divRef.current) {
const _mapScene = await MapScene.create(divRef.current, "20");
if (_mapScene) {
setMapScene(_mapScene);
}
}
}
if (!ignore) {
init(divRef.current);
loadScene();
}
return () => {