updating UI
This commit is contained in:
parent
750ac5af1d
commit
2ad1006de4
|
@ -1,19 +1,58 @@
|
|||
export function ThroughputSummaryIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="26"
|
||||
height="27"
|
||||
viewBox="0 0 26 27"
|
||||
width="35"
|
||||
height="35"
|
||||
viewBox="0 0 35 35"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle cx="13.3457" cy="13.498" r="12.6543" fill="#FC9D2F" />
|
||||
<g filter="url(#filter0_d_4173_2625)">
|
||||
<circle cx="15.5" cy="15.5" r="12.5" fill="#FC9D2F" />
|
||||
</g>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M13.9063 12.9046L14.2265 13.86L14.4378 14.5073C14.9906 16.2239 15.2594 17.2662 15.2594 17.7299C15.2594 18.8219 14.3742 19.7072 13.2822 19.7072C12.1902 19.7072 11.305 18.8219 11.305 17.7299C11.305 17.2106 11.6422 15.9654 12.3379 13.86L12.658 12.9046C12.8604 12.3082 13.704 12.3082 13.9063 12.9046ZM13.2822 7.84375C16.9222 7.84375 19.873 10.7945 19.873 14.4345C19.873 15.7565 19.4823 17.0219 18.7621 18.0974C18.5596 18.3999 18.1502 18.4809 17.8478 18.2784C17.5453 18.0758 17.4643 17.6665 17.6668 17.364C18.2428 16.5038 18.5548 15.4933 18.5548 14.4345C18.5548 11.5225 16.1942 9.16191 13.2822 9.16191C10.3702 9.16191 8.00956 11.5225 8.00956 14.4345C8.00956 15.4933 8.32153 16.5038 8.89752 17.364C9.10005 17.6665 9.01904 18.0758 8.71659 18.2784C8.41414 18.4809 8.00477 18.3999 7.80224 18.0974C7.08206 17.0219 6.69141 15.7565 6.69141 14.4345C6.69141 10.7945 9.6422 7.84375 13.2822 7.84375ZM13.2822 15.2247L13.0657 15.9238L12.9161 16.4319C12.7219 17.111 12.6231 17.5509 12.6231 17.7299C12.6231 18.0939 12.9182 18.389 13.2822 18.389C13.6462 18.389 13.9413 18.0939 13.9413 17.7299C13.9413 17.511 13.7936 16.9022 13.5044 15.9428L13.2822 15.2247Z"
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M16.0538 14.9132L16.3701 15.857L16.5788 16.4964C17.1249 18.1921 17.3904 19.2217 17.3904 19.6797C17.3904 20.7584 16.516 21.6328 15.4373 21.6328C14.3586 21.6328 13.4842 20.7584 13.4842 19.6797C13.4842 19.1667 13.8173 17.9367 14.5045 15.857L14.8208 14.9132C15.0206 14.3241 15.8539 14.3241 16.0538 14.9132ZM15.4373 9.91406C19.0329 9.91406 21.9477 12.8289 21.9477 16.4245C21.9477 17.7303 21.5618 18.9803 20.8504 20.0427C20.6504 20.3415 20.246 20.4215 19.9472 20.2214C19.6485 20.0214 19.5684 19.617 19.7685 19.3182C20.3375 18.4685 20.6456 17.4703 20.6456 16.4245C20.6456 13.548 18.3138 11.2161 15.4373 11.2161C12.5608 11.2161 10.229 13.548 10.229 16.4245C10.229 17.4703 10.5371 18.4685 11.1061 19.3182C11.3062 19.617 11.2261 20.0214 10.9274 20.2214C10.6286 20.4215 10.2242 20.3415 10.0242 20.0427C9.31277 18.9803 8.92688 17.7303 8.92688 16.4245C8.92688 12.8289 11.8417 9.91406 15.4373 9.91406ZM15.4373 17.2051L15.2235 17.8956L15.0757 18.3975C14.8838 19.0684 14.7863 19.5028 14.7863 19.6797C14.7863 20.0392 15.0777 20.3307 15.4373 20.3307C15.7969 20.3307 16.0883 20.0392 16.0883 19.6797C16.0883 19.4634 15.9424 18.862 15.6568 17.9143L15.4373 17.2051Z"
|
||||
fill="white"
|
||||
/>
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_d_4173_2625"
|
||||
x="0.629264"
|
||||
y="0.629264"
|
||||
width="33.6927"
|
||||
height="33.6927"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dx="1.97561" dy="1.97561" />
|
||||
<feGaussianBlur stdDeviation="2.17317" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0.988235 0 0 0 0 0.615686 0 0 0 0 0.184314 0 0 0 0.25 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_4173_2625"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_4173_2625"
|
||||
result="shape"
|
||||
/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
@ -21,28 +60,72 @@ export function ThroughputSummaryIcon() {
|
|||
export function ProductionCapacityIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="25"
|
||||
height="25"
|
||||
viewBox="0 0 25 25"
|
||||
width="33"
|
||||
height="33"
|
||||
viewBox="0 0 33 33"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect width="25" height="25" rx="12.5" fill="#6F42C1" />
|
||||
<g clipPath="url(#clip0_4107_2562)">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M13.5167 7.88281H15.3741C15.668 7.88281 15.9053 8.09496 15.9053 8.35581V13.0575H9.079L9.00279 13.0583V8.35581C9.00279 8.09417 9.24007 7.88281 9.53393 7.88281H11.3921V10.251C11.3921 10.3138 11.4204 10.3735 11.4707 10.4183C11.5226 10.4633 11.5891 10.4879 11.6577 10.4875H13.2511C13.3201 10.4881 13.3868 10.4635 13.4389 10.4183C13.4625 10.3971 13.4815 10.3713 13.4949 10.3426C13.5082 10.3138 13.5157 10.2826 13.5167 10.251V7.88281ZM9.079 14.0389H15.921C16.4243 14.0491 16.9035 14.2561 17.2559 14.6157C17.6082 14.9752 17.8056 15.4585 17.8056 15.9619C17.8056 16.4653 17.6082 16.9486 17.2559 17.3082C16.9035 17.6677 16.4243 17.8748 15.921 17.885H9.079C8.82319 17.8901 8.56892 17.8442 8.33108 17.7499C8.09324 17.6556 7.87661 17.5147 7.69387 17.3357C7.51113 17.1566 7.36596 16.9428 7.26685 16.707C7.16775 16.4711 7.1167 16.2178 7.1167 15.9619C7.1167 15.7061 7.16775 15.4528 7.26685 15.2169C7.36596 14.981 7.51113 14.7673 7.69387 14.5882C7.87661 14.4091 8.09324 14.2683 8.33108 14.174C8.56892 14.0796 8.82319 14.0337 9.079 14.0389ZM10.4626 15.956C10.4626 16.1384 10.3902 16.3132 10.2613 16.4422C10.1323 16.5711 9.95748 16.6435 9.77514 16.6435C9.59281 16.6435 9.41794 16.5711 9.28901 16.4422C9.16008 16.3132 9.08764 16.1384 9.08764 15.956C9.08764 15.7737 9.16008 15.5988 9.28901 15.4699C9.41794 15.341 9.59281 15.2685 9.77514 15.2685C9.95748 15.2685 10.1323 15.341 10.2613 15.4699C10.3902 15.5988 10.4626 15.7737 10.4626 15.956ZM13.1914 15.956C13.1914 16.1384 13.119 16.3132 12.9901 16.4422C12.8611 16.5711 12.6863 16.6435 12.5039 16.6435C12.3216 16.6435 12.1467 16.5711 12.0178 16.4422C11.8889 16.3132 11.8164 16.1384 11.8164 15.956C11.8164 15.7737 11.8889 15.5988 12.0178 15.4699C12.1467 15.341 12.3216 15.2685 12.5039 15.2685C12.6863 15.2685 12.8611 15.341 12.9901 15.4699C13.119 15.5988 13.1914 15.7737 13.1914 15.956ZM15.2319 16.6427C15.4143 16.6427 15.5891 16.5703 15.7181 16.4414C15.847 16.3124 15.9194 16.1376 15.9194 15.9552C15.9194 15.7729 15.847 15.598 15.7181 15.4691C15.5891 15.3402 15.4143 15.2677 15.2319 15.2677C15.0496 15.2677 14.8747 15.3402 14.7458 15.4691C14.6169 15.598 14.5444 15.7729 14.5444 15.9552C14.5444 16.1376 14.6169 16.3124 14.7458 16.4414C14.8747 16.5703 15.0496 16.6427 15.2319 16.6427Z"
|
||||
fill="white"
|
||||
<g filter="url(#filter0_d_4173_2653)">
|
||||
<rect
|
||||
x="4"
|
||||
width="25"
|
||||
height="25"
|
||||
rx="12.5"
|
||||
fill="#6F42C1"
|
||||
shape-rendering="crispEdges"
|
||||
/>
|
||||
<g clip-path="url(#clip0_4173_2653)">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M17.5167 7.88281H19.3741C19.6679 7.88281 19.9052 8.09496 19.9052 8.35581V13.0575H13.0789L13.0027 13.0583V8.35581C13.0027 8.09417 13.24 7.88281 13.5339 7.88281H15.3921V10.251C15.3921 10.3138 15.4204 10.3735 15.4707 10.4183C15.5225 10.4633 15.589 10.4879 15.6577 10.4875H17.2511C17.32 10.4881 17.3868 10.4635 17.4389 10.4183C17.4624 10.3971 17.4815 10.3713 17.4948 10.3426C17.5082 10.3138 17.5156 10.2826 17.5167 10.251V7.88281ZM13.0789 14.0389H19.9209C20.4242 14.0491 20.9035 14.2561 21.2558 14.6157C21.6081 14.9752 21.8055 15.4585 21.8055 15.9619C21.8055 16.4653 21.6081 16.9486 21.2558 17.3082C20.9035 17.6677 20.4242 17.8748 19.9209 17.885H13.0789C12.8231 17.8901 12.5689 17.8442 12.331 17.7499C12.0932 17.6556 11.8766 17.5147 11.6938 17.3357C11.5111 17.1566 11.3659 16.9428 11.2668 16.707C11.1677 16.4711 11.1166 16.2178 11.1166 15.9619C11.1166 15.7061 11.1677 15.4528 11.2668 15.2169C11.3659 14.981 11.5111 14.7673 11.6938 14.5882C11.8766 14.4091 12.0932 14.2683 12.331 14.174C12.5689 14.0796 12.8231 14.0337 13.0789 14.0389ZM14.4626 15.956C14.4626 16.1384 14.3901 16.3132 14.2612 16.4422C14.1323 16.5711 13.9574 16.6435 13.7751 16.6435C13.5927 16.6435 13.4179 16.5711 13.2889 16.4422C13.16 16.3132 13.0876 16.1384 13.0876 15.956C13.0876 15.7737 13.16 15.5988 13.2889 15.4699C13.4179 15.341 13.5927 15.2685 13.7751 15.2685C13.9574 15.2685 14.1323 15.341 14.2612 15.4699C14.3901 15.5988 14.4626 15.7737 14.4626 15.956ZM17.1914 15.956C17.1914 16.1384 17.1189 16.3132 16.99 16.4422C16.8611 16.5711 16.6862 16.6435 16.5039 16.6435C16.3215 16.6435 16.1467 16.5711 16.0177 16.4422C15.8888 16.3132 15.8164 16.1384 15.8164 15.956C15.8164 15.7737 15.8888 15.5988 16.0177 15.4699C16.1467 15.341 16.3215 15.2685 16.5039 15.2685C16.6862 15.2685 16.8611 15.341 16.99 15.4699C17.1189 15.5988 17.1914 15.7737 17.1914 15.956ZM19.2319 16.6427C19.4142 16.6427 19.5891 16.5703 19.718 16.4414C19.8469 16.3124 19.9194 16.1376 19.9194 15.9552C19.9194 15.7729 19.8469 15.598 19.718 15.4691C19.5891 15.3402 19.4142 15.2677 19.2319 15.2677C19.0495 15.2677 18.8747 15.3402 18.7457 15.4691C18.6168 15.598 18.5444 15.7729 18.5444 15.9552C18.5444 16.1376 18.6168 16.3124 18.7457 16.4414C18.8747 16.5703 19.0495 16.6427 19.2319 16.6427Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_4107_2562">
|
||||
<filter
|
||||
id="filter0_d_4173_2653"
|
||||
x="0"
|
||||
y="0"
|
||||
width="33"
|
||||
height="33"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dy="4" />
|
||||
<feGaussianBlur stdDeviation="2" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0.435294 0 0 0 0 0.258824 0 0 0 0 0.756863 0 0 0 0.25 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_4173_2653"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_4173_2653"
|
||||
result="shape"
|
||||
/>
|
||||
</filter>
|
||||
<clipPath id="clip0_4173_2653">
|
||||
<rect
|
||||
width="11"
|
||||
height="11"
|
||||
fill="var(--text-color)"
|
||||
transform="translate(7 7)"
|
||||
fill="white"
|
||||
transform="translate(11 7)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
PointElement,
|
||||
} from "chart.js";
|
||||
import { PowerIcon, ProductionCapacityIcon } from "../../icons/analysis";
|
||||
import { ThroughputIcon } from "../../icons/3dChartIcons";
|
||||
|
||||
ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);
|
||||
|
||||
|
@ -84,8 +85,8 @@ const ThroughputSummary = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="throughoutSummary analysis-card">
|
||||
<div className="throughoutSummary-wrapper analysis-card-wrapper">
|
||||
<div className="production analysis-card">
|
||||
<div className="production-wrapper analysis-card-wrapper">
|
||||
<div className="card-header">
|
||||
<div className="header">
|
||||
<div className="main-header">Production Capacity</div>
|
||||
|
|
|
@ -117,7 +117,9 @@ const ROISummary = ({
|
|||
</div>
|
||||
</div>
|
||||
<div className="metric-item net-profit">
|
||||
<span className="metric-label">Net Profit</span>
|
||||
<span className="metric-label">
|
||||
<span>↑</span> Net Profit
|
||||
</span>
|
||||
<span className="metric-value">{roiSummaryData.netProfit}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -186,9 +188,10 @@ const ROISummary = ({
|
|||
Increase CNC utilization by <span className="highlight">10%</span>{" "}
|
||||
to shave <span className="highlight">0.5</span> months of payback
|
||||
period
|
||||
<div className="placeHolder"></div>
|
||||
<div className="placeHolder"></div>
|
||||
<div className="placeHolder"></div>
|
||||
<div className="placeHolder-wrapper">
|
||||
<div className="placeHolder"></div>
|
||||
<div className="placeHolder"></div>
|
||||
</div>
|
||||
</div>
|
||||
<button className="get-tips-button">
|
||||
<div className="btn">Get ROI Boost Tips</div>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import { ThroughputSummaryIcon } from "../../icons/analysis";
|
||||
import {
|
||||
ProductionCapacityIcon,
|
||||
ThroughputSummaryIcon,
|
||||
} from "../../icons/analysis";
|
||||
|
||||
const ProductionCapacity = ({
|
||||
progressPercent = 50,
|
||||
|
@ -13,8 +16,8 @@ const ProductionCapacity = ({
|
|||
((progressPercent / 100) * totalBars - barsToFill) * 100;
|
||||
|
||||
return (
|
||||
<div className="productionCapacity-container analysis-card">
|
||||
<div className="productionCapacity-wrapper analysis-card-wrapper">
|
||||
<div className="throughtputSummary-container analysis-card">
|
||||
<div className="throughtputSummary-wrapper analysis-card-wrapper">
|
||||
<div className="card-header">
|
||||
<div className="header">
|
||||
<div className="main-header">Throughput Summary</div>
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import React, { createContext, useContext, useState, useCallback, useMemo } from "react";
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useState,
|
||||
useCallback,
|
||||
useMemo,
|
||||
} from "react";
|
||||
|
||||
export type LogType = "log" | "info" | "warning" | "error" | "success";
|
||||
|
||||
|
@ -48,18 +54,21 @@ export const LoggerProvider: React.FC<{ children: React.ReactNode }> = ({
|
|||
[generateId]
|
||||
);
|
||||
|
||||
const loggerMethods: LoggerContextValue = useMemo(() => ({
|
||||
logs,
|
||||
setLogs,
|
||||
isLogListVisible,
|
||||
setIsLogListVisible,
|
||||
log: (message: string) => addLog("log", message),
|
||||
info: (message: string) => addLog("info", message),
|
||||
warn: (message: string) => addLog("warning", message),
|
||||
error: (message: string) => addLog("error", message),
|
||||
success: (message: string) => addLog("success", message),
|
||||
clear: () => setLogs([]),
|
||||
}), [logs, setLogs, isLogListVisible, setIsLogListVisible, addLog]);
|
||||
const loggerMethods: LoggerContextValue = useMemo(
|
||||
() => ({
|
||||
logs,
|
||||
setLogs,
|
||||
isLogListVisible,
|
||||
setIsLogListVisible,
|
||||
log: (message: string) => addLog("log", message),
|
||||
info: (message: string) => addLog("info", message),
|
||||
warn: (message: string) => addLog("warning", message),
|
||||
error: (message: string) => addLog("error", message),
|
||||
success: (message: string) => addLog("success", message),
|
||||
clear: () => setLogs([]),
|
||||
}),
|
||||
[logs, setLogs, isLogListVisible, setIsLogListVisible, addLog]
|
||||
);
|
||||
|
||||
return (
|
||||
<LoggerContext.Provider value={loggerMethods}>
|
||||
|
|
|
@ -368,7 +368,7 @@ const SimulationPlayer: React.FC = () => {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{subModule === "analysis" && (
|
||||
{/* {subModule === "analysis" && ( */}
|
||||
<div className="analysis">
|
||||
<div className="analysis-wrapper">
|
||||
<ProductionCapacity />
|
||||
|
@ -376,7 +376,7 @@ const SimulationPlayer: React.FC = () => {
|
|||
</div>
|
||||
<ROISummary />
|
||||
</div>
|
||||
)}
|
||||
{/* )} */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useActiveTool, useAsset3dWidget, useCamMode, useDeletableFloorItem, useDeleteTool, useFloorItems, useLoadingProgress, useRenderDistance, useSelectedFloorItem, useSelectedItem, useSocketStore, useToggleView, useTransformMode, } from "../../../store/store";
|
||||
import {
|
||||
useActiveTool,
|
||||
useAsset3dWidget,
|
||||
useCamMode,
|
||||
useDeletableFloorItem,
|
||||
useDeleteTool,
|
||||
useFloorItems,
|
||||
useLoadingProgress,
|
||||
useRenderDistance,
|
||||
useSelectedFloorItem,
|
||||
useSelectedItem,
|
||||
useSocketStore,
|
||||
useToggleView,
|
||||
useTransformMode,
|
||||
} from "../../../store/store";
|
||||
import assetVisibility from "../geomentries/assets/assetVisibility";
|
||||
import { useEffect } from "react";
|
||||
import * as THREE from "three";
|
||||
import * as Types from "../../../types/world/worldTypes";
|
||||
import assetManager, {
|
||||
cancelOngoingTasks,
|
||||
cancelOngoingTasks,
|
||||
} from "../geomentries/assets/assetManager";
|
||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
||||
|
@ -18,313 +32,422 @@ import useModuleStore from "../../../store/useModuleStore";
|
|||
// import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
|
||||
import { useEventsStore } from "../../../store/simulation/useEventsStore";
|
||||
|
||||
const assetManagerWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/assetManagerWorker.js", import.meta.url));
|
||||
const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url));
|
||||
const assetManagerWorker = new Worker(
|
||||
new URL(
|
||||
"../../../services/factoryBuilder/webWorkers/assetManagerWorker.js",
|
||||
import.meta.url
|
||||
)
|
||||
);
|
||||
const gltfLoaderWorker = new Worker(
|
||||
new URL(
|
||||
"../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js",
|
||||
import.meta.url
|
||||
)
|
||||
);
|
||||
|
||||
const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject, floorGroup, tempLoader, isTempLoader, plane, }: any) => {
|
||||
const state: Types.ThreeState = useThree();
|
||||
const { raycaster, controls }: any = state;
|
||||
const { renderDistance } = useRenderDistance();
|
||||
const { toggleView } = useToggleView();
|
||||
const { floorItems, setFloorItems } = useFloorItems();
|
||||
const { camMode } = useCamMode();
|
||||
const { deleteTool } = useDeleteTool();
|
||||
const { setDeletableFloorItem } = useDeletableFloorItem();
|
||||
const { transformMode } = useTransformMode();
|
||||
const { setSelectedFloorItem } = useSelectedFloorItem();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { selectedItem, setSelectedItem } = useSelectedItem();
|
||||
const { setLoadingProgress } = useLoadingProgress();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { socket } = useSocketStore();
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
const { addEvent } = useEventsStore();
|
||||
const FloorItemsGroup = ({
|
||||
itemsGroup,
|
||||
hoveredDeletableFloorItem,
|
||||
AttachedObject,
|
||||
floorGroup,
|
||||
tempLoader,
|
||||
isTempLoader,
|
||||
plane,
|
||||
}: any) => {
|
||||
const state: Types.ThreeState = useThree();
|
||||
const { raycaster, controls }: any = state;
|
||||
const { renderDistance } = useRenderDistance();
|
||||
const { toggleView } = useToggleView();
|
||||
const { floorItems, setFloorItems } = useFloorItems();
|
||||
const { camMode } = useCamMode();
|
||||
const { deleteTool } = useDeleteTool();
|
||||
const { setDeletableFloorItem } = useDeletableFloorItem();
|
||||
const { transformMode } = useTransformMode();
|
||||
const { setSelectedFloorItem } = useSelectedFloorItem();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { selectedItem, setSelectedItem } = useSelectedItem();
|
||||
const { setLoadingProgress } = useLoadingProgress();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { socket } = useSocketStore();
|
||||
const loader = new GLTFLoader();
|
||||
const dracoLoader = new DRACOLoader();
|
||||
const { addEvent } = useEventsStore();
|
||||
|
||||
dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
dracoLoader.setDecoderPath(
|
||||
"https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
|
||||
);
|
||||
loader.setDRACOLoader(dracoLoader);
|
||||
|
||||
useEffect(() => {
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email!.split("@")[1].split(".")[0];
|
||||
useEffect(() => {
|
||||
const email = localStorage.getItem("email");
|
||||
const organization = email!.split("@")[1].split(".")[0];
|
||||
|
||||
let totalAssets = 0;
|
||||
let loadedAssets = 0;
|
||||
let totalAssets = 0;
|
||||
let loadedAssets = 0;
|
||||
|
||||
const updateLoadingProgress = (progress: number) => {
|
||||
if (progress < 100) {
|
||||
setLoadingProgress(progress);
|
||||
} else if (progress === 100) {
|
||||
setTimeout(() => {
|
||||
setLoadingProgress(100);
|
||||
setTimeout(() => {
|
||||
setLoadingProgress(0);
|
||||
}, 1500);
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
const updateLoadingProgress = (progress: number) => {
|
||||
if (progress < 100) {
|
||||
setLoadingProgress(progress);
|
||||
} else if (progress === 100) {
|
||||
setTimeout(() => {
|
||||
setLoadingProgress(100);
|
||||
setTimeout(() => {
|
||||
setLoadingProgress(0);
|
||||
}, 1500);
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
getFloorAssets(organization).then((data) => {
|
||||
if (data.length > 0) {
|
||||
const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID));
|
||||
totalAssets = uniqueItems.length;
|
||||
if (totalAssets === 0) {
|
||||
updateLoadingProgress(100);
|
||||
return;
|
||||
}
|
||||
gltfLoaderWorker.postMessage({ floorItems: data });
|
||||
} else {
|
||||
gltfLoaderWorker.postMessage({ floorItems: [] });
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems, addEvent, renderDistance);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
getFloorAssets(organization).then((data) => {
|
||||
if (data.length > 0) {
|
||||
const uniqueItems = (data as Types.FloorItems).filter(
|
||||
(item, index, self) =>
|
||||
index === self.findIndex((t) => t.modelfileID === item.modelfileID)
|
||||
);
|
||||
totalAssets = uniqueItems.length;
|
||||
if (totalAssets === 0) {
|
||||
updateLoadingProgress(100);
|
||||
return;
|
||||
}
|
||||
gltfLoaderWorker.postMessage({ floorItems: data });
|
||||
} else {
|
||||
gltfLoaderWorker.postMessage({ floorItems: [] });
|
||||
loadInitialFloorItems(
|
||||
itemsGroup,
|
||||
setFloorItems,
|
||||
addEvent,
|
||||
renderDistance
|
||||
);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
});
|
||||
|
||||
gltfLoaderWorker.onmessage = async (event) => {
|
||||
if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
|
||||
const blobUrl = URL.createObjectURL(event.data.modelBlob);
|
||||
|
||||
loader.load(blobUrl, (gltf) => {
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
THREE.Cache.remove(blobUrl);
|
||||
THREE.Cache.add(event.data.modelID, gltf);
|
||||
|
||||
loadedAssets++;
|
||||
const progress = Math.round((loadedAssets / totalAssets) * 100);
|
||||
updateLoadingProgress(progress);
|
||||
|
||||
if (loadedAssets === totalAssets) {
|
||||
loadInitialFloorItems(
|
||||
itemsGroup,
|
||||
setFloorItems,
|
||||
addEvent,
|
||||
renderDistance
|
||||
);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
gltfLoaderWorker.onmessage = async (event) => {
|
||||
if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
|
||||
const blobUrl = URL.createObjectURL(event.data.modelBlob);
|
||||
useEffect(() => {
|
||||
assetManagerWorker.onmessage = async (event) => {
|
||||
cancelOngoingTasks(); // Cancel the ongoing process
|
||||
await assetManager(event.data, itemsGroup, loader);
|
||||
};
|
||||
}, [assetManagerWorker]);
|
||||
|
||||
loader.load(blobUrl, (gltf) => {
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
THREE.Cache.remove(blobUrl);
|
||||
THREE.Cache.add(event.data.modelID, gltf);
|
||||
useEffect(() => {
|
||||
if (toggleView) return;
|
||||
|
||||
loadedAssets++;
|
||||
const progress = Math.round((loadedAssets / totalAssets) * 100);
|
||||
updateLoadingProgress(progress);
|
||||
const uuids: string[] = [];
|
||||
itemsGroup.current?.children.forEach((child: any) => {
|
||||
uuids.push(child.uuid);
|
||||
});
|
||||
const cameraPosition = state.camera.position;
|
||||
|
||||
if (loadedAssets === totalAssets) {
|
||||
loadInitialFloorItems(itemsGroup, setFloorItems, addEvent, renderDistance);
|
||||
updateLoadingProgress(100);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
assetManagerWorker.postMessage({
|
||||
floorItems,
|
||||
cameraPosition,
|
||||
uuids,
|
||||
renderDistance,
|
||||
});
|
||||
}, [camMode, renderDistance]);
|
||||
|
||||
useEffect(() => {
|
||||
assetManagerWorker.onmessage = async (event) => {
|
||||
cancelOngoingTasks(); // Cancel the ongoing process
|
||||
await assetManager(event.data, itemsGroup, loader);
|
||||
};
|
||||
}, [assetManagerWorker]);
|
||||
useEffect(() => {
|
||||
const controls: any = state.controls;
|
||||
const camera: any = state.camera;
|
||||
|
||||
useEffect(() => {
|
||||
if (controls) {
|
||||
let intervalId: NodeJS.Timeout | null = null;
|
||||
|
||||
const handleChange = () => {
|
||||
if (toggleView) return;
|
||||
|
||||
const uuids: string[] = [];
|
||||
itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
|
||||
const cameraPosition = state.camera.position;
|
||||
itemsGroup.current?.children.forEach((child: any) => {
|
||||
uuids.push(child.uuid);
|
||||
});
|
||||
const cameraPosition = camera.position;
|
||||
|
||||
assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
|
||||
}, [camMode, renderDistance]);
|
||||
assetManagerWorker.postMessage({
|
||||
floorItems,
|
||||
cameraPosition,
|
||||
uuids,
|
||||
renderDistance,
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const controls: any = state.controls;
|
||||
const camera: any = state.camera;
|
||||
|
||||
if (controls) {
|
||||
let intervalId: NodeJS.Timeout | null = null;
|
||||
|
||||
const handleChange = () => {
|
||||
if (toggleView) return;
|
||||
|
||||
const uuids: string[] = [];
|
||||
itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
|
||||
const cameraPosition = camera.position;
|
||||
|
||||
assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
|
||||
};
|
||||
|
||||
const startInterval = () => {
|
||||
if (!intervalId) {
|
||||
intervalId = setInterval(handleChange, 50);
|
||||
}
|
||||
};
|
||||
|
||||
const stopInterval = () => {
|
||||
handleChange();
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
};
|
||||
|
||||
controls.addEventListener("rest", handleChange);
|
||||
controls.addEventListener("rest", stopInterval);
|
||||
controls.addEventListener("control", startInterval);
|
||||
controls.addEventListener("controlend", stopInterval);
|
||||
|
||||
return () => {
|
||||
controls.removeEventListener("rest", handleChange);
|
||||
controls.removeEventListener("rest", stopInterval);
|
||||
controls.removeEventListener("control", startInterval);
|
||||
controls.removeEventListener("controlend", stopInterval);
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
};
|
||||
const startInterval = () => {
|
||||
if (!intervalId) {
|
||||
intervalId = setInterval(handleChange, 50);
|
||||
}
|
||||
}, [state.controls, floorItems, toggleView, renderDistance]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = state.gl.domElement;
|
||||
let drag = false;
|
||||
let isLeftMouseDown = false;
|
||||
|
||||
const onMouseDown = (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = true;
|
||||
drag = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseMove = () => {
|
||||
if (isLeftMouseDown) {
|
||||
drag = true;
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseUp = async (evt: any) => {
|
||||
if (controls) {
|
||||
(controls as any).enabled = true;
|
||||
}
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (drag) return;
|
||||
|
||||
if (deleteTool) {
|
||||
DeleteFloorItems(itemsGroup, hoveredDeletableFloorItem, setFloorItems, socket);
|
||||
}
|
||||
const Mode = transformMode;
|
||||
|
||||
if (Mode !== null || activeTool === "cursor") {
|
||||
if (!itemsGroup.current) return;
|
||||
let intersects = raycaster.intersectObjects(
|
||||
itemsGroup.current.children,
|
||||
true
|
||||
);
|
||||
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
||||
// let currentObject = intersects[0].object;
|
||||
// while (currentObject) {
|
||||
// if (currentObject.name === "Scene") {
|
||||
// break;
|
||||
// }
|
||||
// currentObject = currentObject.parent as THREE.Object3D;
|
||||
// }
|
||||
// if (currentObject) {
|
||||
// AttachedObject.current = currentObject as any;
|
||||
// setSelectedFloorItem(AttachedObject.current!);
|
||||
// }
|
||||
} else {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
await controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDblClick = async (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (drag) return;
|
||||
|
||||
const Mode = transformMode;
|
||||
|
||||
if (Mode !== null || activeTool === "cursor") {
|
||||
if (!itemsGroup.current) return;
|
||||
let intersects = raycaster.intersectObjects(itemsGroup.current.children, true);
|
||||
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
||||
let currentObject = intersects[0].object;
|
||||
|
||||
while (currentObject) {
|
||||
if (currentObject.name === "Scene") {
|
||||
break;
|
||||
}
|
||||
currentObject = currentObject.parent as THREE.Object3D;
|
||||
}
|
||||
if (currentObject) {
|
||||
AttachedObject.current = currentObject as any;
|
||||
// controls.fitToSphere(AttachedObject.current!, true);
|
||||
|
||||
const bbox = new THREE.Box3().setFromObject(AttachedObject.current);
|
||||
const size = bbox.getSize(new THREE.Vector3());
|
||||
const center = bbox.getCenter(new THREE.Vector3());
|
||||
|
||||
const front = new THREE.Vector3(0, 0, 1);
|
||||
AttachedObject.current.localToWorld(front);
|
||||
front.sub(AttachedObject.current.position).normalize();
|
||||
|
||||
const distance = Math.max(size.x, size.y, size.z) * 2;
|
||||
const newPosition = center.clone().addScaledVector(front, distance);
|
||||
|
||||
controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
|
||||
controls.setTarget(center.x, center.y, center.z, true);
|
||||
controls.fitToBox(AttachedObject.current!, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
||||
|
||||
setSelectedFloorItem(AttachedObject.current!);
|
||||
}
|
||||
} else {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
await controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDrop = (event: any) => {
|
||||
if (!event.dataTransfer?.files[0]) return;
|
||||
|
||||
if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
|
||||
addAssetModel(raycaster, state.camera, state.pointer, floorGroup, setFloorItems, itemsGroup, isTempLoader, tempLoader, socket, selectedItem, setSelectedItem, addEvent, plane);
|
||||
}
|
||||
};
|
||||
|
||||
const onDragOver = (event: any) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
if (activeModule === "builder") {
|
||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||
canvasElement.addEventListener("dblclick", onDblClick);
|
||||
canvasElement.addEventListener("drop", onDrop);
|
||||
canvasElement.addEventListener("dragover", onDragOver);
|
||||
} else {
|
||||
if (controls) {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
const stopInterval = () => {
|
||||
handleChange();
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
};
|
||||
|
||||
return () => {
|
||||
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||
canvasElement.removeEventListener("dblclick", onDblClick);
|
||||
canvasElement.removeEventListener("drop", onDrop);
|
||||
canvasElement.removeEventListener("dragover", onDragOver);
|
||||
};
|
||||
}, [deleteTool, transformMode, controls, selectedItem, state.camera, state.pointer, activeTool, activeModule,]);
|
||||
controls.addEventListener("rest", handleChange);
|
||||
controls.addEventListener("rest", stopInterval);
|
||||
controls.addEventListener("control", startInterval);
|
||||
controls.addEventListener("controlend", stopInterval);
|
||||
|
||||
useFrame(() => {
|
||||
if (controls)
|
||||
// assetVisibility(itemsGroup, state.camera.position, renderDistance);
|
||||
if (deleteTool && activeModule === "builder") {
|
||||
DeletableHoveredFloorItems(state, itemsGroup, hoveredDeletableFloorItem, setDeletableFloorItem);
|
||||
} else if (!deleteTool) {
|
||||
if (hoveredDeletableFloorItem.current) {
|
||||
hoveredDeletableFloorItem.current = undefined;
|
||||
setDeletableFloorItem(null);
|
||||
}
|
||||
return () => {
|
||||
controls.removeEventListener("rest", handleChange);
|
||||
controls.removeEventListener("rest", stopInterval);
|
||||
controls.removeEventListener("control", startInterval);
|
||||
controls.removeEventListener("controlend", stopInterval);
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [state.controls, floorItems, toggleView, renderDistance]);
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = state.gl.domElement;
|
||||
let drag = false;
|
||||
let isLeftMouseDown = false;
|
||||
|
||||
const onMouseDown = (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = true;
|
||||
drag = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseMove = () => {
|
||||
console.log('isLeftMouseDown: ', isLeftMouseDown);
|
||||
if (isLeftMouseDown) {
|
||||
drag = true;
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseUp = async (evt: any) => {
|
||||
if (controls) {
|
||||
(controls as any).enabled = true;
|
||||
}
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (drag) return;
|
||||
|
||||
if (deleteTool) {
|
||||
DeleteFloorItems(
|
||||
itemsGroup,
|
||||
hoveredDeletableFloorItem,
|
||||
setFloorItems,
|
||||
socket
|
||||
);
|
||||
}
|
||||
const Mode = transformMode;
|
||||
|
||||
if (Mode !== null || activeTool === "cursor") {
|
||||
if (!itemsGroup.current) return;
|
||||
let intersects = raycaster.intersectObjects(
|
||||
itemsGroup.current.children,
|
||||
true
|
||||
);
|
||||
if (
|
||||
intersects.length > 0 &&
|
||||
intersects[0]?.object?.parent?.parent?.position &&
|
||||
intersects[0]?.object?.parent?.parent?.scale &&
|
||||
intersects[0]?.object?.parent?.parent?.rotation
|
||||
) {
|
||||
// let currentObject = intersects[0].object;
|
||||
// while (currentObject) {
|
||||
// if (currentObject.name === "Scene") {
|
||||
// break;
|
||||
// }
|
||||
// currentObject = currentObject.parent as THREE.Object3D;
|
||||
// }
|
||||
// if (currentObject) {
|
||||
// AttachedObject.current = currentObject as any;
|
||||
// setSelectedFloorItem(AttachedObject.current!);
|
||||
// }
|
||||
} else {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
await controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDblClick = async (evt: any) => {
|
||||
if (evt.button === 0) {
|
||||
isLeftMouseDown = false;
|
||||
if (drag) return;
|
||||
|
||||
const Mode = transformMode;
|
||||
|
||||
if (Mode !== null || activeTool === "cursor") {
|
||||
if (!itemsGroup.current) return;
|
||||
let intersects = raycaster.intersectObjects(
|
||||
itemsGroup.current.children,
|
||||
true
|
||||
);
|
||||
if (
|
||||
intersects.length > 0 &&
|
||||
intersects[0]?.object?.parent?.parent?.position &&
|
||||
intersects[0]?.object?.parent?.parent?.scale &&
|
||||
intersects[0]?.object?.parent?.parent?.rotation
|
||||
) {
|
||||
let currentObject = intersects[0].object;
|
||||
|
||||
while (currentObject) {
|
||||
if (currentObject.name === "Scene") {
|
||||
break;
|
||||
}
|
||||
currentObject = currentObject.parent as THREE.Object3D;
|
||||
}
|
||||
});
|
||||
if (currentObject) {
|
||||
AttachedObject.current = currentObject as any;
|
||||
// controls.fitToSphere(AttachedObject.current!, true);
|
||||
|
||||
return <group ref={itemsGroup} name="itemsGroup"></group>;
|
||||
const bbox = new THREE.Box3().setFromObject(
|
||||
AttachedObject.current
|
||||
);
|
||||
const size = bbox.getSize(new THREE.Vector3());
|
||||
const center = bbox.getCenter(new THREE.Vector3());
|
||||
|
||||
const front = new THREE.Vector3(0, 0, 1);
|
||||
AttachedObject.current.localToWorld(front);
|
||||
front.sub(AttachedObject.current.position).normalize();
|
||||
|
||||
const distance = Math.max(size.x, size.y, size.z) * 2;
|
||||
const newPosition = center
|
||||
.clone()
|
||||
.addScaledVector(front, distance);
|
||||
|
||||
controls.setPosition(
|
||||
newPosition.x,
|
||||
newPosition.y,
|
||||
newPosition.z,
|
||||
true
|
||||
);
|
||||
controls.setTarget(center.x, center.y, center.z, true);
|
||||
controls.fitToBox(AttachedObject.current!, true, {
|
||||
cover: true,
|
||||
paddingTop: 5,
|
||||
paddingLeft: 5,
|
||||
paddingBottom: 5,
|
||||
paddingRight: 5,
|
||||
});
|
||||
|
||||
setSelectedFloorItem(AttachedObject.current!);
|
||||
}
|
||||
} else {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
await controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDrop = (event: any) => {
|
||||
if (!event.dataTransfer?.files[0]) return;
|
||||
|
||||
if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
|
||||
addAssetModel(
|
||||
raycaster,
|
||||
state.camera,
|
||||
state.pointer,
|
||||
floorGroup,
|
||||
setFloorItems,
|
||||
itemsGroup,
|
||||
isTempLoader,
|
||||
tempLoader,
|
||||
socket,
|
||||
selectedItem,
|
||||
setSelectedItem,
|
||||
addEvent,
|
||||
plane
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const onDragOver = (event: any) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
if (activeModule === "builder") {
|
||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||
canvasElement.addEventListener("dblclick", onDblClick);
|
||||
canvasElement.addEventListener("drop", onDrop);
|
||||
canvasElement.addEventListener("dragover", onDragOver);
|
||||
} else {
|
||||
if (controls) {
|
||||
const target = controls.getTarget(new THREE.Vector3());
|
||||
controls.setTarget(target.x, 0, target.z, true);
|
||||
setSelectedFloorItem(null);
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||
canvasElement.removeEventListener("dblclick", onDblClick);
|
||||
canvasElement.removeEventListener("drop", onDrop);
|
||||
canvasElement.removeEventListener("dragover", onDragOver);
|
||||
};
|
||||
}, [
|
||||
deleteTool,
|
||||
transformMode,
|
||||
controls,
|
||||
selectedItem,
|
||||
state.camera,
|
||||
state.pointer,
|
||||
activeTool,
|
||||
activeModule,
|
||||
]);
|
||||
|
||||
useFrame(() => {
|
||||
if (controls)
|
||||
if (deleteTool && activeModule === "builder") {
|
||||
// assetVisibility(itemsGroup, state.camera.position, renderDistance);
|
||||
DeletableHoveredFloorItems(
|
||||
state,
|
||||
itemsGroup,
|
||||
hoveredDeletableFloorItem,
|
||||
setDeletableFloorItem
|
||||
);
|
||||
} else if (!deleteTool) {
|
||||
if (hoveredDeletableFloorItem.current) {
|
||||
hoveredDeletableFloorItem.current = undefined;
|
||||
setDeletableFloorItem(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return <group ref={itemsGroup} name="itemsGroup"></group>;
|
||||
};
|
||||
|
||||
export default FloorItemsGroup;
|
||||
|
|
|
@ -104,7 +104,6 @@
|
|||
|
||||
.metrics-section {
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--background-color-gray);
|
||||
|
||||
.metric {
|
||||
display: flex;
|
||||
|
@ -124,7 +123,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.throughoutSummary-wrapper {
|
||||
.production-wrapper {
|
||||
.process-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -172,6 +171,8 @@
|
|||
.footer-card {
|
||||
width: 100%;
|
||||
background: var(--background-color-gray);
|
||||
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
|
@ -303,15 +304,19 @@
|
|||
border: 1px solid var(--border-color);
|
||||
|
||||
.info {
|
||||
opacity: 0.8;
|
||||
|
||||
span {
|
||||
font-size: var(--font-size-xlarge);
|
||||
|
||||
&:first-child {
|
||||
color: #31c756;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
color: var(--text-color);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -361,6 +366,8 @@
|
|||
|
||||
&:last-child {
|
||||
align-items: center;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
|
@ -378,6 +385,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
.metric-item.net-profit {
|
||||
.metric-label {
|
||||
|
||||
span {
|
||||
color: #21ad50;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.metric-wrapper {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
|
@ -446,6 +462,7 @@
|
|||
padding: 8px;
|
||||
text-align: left;
|
||||
border: 1px solid var(--border-color);
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
th {
|
||||
|
@ -486,6 +503,24 @@
|
|||
color: #488ef6;
|
||||
}
|
||||
}
|
||||
|
||||
.placeHolder-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding-top: 6px;
|
||||
|
||||
.placeHolder {
|
||||
height: 11px;
|
||||
width: 100%;
|
||||
background: #EAEAEA;
|
||||
border-radius: 4px;
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue