diff --git a/package-lock.json b/package-lock.json index 149426d0..88b208ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.9.0", "license": "ISC", "dependencies": { - "@aics/simularium-viewer": "^3.6.1", + "@aics/simularium-viewer": "^3.6.2", "@ant-design/css-animation": "^1.7.3", "@ant-design/icons": "^4.0.6", "antd": "^4.23.6", @@ -111,9 +111,9 @@ "dev": true }, "node_modules/@aics/simularium-viewer": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@aics/simularium-viewer/-/simularium-viewer-3.6.1.tgz", - "integrity": "sha512-vP5PsMHc8J3BJg7D2bXz7eeSKom+TSkgs6gr5OKSqcZif4OljOgQEowEZH6MaYLviY+Xpyt1KSO3bg8BB2ExkQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@aics/simularium-viewer/-/simularium-viewer-3.6.2.tgz", + "integrity": "sha512-QTuxtExeqFYhAmfr4VFqpu9QKVqd0Vg1znaDFUyV4qGEr9W1hDlA2evxK3c3PXnNn/wNCWEE1SnrWRjSzjesIA==", "dependencies": { "@fortawesome/fontawesome-free": "^5.15.2", "@fortawesome/fontawesome-svg-core": "~1.2.34", @@ -24354,9 +24354,9 @@ "dev": true }, "@aics/simularium-viewer": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@aics/simularium-viewer/-/simularium-viewer-3.6.1.tgz", - "integrity": "sha512-vP5PsMHc8J3BJg7D2bXz7eeSKom+TSkgs6gr5OKSqcZif4OljOgQEowEZH6MaYLviY+Xpyt1KSO3bg8BB2ExkQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@aics/simularium-viewer/-/simularium-viewer-3.6.2.tgz", + "integrity": "sha512-QTuxtExeqFYhAmfr4VFqpu9QKVqd0Vg1znaDFUyV4qGEr9W1hDlA2evxK3c3PXnNn/wNCWEE1SnrWRjSzjesIA==", "requires": { "@fortawesome/fontawesome-free": "^5.15.2", "@fortawesome/fontawesome-svg-core": "~1.2.34", diff --git a/package.json b/package.json index 9ed9b5d9..f71e7e5a 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "webpack-dev-server": "^4.10.1" }, "dependencies": { - "@aics/simularium-viewer": "^3.6.1", + "@aics/simularium-viewer": "^3.6.2", "@ant-design/css-animation": "^1.7.3", "@ant-design/icons": "^4.0.6", "antd": "^4.23.6", diff --git a/src/assets/orthographic.svg b/src/assets/orthographic.svg new file mode 100644 index 00000000..b2295316 --- /dev/null +++ b/src/assets/orthographic.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/assets/perspective.svg b/src/assets/perspective.svg new file mode 100644 index 00000000..558fca8e --- /dev/null +++ b/src/assets/perspective.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/CameraControls/index.tsx b/src/components/CameraControls/index.tsx index aed5086f..565a4a65 100644 --- a/src/components/CameraControls/index.tsx +++ b/src/components/CameraControls/index.tsx @@ -10,12 +10,21 @@ import styles from "./style.css"; const PAN = "pan"; const ROTATE = "rotate"; +const ORTHOGRAPHIC = "o"; +const PERSPECTIVE = "p"; const CAMERA_MODE_MODIFIER_KEYS = ["Meta", "Shift"]; const ZOOM_IN_HK = "ArrowUp"; const ZOOM_OUT_HK = "ArrowDown"; const RESET_HK = "h"; const FOCUS_HK = "f"; -const HOT_KEYS = [ZOOM_IN_HK, ZOOM_OUT_HK, RESET_HK, FOCUS_HK]; +const HOT_KEYS = [ + ZOOM_IN_HK, + ZOOM_OUT_HK, + RESET_HK, + FOCUS_HK, + ORTHOGRAPHIC, + PERSPECTIVE, +]; interface CameraControlsProps { resetCamera: () => void; @@ -23,6 +32,7 @@ interface CameraControlsProps { zoomOut: () => void; setPanningMode: (value: boolean) => void; setFocusMode: (value: boolean) => void; + setCameraType: (value: boolean) => void; } const CameraControls = ({ @@ -31,9 +41,12 @@ const CameraControls = ({ zoomOut, setPanningMode, setFocusMode, + setCameraType, }: CameraControlsProps): JSX.Element => { const [isFocused, saveFocusMode] = useState(true); const [mode, setMode] = useState(ROTATE); + const [cameraProjectionType, setCameraProjectionType] = + useState(PERSPECTIVE); const [keyPressed, setKeyPressed] = useState(""); const lastKeyPressed = useRef(""); @@ -91,6 +104,10 @@ const CameraControls = ({ } }, [mode]); + useEffect(() => { + setCameraType(cameraProjectionType === ORTHOGRAPHIC); + }, [cameraProjectionType]); + useEffect(() => { if ( (isModifierKey(keyPressed) && !lastKeyPressed.current) || @@ -113,6 +130,12 @@ const CameraControls = ({ case FOCUS_HK: saveFocusMode(!isFocused); break; + case ORTHOGRAPHIC: + setCameraProjectionType(ORTHOGRAPHIC); + break; + case PERSPECTIVE: + setCameraProjectionType(PERSPECTIVE); + break; default: break; } @@ -120,6 +143,30 @@ const CameraControls = ({ }, [keyPressed]); return (
+
+ +
- -
+
+
+ + {/* Should be radio buttons, but using radio buttons + detaches keypressed listener after the button is pressed */} + + + - - - + onClick={() => { + setCameraProjectionType(PERSPECTIVE); + }} + icon={Icons.PerspectiveCamera} + > + +
- -
- -
+ +
); diff --git a/src/styles/colors.css b/src/styles/colors.css index 25c6b10a..2b89c049 100644 --- a/src/styles/colors.css +++ b/src/styles/colors.css @@ -13,10 +13,12 @@ --white-six: #e7e7e7; --transparent-white: rgba(255, 255, 255, 0.65); --dim-gray: #383838; + --dim-gray-two: #6E6E6E; + --purplish-gray: #4A4658; --pale-grey: #ddd9ec; --heather: #bab5c9; --text-gray: #a0a0a0; - --greyish-brown: #4a4a4a; + --grayish-brown: #4a4a4a; --warm-gray: #979797; --charcoal-grey: #3b3649; --dark-blue-grey: #2d224d; @@ -72,4 +74,11 @@ --light-theme-modal-supplemental-text: var(--charcoal-grey); --light-theme-modal-btn-default-color: var(--dark-four); --light-theme-btn-default-disabled-bg: var(--heather); + --viewer-btn-bg-default: var(--dark-three); + --viewer-btn-bg-hover: var(--purplish-gray); + --viewer-btn-bg-disabled: var(--dark-three); + --viewer-btn-border-active: var( --white-three); + --viewer-btn-border-on: var(--dim-gray-two); + --viewer-btn-color-default: var(--white-three); + --viewer-btn-color-disabled: var(--grayish-brown); }