From 8d05daf3763c657610d8f96f517d022896cf811a Mon Sep 17 00:00:00 2001 From: MyNameIsBatman Date: Tue, 15 Jun 2021 14:40:02 -0300 Subject: [PATCH] Room Widget Camera --- public/configuration.json | 220 ++++++++++++++++++ .../images/icons/camera-colormatrix.png | Bin 0 -> 249 bytes src/assets/images/icons/camera-composite.png | Bin 0 -> 204 bytes .../camera-widget/camera-spritesheet.png | Bin 6015 -> 6286 bytes .../room-widgets/camera-widget/selected.png | Bin 183 -> 0 bytes .../room-widgets/camera-widget/selector.png | Bin 154 -> 0 bytes src/assets/styles/icons.scss | 12 + .../card/content/NitroCardContentView.tsx | 2 +- .../content/NitroCardContextView.types.ts | 2 +- .../avatar-info/AvatarInfoWidgetView.tsx | 4 +- .../name/AvatarInfoWidgetNameView.types.ts | 2 +- .../room/widgets/camera/CameraWidgetView.scss | 107 +++++++-- .../room/widgets/camera/CameraWidgetView.tsx | 87 +++---- .../views/capture/CameraWidgetCaptureView.tsx | 102 ++++++++ .../capture/CameraWidgetCaptureView.types.ts | 5 + .../views/editor/CameraWidgetEditorView.tsx | 127 ++++++++++ .../editor/CameraWidgetEditorView.types.ts | 14 ++ 17 files changed, 615 insertions(+), 69 deletions(-) create mode 100644 src/assets/images/icons/camera-colormatrix.png create mode 100644 src/assets/images/icons/camera-composite.png delete mode 100644 src/assets/images/room-widgets/camera-widget/selected.png delete mode 100644 src/assets/images/room-widgets/camera-widget/selector.png create mode 100644 src/views/room/widgets/camera/views/capture/CameraWidgetCaptureView.tsx create mode 100644 src/views/room/widgets/camera/views/capture/CameraWidgetCaptureView.types.ts create mode 100644 src/views/room/widgets/camera/views/editor/CameraWidgetEditorView.tsx create mode 100644 src/views/room/widgets/camera/views/editor/CameraWidgetEditorView.types.ts diff --git a/public/configuration.json b/public/configuration.json index 7debfc8a..8be03e62 100644 --- a/public/configuration.json +++ b/public/configuration.json @@ -402,6 +402,226 @@ "isAmbassadorOnly": false } ], + "camera.available.effects": [ + { + "name":"dark_sepia", + "colorMatrix": [0.4, 0.4, 0.1, 0, 110, 0.3, 0.4, 0.1, 0, 30, 0.3, 0.2, 0.1, 0, 0, 0, 0, 0, 1, 0], + "minLevel": 0, + "enabled": true + }, + { + "name":"increase_saturation", + "colorMatrix": [2, -0.5, -0.5, 0, 0, -0.5, 2, -0.5, 0, 0, -0.5, -0.5, 2, 0, 0, 0, 0, 0, 1, 0], + "minLevel": 0, + "enabled": true + }, + { + "name":"increase_contrast", + "colorMatrix": [1.5, 0, 0, 0, -50, 0, 1.5, 0, 0, -50, 0, 0, 1.5, 0, -50, 0, 0, 0, 1.5, 0], + "minLevel": 0, + "enabled": true + }, + { + "name":"shadow_multiply_02", + "minLevel": 0, + "enabled": true + }, + { + "name":"color_1", + "colorMatrix": [0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 1, + "enabled": true + }, + { + "name":"hue_bright_sat", + "colorMatrix": [1, 0.6, 0.2, 0, -50, 0.2, 1, 0.6, 0, -50, 0.6, 0.2, 1, 0, -50, 0, 0, 0, 1, 0], + "minlevel": 1, + "enabled": true + }, + { + "name":"hearts_hardlight_02", + "minlevel": 1, + "enabled": true + }, + { + "name":"texture_overlay", + "minlevel": 1, + "enabled": true + }, + { + "name":"pinky_nrm", + "minlevel": 1, + "enabled": true + }, + { + "name":"color_2", "colorMatrix": [0.333, 0.333, 0.333, 0, 0, 0.333, 0.333, 0.333, 0, 0, 0.333, 0.333, 0.333, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 2, + "enabled": true + }, + { + "name":"night_vision", "colorMatrix": [0, 0, 0, 0, 0, 0, 1.1, 0, 0, -50, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 2, + "enabled": true + }, + { + "name":"stars_hardlight_02", + "minlevel": 2, + "enabled": true + }, + { + "name":"coffee_mpl", + "minlevel": 2, + "enabled": true + }, + { + "name":"security_hardlight", + "minlevel": 3, + "enabled": true + }, + { + "name":"bluemood_mpl", + "minlevel": 3, + "enabled": true + }, + { + "name":"rusty_mpl", + "minlevel": 3, + "enabled": true + }, + { + "name":"decr_conrast", + "colorMatrix": [0.5, 0, 0, 0, 50, 0, 0.5, 0, 0, 50, 0, 0, 0.5, 0, 50, 0, 0, 0, 1, 0], + "minlevel": 4, + "enabled": true + }, + { + "name":"green_2", + "colorMatrix": [0.5, 0.5, 0.5, 0, 0, 0.5, 0.5, 0.5, 0, 90, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 4, + "enabled": true + }, + { + "name":"alien_hrd", + "minlevel": 4, + "enabled": true + }, + { + "name":"color_3", + "colorMatrix": [0.609, 0.609, 0.082, 0, 0, 0.309, 0.609, 0.082, 0, 0, 0.309, 0.609, 0.082, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 5, + "enabled": true + }, + { + "name":"color_4", + "colorMatrix": [0.8, -0.8, 1, 0, 70, 0.8, -0.8, 1, 0, 70, 0.8, -0.8, 1, 0, 70, 0, 0, 0, 1, 0], + "minlevel": 5, + "enabled": true + }, + { + "name":"toxic_hrd", + "minlevel": 5, + "enabled": true + }, + { + "name":"hypersaturated", + "colorMatrix": [2, -1, 0, 0, 0, -1, 2, 0, 0, 0, 0, -1, 2, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 6, + "enabled": true + }, + { + "name":"Yellow", + "colorMatrix": [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 6, + "enabled": true + }, + { + "name":"misty_hrd", + "minlevel": 6, + "enabled": true + }, + { + "name":"x_ray", + "colorMatrix": [0, 1.2, 0, 0, -100, 0, 2, 0, 0, -120, 0, 2, 0, 0, -120, 0, 0, 0, 1, 0], + "minlevel": 7, + "enabled": true + }, + { + "name":"decrease_saturation", + "colorMatrix": [0.7, 0.2, 0.2, 0, 0, 0.2, 0.7, 0.2, 0, 0, 0.2, 0.2, 0.7, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 7, + "enabled": true + }, + { + "name":"drops_mpl", + "minlevel": 8, + "enabled": true + }, + { + "name":"shiny_hrd", + "minlevel": 9, + "enabled": true + }, + { + "name":"glitter_hrd", + "minlevel": 10, + "enabled": true + }, + { + "name":"frame_gold", + "minlevel": 10, + "enabled": true + }, + { + "name":"frame_gray_4", + "minlevel": 10, + "enabled": true + }, + { + "name":"frame_black_2", + "minlevel": 10, + "enabled": true + }, + { + "name":"frame_wood_2", + "minlevel": 10, + "enabled": true + }, + { + "name":"finger_nrm", + "minlevel": 10, + "enabled": true + }, + { + "name":"color_5", + "colorMatrix": [3.309, 0.609, 1.082, 0.2, 0, 0.309, 0.609, 0.082, 0, 0, 1.309, 0.609, 0.082, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 10, + "enabled": true + }, + { + "name":"black_white_negative", + "colorMatrix": [-0.5, -0.5, -0.5, 0, 0, -0.5, -0.5, -0.5, 0, 0, -0.5, -0.5, -0.5, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 10, + "enabled": true + }, + { + "name":"blue", + "colorMatrix": [0.5, 0.5, 0.5, 0, -255, 0.5, 0.5, 0.5, 0, -170, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 1, 0], + "minlevel": 10, + "enabled": true + }, + { + "name":"red", + "colorMatrix": [0.5, 0.5, 0.5, 0, 0, 0.5, 0.5, 0.5, 0, -170, 0.5, 0.5, 0.5, 0, -170, 0, 0, 0, 1, 0], + "minlevel": 10, + "enabled": true + }, + { + "name":"green", + "colorMatrix": [0.5, 0.5, 0.5, 0, -170, 0.5, 0.5, 0.5, 0, 0, 0.5, 0.5, 0.5, 0, -170, 0, 0, 0, 1, 0], + "minlevel": 10, + "enabled": true + } + ], "avatar.default.figuredata": " DDDDDD FAFAFA EEEEEE FA3831 FD92A0 2AC7D2 35332C EFFF92 C6FF98 FF925A 9D597E B6F3FF 6DFF33 3378C9 FFB631 DFA1E9 F9FB32 CAAF8F C5C6C5 47623D 8A8361 FF8C33 54C627 1E6C99 984F88 77C8FF FFC08E 3C4B87 7C2C47 D7FFE3 8F3F1C FF6393 1F9B79 FDFF33 ", "avatar.default.actions": { "actions": [ diff --git a/src/assets/images/icons/camera-colormatrix.png b/src/assets/images/icons/camera-colormatrix.png new file mode 100644 index 0000000000000000000000000000000000000000..894396e7c6ed77f3521136803563d1584e4fb3ab GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^3P3E%!3HGN&%SvDq&N#aB8wRqxP?HN@zUM8KS06N zo-U3d6}PTlJN+=Futz1o_Bvo~F!n_MR`C%BSmPI_b=T zsfSiRWLUIGO|M&{l;Pr6ZaeQ6VaG3T-pkIgUipN5^?}w6K$kFhy85}Sb4q9e0EszC As{jB1 literal 0 HcmV?d00001 diff --git a/src/assets/images/room-widgets/camera-widget/camera-spritesheet.png b/src/assets/images/room-widgets/camera-widget/camera-spritesheet.png index 3d3f418460ffbb57ae0157671e22c12a3d5753cb..f215f0c91131357abe403caaba790ff8c3b325ef 100644 GIT binary patch literal 6286 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 bW7fZMJ?bj0li!1XFyJ^o%e^mohQ|LN)PY}4 literal 6015 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 diff --git a/src/assets/images/room-widgets/camera-widget/selected.png b/src/assets/images/room-widgets/camera-widget/selected.png deleted file mode 100644 index 91a58b8602ae0e9404b55bf8efa2b2d2da878c7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^+91rq1|%QG79Idnb)GJcAr-gY-ZbPppupoC_-+dK zw`VV%T%$`hBs-M%E%njy=a{x*tDyKi_ZZ9a4dEwP*Y$>0EZ@JuOFmmHn^X8ul)X)u z@Ba^C2lZO_9r%1>$?V?b$xLE85gQT?HnDQU7`xT487~xE^Q~^%m1nb=QkGY}+`J<= bU&24p>v>7nr48$WE@AL=^>bP0l+XkKX-`I+ diff --git a/src/assets/images/room-widgets/camera-widget/selector.png b/src/assets/images/room-widgets/camera-widget/selector.png deleted file mode 100644 index f49ac8b325db92188108a4ece174f28c046e43e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+95~)y}6O|fB}!IWA3_( zvK%Zj?#zD<*akd(R-hTWH#*UH+of3>w71Gu+qsw|KAxa1CV~Zg$(Mfq#kMZ|-^PXW l=f69(+pu{piGkyR7 diff --git a/src/assets/styles/icons.scss b/src/assets/styles/icons.scss index 112bc679..dc97caba 100644 --- a/src/assets/styles/icons.scss +++ b/src/assets/styles/icons.scss @@ -446,6 +446,18 @@ i { height: 20px; } + &.icon-camera-colormatrix { + background: url('../images/icons/camera-colormatrix.png'); + width: 32px; + height: 14px; + } + + &.icon-camera-composite { + background: url('../images/icons/camera-composite.png'); + width: 32px; + height: 14px; + } + &.spin { animation: rotating 1s linear infinite; } diff --git a/src/layout/card/content/NitroCardContentView.tsx b/src/layout/card/content/NitroCardContentView.tsx index 4067d928..52986715 100644 --- a/src/layout/card/content/NitroCardContentView.tsx +++ b/src/layout/card/content/NitroCardContentView.tsx @@ -4,7 +4,7 @@ import { NitroCardContentViewProps } from './NitroCardContextView.types'; export const NitroCardContentView: FC = props => { return ( -
+
{ props.children }
); diff --git a/src/layout/card/content/NitroCardContextView.types.ts b/src/layout/card/content/NitroCardContextView.types.ts index 4c529598..78ff6979 100644 --- a/src/layout/card/content/NitroCardContextView.types.ts +++ b/src/layout/card/content/NitroCardContextView.types.ts @@ -1,4 +1,4 @@ export interface NitroCardContentViewProps { - + className?: string; } diff --git a/src/views/room/widgets/avatar-info/AvatarInfoWidgetView.tsx b/src/views/room/widgets/avatar-info/AvatarInfoWidgetView.tsx index 22689633..85249520 100644 --- a/src/views/room/widgets/avatar-info/AvatarInfoWidgetView.tsx +++ b/src/views/room/widgets/avatar-info/AvatarInfoWidgetView.tsx @@ -1,10 +1,10 @@ import { RoomObjectCategory } from 'nitro-renderer'; import { FC, useCallback, useState } from 'react'; +import { GetRoomObjectNameData } from '../../../../api/nitro/session/GetRoomObjectNameData'; +import { RoomObjectNameData } from '../../../../api/nitro/session/RoomObjectNameData'; import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base'; import { RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from '../events'; import { AvatarInfoWidgetViewProps } from './AvatarInfoWidgetView.types'; -import { GetRoomObjectNameData } from './utils/GetRoomObjectNameData'; -import { RoomObjectNameData } from './utils/RoomObjectNameData'; import { AvatarInfoWidgetNameView } from './views/name/AvatarInfoWidgetNameView'; export const AvatarInfoWidgetView: FC = props => diff --git a/src/views/room/widgets/avatar-info/views/name/AvatarInfoWidgetNameView.types.ts b/src/views/room/widgets/avatar-info/views/name/AvatarInfoWidgetNameView.types.ts index 7cf34445..7c10cb22 100644 --- a/src/views/room/widgets/avatar-info/views/name/AvatarInfoWidgetNameView.types.ts +++ b/src/views/room/widgets/avatar-info/views/name/AvatarInfoWidgetNameView.types.ts @@ -1,4 +1,4 @@ -import { RoomObjectNameData } from '../../utils/RoomObjectNameData'; +import { RoomObjectNameData } from '../../../../../../api/nitro/session/RoomObjectNameData'; export interface AvatarInfoWidgetNameViewProps { diff --git a/src/views/room/widgets/camera/CameraWidgetView.scss b/src/views/room/widgets/camera/CameraWidgetView.scss index 4b7f8363..e24d2e21 100644 --- a/src/views/room/widgets/camera/CameraWidgetView.scss +++ b/src/views/room/widgets/camera/CameraWidgetView.scss @@ -1,29 +1,94 @@ -.nitro-camera { - width: 340px; - height: 462px; +.nitro-camera-capture { + .camera-canvas { + width: 340px; + height: 462px; + + background-image: url('../../../../assets/images/room-widgets/camera-widget/camera-spritesheet.png'); - background-image: url('../../../../assets/images/room-widgets/camera-widget/camera-spritesheet.png'); + .camera-frame { + position: absolute; + width: 318px; + height: 318px; + margin-top: 9px; + margin-left: 11.4px; - .camera-frame { - width: 300px; - height: 300px; + &.bg { + background: black; + } + + .camera-frame-preview-actions { + background: rgba(0, 0, 0, .5); + } + } + + .camera-button { + width: 94px; + height: 94px; + cursor: pointer; + margin-top: 334px; + + background-image: url('../../../../assets/images/room-widgets/camera-widget/camera-spritesheet.png'); + background-position: -340px 0px; + + &:hover { + background-position: -340px -94px; + } + + &:active { + background-position: -340px -188px; + } + } } - .camera-button { - width: 94px; - height: 94px; - cursor: pointer; - margin-top: 334px; + .camera-roll { + width: 330px; + background: #bab8b4; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; + border: 1px solid black; + box-shadow: inset 1px 0px white, inset -1px -1px white; - background-image: url('../../../../assets/images/room-widgets/camera-widget/camera-spritesheet.png'); - background-position: -340px 0px; - - &:hover { - background-position: -340px -94px; - } - - &:active { - background-position: -340px -188px; + img { + width: 56px; + height: 56px; + border: 1px solid black; + } + } +} + +.nitro-camera-editor { + width: 600px; + + .effects { + max-height: 354px; + + .effect-thumbnail { + border-color: $grid-border-color !important; + background-color: $grid-bg-color; + + &.active { + border-color: $grid-active-border-color !important; + background-color: $grid-active-bg-color; + } + + .effect-thumbnail-image { + background: black; + + img { + width: 56px; + height: 56px; + } + } + } + } + + .picture-preview { + width: 318px; + height: 318px; + + &.zoomed { + background-size: 636px; + background-position: center; } } } diff --git a/src/views/room/widgets/camera/CameraWidgetView.tsx b/src/views/room/widgets/camera/CameraWidgetView.tsx index 00c3284d..6e3a3ad3 100644 --- a/src/views/room/widgets/camera/CameraWidgetView.tsx +++ b/src/views/room/widgets/camera/CameraWidgetView.tsx @@ -1,74 +1,75 @@ -import { NitroRectangle } from 'nitro-renderer'; -import { FC, useCallback, useRef, useState } from 'react'; -import { GetRoomEngine, GetRoomSession } from '../../../../api'; +import { RoomCameraWidgetEditorEffect } from 'nitro-renderer/src/nitro/room/camera-widget/RoomCameraWidgetEditorEffect'; +import { RoomCameraWidgetManagerEvent } from 'nitro-renderer/src/nitro/room/events/RoomCameraWidgetManagerEvent'; +import { FC, useCallback, useState } from 'react'; +import { GetRoomEngine } from '../../../../api'; import { RoomWidgetCameraEvent } from '../../../../events/room-widgets/camera/RoomWidgetCameraEvent'; -import { DraggableWindow } from '../../../../hooks/draggable-window/DraggableWindow'; +import { useRoomEngineEvent } from '../../../../hooks/events/nitro/room/room-engine-event'; import { useUiEvent } from '../../../../hooks/events/ui/ui-event'; import { CameraWidgetViewProps } from './CameraWidgetView.types'; +import { CameraWidgetCaptureView } from './views/capture/CameraWidgetCaptureView'; +import { CameraWidgetEditorView } from './views/editor/CameraWidgetEditorView'; export const CameraWidgetView: FC = props => { - const [ isVisible, setIsVisible ] = useState(false); - const cameraFrameRef = useRef(); + const [ isCaptureVisible, setIsCaptureVisible ] = useState(false); + const [ isEditorVisible, setIsEditorVisible ] = useState(false); + const [ chosenPicture, setChosenPicture ] = useState(null); + const [ availableEffects, setAvailableEffects ] = useState(null); - const onRoomWidgetCameraEvent = useCallback((event: RoomWidgetCameraEvent) => + const getAvailableEffects = useCallback(() => + { + if(GetRoomEngine().roomCameraWidgetManager.isLoaded) + { + setAvailableEffects(Array.from(GetRoomEngine().roomCameraWidgetManager.loadedEffects.values())); + } + }, []); + + const onNitroEvent = useCallback((event: RoomWidgetCameraEvent) => { switch(event.type) { case RoomWidgetCameraEvent.SHOW_CAMERA: - setIsVisible(true); + setIsCaptureVisible(true); + getAvailableEffects(); return; case RoomWidgetCameraEvent.HIDE_CAMERA: - setIsVisible(false); + setIsCaptureVisible(false); + setIsEditorVisible(false); return; case RoomWidgetCameraEvent.TOGGLE_CAMERA: - setIsVisible(value => !value); + setIsEditorVisible(false); + setIsCaptureVisible(value => !value); + getAvailableEffects(); + return; + case RoomCameraWidgetManagerEvent.INITIALIZED: + getAvailableEffects(); return; } }, []); - useUiEvent(RoomWidgetCameraEvent.SHOW_CAMERA, onRoomWidgetCameraEvent); - useUiEvent(RoomWidgetCameraEvent.HIDE_CAMERA, onRoomWidgetCameraEvent); - useUiEvent(RoomWidgetCameraEvent.TOGGLE_CAMERA, onRoomWidgetCameraEvent); + useUiEvent(RoomWidgetCameraEvent.SHOW_CAMERA, onNitroEvent); + useUiEvent(RoomWidgetCameraEvent.HIDE_CAMERA, onNitroEvent); + useUiEvent(RoomWidgetCameraEvent.TOGGLE_CAMERA, onNitroEvent); + useRoomEngineEvent(RoomCameraWidgetManagerEvent.INITIALIZED, onNitroEvent); - const processAction = useCallback((type: string, value: string = null) => + const processAction = useCallback((type: string, value: any = null) => { switch(type) { case 'close': - setIsVisible(false); + setIsCaptureVisible(false); + setIsEditorVisible(false); + return; + case 'capture_choose_picture': + setChosenPicture(value); + setIsCaptureVisible(false); + setIsEditorVisible(true); return; } }, []); - const takePicture = useCallback(() => - { - const frameBounds = cameraFrameRef.current.getBoundingClientRect(); - - if(!frameBounds) return; - - const rectangle = new NitroRectangle(Math.floor(frameBounds.x), Math.floor(frameBounds.y), Math.floor(frameBounds.width), Math.floor(frameBounds.height)); - - console.log(rectangle); - - GetRoomEngine().createRoomScreenshot(GetRoomSession().roomId, 1, rectangle); - }, []); - - if(!isVisible) return null; - return ( - -
-
-
processAction('close') }> - -
-
-
-
-
-
-
-
+ ( isCaptureVisible && processAction('close') } onChoosePicture={ (picture) => processAction('capture_choose_picture', picture) } /> ) || + ( isEditorVisible && processAction('close') } picture={ chosenPicture } availableEffects={ availableEffects } /> ) ); } diff --git a/src/views/room/widgets/camera/views/capture/CameraWidgetCaptureView.tsx b/src/views/room/widgets/camera/views/capture/CameraWidgetCaptureView.tsx new file mode 100644 index 00000000..e57f2626 --- /dev/null +++ b/src/views/room/widgets/camera/views/capture/CameraWidgetCaptureView.tsx @@ -0,0 +1,102 @@ +import classNames from 'classnames'; +import { NitroRectangle } from 'nitro-renderer'; +import { FC, useCallback, useRef, useState } from 'react'; +import { GetRoomEngine } from '../../../../../../api/nitro/room/GetRoomEngine'; +import { GetRoomSession } from '../../../../../../api/nitro/session/GetRoomSession'; +import { DraggableWindow } from '../../../../../../hooks/draggable-window/DraggableWindow'; +import { LocalizeText } from '../../../../../../utils/LocalizeText'; +import { CameraWidgetCaptureViewProps } from './CameraWidgetCaptureView.types'; + +export const CameraWidgetCaptureView: FC = props => +{ + const CAMERA_ROLL_LIMIT: number = 5; + + const [ picturesTaken, setPicturesTaken ] = useState([]); + const [ selectedPictureIndex, setSelectedPictureIndex ] = useState(-1); + const cameraFrameRef = useRef(); + + const takePicture = useCallback(() => + { + if(selectedPictureIndex > -1) + { + setSelectedPictureIndex(-1); + return; + } + + const frameBounds = cameraFrameRef.current.getBoundingClientRect(); + + if(!frameBounds) return; + + const rectangle = new NitroRectangle(Math.floor(frameBounds.x), Math.floor(frameBounds.y), Math.floor(frameBounds.width), Math.floor(frameBounds.height)); + + const image = GetRoomEngine().createRoomScreenshot(GetRoomSession().roomId, 1, rectangle); + + if(picturesTaken.length + 1 === CAMERA_ROLL_LIMIT) + { + alert(LocalizeText('camera.full.body')); + } + + if(picturesTaken.length === CAMERA_ROLL_LIMIT) + { + setPicturesTaken(picturesTaken => [ ...picturesTaken.slice(0, CAMERA_ROLL_LIMIT - 1), image ]); + } + else + { + setPicturesTaken(picturesTaken => [ ...picturesTaken, image ]); + } + }, [ picturesTaken, selectedPictureIndex ]); + + const processAction = useCallback((type: string, value: string | number = null) => + { + switch(type) + { + case 'take_picture': + takePicture(); + return; + case 'preview_picture': + setSelectedPictureIndex(Number(value)); + return; + case 'discard_picture': + setSelectedPictureIndex(-1); + const newPicturesTaken = picturesTaken; + picturesTaken.splice(selectedPictureIndex, 1); + setPicturesTaken(newPicturesTaken); + return; + case 'edit_picture': + props.onChoosePicture(picturesTaken[selectedPictureIndex]); + return; + } + }, [ picturesTaken, selectedPictureIndex ]); + + return ( + +
+
+
+
+ +
+
+
-1}) }> + { selectedPictureIndex > -1 &&
+ +
+ + +
+
} +
+
+
+
+
+ { picturesTaken.length > 0 &&
+ { picturesTaken.map((picture, index) => + { + return processAction('preview_picture', index) } />; + }) } +
} +
+
+ ); +} diff --git a/src/views/room/widgets/camera/views/capture/CameraWidgetCaptureView.types.ts b/src/views/room/widgets/camera/views/capture/CameraWidgetCaptureView.types.ts new file mode 100644 index 00000000..435e6d29 --- /dev/null +++ b/src/views/room/widgets/camera/views/capture/CameraWidgetCaptureView.types.ts @@ -0,0 +1,5 @@ +export interface CameraWidgetCaptureViewProps +{ + onCloseClick: () => void; + onChoosePicture: (picture: HTMLImageElement) => void; +} diff --git a/src/views/room/widgets/camera/views/editor/CameraWidgetEditorView.tsx b/src/views/room/widgets/camera/views/editor/CameraWidgetEditorView.tsx new file mode 100644 index 00000000..0153ced7 --- /dev/null +++ b/src/views/room/widgets/camera/views/editor/CameraWidgetEditorView.tsx @@ -0,0 +1,127 @@ +import classNames from 'classnames'; +import { RoomCameraWidgetEditorSelectedEffect } from 'nitro-renderer/src/nitro/room/camera-widget/RoomCameraWidgetEditorSelectedEffect'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { GetRoomEngine } from '../../../../../../api'; +import { NitroCardContentView } from '../../../../../../layout/card/content/NitroCardContentView'; +import { NitroCardHeaderView } from '../../../../../../layout/card/header/NitroCardHeaderView'; +import { NitroCardView } from '../../../../../../layout/card/NitroCardView'; +import { NitroCardTabsView } from '../../../../../../layout/card/tabs/NitroCardTabsView'; +import { NitroCardTabsItemView } from '../../../../../../layout/card/tabs/tabs-item/NitroCardTabsItemView'; +import { LocalizeText } from '../../../../../../utils/LocalizeText'; +import { CameraWidgetEditorTabs, CameraWidgetEditorViewProps } from './CameraWidgetEditorView.types'; + +export const CameraWidgetEditorView: FC = props => +{ + const TABS: string[] = [ CameraWidgetEditorTabs.COLORMATRIX, CameraWidgetEditorTabs.COMPOSITE ]; + const MY_LEVEL: number = 0; + + const [ currentTab, setCurrentTab ] = useState(CameraWidgetEditorTabs.COLORMATRIX); + const [ isZoomed, setIsZoomed ] = useState(false); + const [ selectedEffects, setSelectedEffects ] = useState([]); + const [ effectsThumbnails, setEffectThumbnails ] = useState<{name: string, image: HTMLImageElement}[]>([]); + + useEffect(() => + { + const thumbnails = []; + + for(const effect of props.availableEffects) + { + let alpha = 126; + + if(effect.colorMatrix.length > 0) alpha = 0.5; + + thumbnails.push({name: effect.name, image: GetRoomEngine().roomCameraWidgetManager.editImage(props.picture, [new RoomCameraWidgetEditorSelectedEffect(effect, alpha)])}); + } + + setEffectThumbnails(thumbnails); + }, [ props.availableEffects ]); + + const getEffectThumbnail = useCallback((effectName: string) => + { + const search = effectsThumbnails.find(thumbnail => thumbnail.name === effectName); + + if(search) return search.image.src; + + return null; + }, [ effectsThumbnails ]); + + const getEffectList = useCallback(() => + { + if(currentTab === CameraWidgetEditorTabs.COLORMATRIX) + { + return props.availableEffects.filter(effect => effect.colorMatrix.length > 0); + } + else + { + return props.availableEffects.filter(effect => effect.colorMatrix.length === 0); + } + }, [ currentTab, props.availableEffects ]); + + const processAction = useCallback((type: string, value: string | number = null) => + { + switch(type) + { + case 'close': + props.onCloseClick(); + return; + case 'change_tab': + setCurrentTab(String(value)); + return; + case 'zoom': + setIsZoomed(isZoomed => !isZoomed); + return; + } + }, []); + + return ( + + processAction('close') } /> +
+
+ + { TABS.map(tab => + { + return processAction('change_tab', tab) }> + }) } + + +
+
+ { getEffectList().map(effect => + { + return ( +
+
+
+ +
+
+
+ ); + }) } +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+ + +
+
+
+ ); +} diff --git a/src/views/room/widgets/camera/views/editor/CameraWidgetEditorView.types.ts b/src/views/room/widgets/camera/views/editor/CameraWidgetEditorView.types.ts new file mode 100644 index 00000000..4a3407c6 --- /dev/null +++ b/src/views/room/widgets/camera/views/editor/CameraWidgetEditorView.types.ts @@ -0,0 +1,14 @@ +import { RoomCameraWidgetEditorEffect } from '../../../../../../../../nitro-renderer/src/nitro/room/camera-widget/RoomCameraWidgetEditorEffect'; + +export interface CameraWidgetEditorViewProps +{ + onCloseClick: () => void; + picture: HTMLImageElement; + availableEffects: RoomCameraWidgetEditorEffect[]; +} + +export class CameraWidgetEditorTabs +{ + public static readonly COLORMATRIX: string = 'colormatrix'; + public static readonly COMPOSITE: string = 'composite'; +}