diff --git a/react-components/src/components/RevealToolbar/MeasurementButton.tsx b/react-components/src/components/RevealToolbar/MeasurementButton.tsx new file mode 100644 index 00000000000..1de3cd629cf --- /dev/null +++ b/react-components/src/components/RevealToolbar/MeasurementButton.tsx @@ -0,0 +1,73 @@ +/*! + * Copyright 2023 Cognite AS + */ + +import { useMemo, type ReactElement, useState, useEffect } from 'react'; +import { useReveal } from '../RevealContainer/RevealContext'; +import { Button } from '@cognite/cogs.js'; +import { MeasurementTool } from '@cognite/reveal/tools'; +import { FEET_TO_INCHES, METERS_TO_FEET } from '../../utilities/constants'; + +const distancesInFeetAndMeters = (distanceInMeters: number): string => { + const distanceInFeet = distanceInMeters * METERS_TO_FEET; + const distanceInFeetInt = Math.floor(distanceInFeet); + const distanceInches = Math.round(FEET_TO_INCHES * (distanceInFeet - distanceInFeetInt)); + return `${distanceInMeters.toFixed(2)} m\n ${distanceInFeetInt}' ${distanceInches}''`; +}; + +export const MeasurementButton = (): ReactElement => { + const viewer = useReveal(); + const [measurementEnabled, setMeasurementEnabled] = useState(false); + + const measurementTool = useMemo(() => { + return new MeasurementTool(viewer, { + distanceToLabelCallback: (distanceInMeters: number) => { + return distancesInFeetAndMeters(distanceInMeters); + } + }); + }, [viewer]); + + const enterMeasurement = (): void => { + viewer.domElement.style.cursor = 'crosshair'; + measurementTool.enterMeasurementMode(); + measurementTool.visible(true); + }; + + const exitMeasurement = (): void => { + viewer.domElement.style.cursor = 'default'; + measurementTool.visible(false); + measurementTool.exitMeasurementMode(); + }; + + const handleMeasurement = (enable: boolean): void => { + if (viewer.models.length <= 0) { + return; + } + setMeasurementEnabled((prevState) => !prevState); + if (enable) { + enterMeasurement(); + } else { + exitMeasurement(); + } + }; + + useEffect(() => { + return () => { + if (measurementEnabled) { + exitMeasurement(); + } + }; + }, []); + + return ( +