Merge pull request #605 from c-bata/simplify-threejs-viewer

Simplify an artifact viewer for 3D models.
This commit is contained in:
c-bata
2023-09-07 19:06:49 +09:00
committed by GitHub
2 changed files with 56 additions and 44 deletions
@@ -1,10 +1,11 @@
import * as THREE from "three"
import React, { useEffect, useState } from "react"
import React, { useEffect, useState, ReactNode } from "react"
import { Canvas } from "@react-three/fiber"
import { GizmoHelper, GizmoViewport, OrbitControls } from "@react-three/drei"
import { STLLoader } from "three/examples/jsm/loaders/STLLoader"
import { Rhino3dmLoader } from "three/examples/jsm/loaders/3DMLoader"
import { PerspectiveCamera } from "three"
import { Modal, Box } from "@mui/material"
interface ThreejsArtifactViewerProps {
src: string
@@ -109,3 +110,48 @@ export const ThreejsArtifactViewer: React.FC<ThreejsArtifactViewerProps> = (
</Canvas>
)
}
export const useThreejsArtifactModal = (): [
(path: string, artifact: Artifact) => void,
() => ReactNode
] => {
const [open, setOpen] = useState(false)
const [target, setTarget] = useState<[string, Artifact | null]>(["", null])
const openModal = (artifactUrlPath: string, artifact: Artifact) => {
setTarget([artifactUrlPath, artifact])
setOpen(true)
}
const renderDeleteStudyDialog = () => {
return (
<Modal
open={open}
onClose={() => {
setOpen(false)
setTarget(["", null])
}}
>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
bgcolor: "background.paper",
borderRadius: "15px",
}}
>
<ThreejsArtifactViewer
src={target[0]}
width={`${innerWidth * 0.8}px`}
height={`${innerHeight * 0.8}px`}
hasGizmo={true}
filetype={target[1]?.filename.split(".").pop()}
/>
</Box>
</Modal>
)
}
return [openModal, renderDeleteStudyDialog]
}
+9 -43
View File
@@ -20,7 +20,6 @@ import {
CardContent,
CardMedia,
CardActionArea,
Modal,
} from "@mui/material"
import Chip from "@mui/material/Chip"
import Divider from "@mui/material/Divider"
@@ -47,7 +46,10 @@ import { artifactIsAvailable } from "../state"
import { actionCreator } from "../action"
import { useDeleteArtifactDialog } from "./DeleteArtifactDialog"
import { TrialFormWidgets } from "./TrialFormWidgets"
import { ThreejsArtifactViewer } from "./ThreejsArtifactViewer"
import {
ThreejsArtifactViewer,
useThreejsArtifactModal,
} from "./ThreejsArtifactViewer"
const states: TrialState[] = [
"Complete",
@@ -330,9 +332,8 @@ const TrialArtifact: FC<{ trial: Trial }> = ({ trial }) => {
const [openDeleteArtifactDialog, renderDeleteArtifactDialog] =
useDeleteArtifactDialog()
const [dragOver, setDragOver] = useState<boolean>(false)
const [open3dModelViewer, setOpen3dModelViewer] = useState<{
[key: string]: boolean
}>({})
const [openThreejsArtifactModal, renderThreejsArtifactModal] =
useThreejsArtifactModal()
const width = "200px"
const height = "150px"
@@ -499,48 +500,12 @@ const TrialArtifact: FC<{ trial: Trial }> = ({ trial }) => {
color="inherit"
sx={{ margin: "auto 0" }}
onClick={() => {
setOpen3dModelViewer(() => {
const obj = { ...open3dModelViewer }
obj[a.artifact_id] = true
return obj
})
const urlPath = `/artifacts/${trial.study_id}/${trial.trial_id}/${a.artifact_id}`
openThreejsArtifactModal(urlPath, a)
}}
>
<FullscreenIcon />
</IconButton>
<Modal
open={
a.artifact_id in open3dModelViewer
? open3dModelViewer[a.artifact_id]
: false
}
onClose={() => {
setOpen3dModelViewer(() => {
const obj = { ...open3dModelViewer }
obj[a.artifact_id] = false
return obj
})
}}
>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
bgcolor: "background.paper",
borderRadius: "15px",
}}
>
<ThreejsArtifactViewer
src={`/artifacts/${trial.study_id}/${trial.trial_id}/${a.artifact_id}`}
width={`${innerWidth * 0.8}px`}
height={`${innerHeight * 0.8}px`}
hasGizmo={true}
filetype={a.filename.split(".").pop()}
/>
</Box>
</Modal>
<IconButton
aria-label="delete artifact"
size="small"
@@ -763,6 +728,7 @@ const TrialArtifact: FC<{ trial: Trial }> = ({ trial }) => {
) : null}
</Box>
{renderDeleteArtifactDialog()}
{renderThreejsArtifactModal()}
</>
)
}