diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/slider/Slider.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/slider/Slider.jsx index 8f61d725..827c0253 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/slider/Slider.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_components/slider/Slider.jsx @@ -4,44 +4,107 @@ import MUI_Slider from "@mui/material/Slider"; import clsx from "clsx"; export const Slider = (props) => { + const location = props.valueLabelDisplayLocation || "top"; + + const sliderSx = { + color: "var(--dark_700_color)", + "& .MuiSlider-thumb": { + backgroundColor: "var(--primary_600_color)", + "&:hover, &.Mui-focusVisible, &.Mui-active": { + boxShadow: `0 0 0 0.8rem var(--primary_600_color_44)`, + }, + "& .MuiSlider-valueLabel": { + position: "absolute", + backgroundColor: "var(--dark_800_color)", + width: "fit-content", + minWidth: "4.8rem", + padding: "0.4rem 0.8rem", + lineHeight: "1.15", + "& .MuiSlider-valueLabelLabel": { + fontSize: "1.4rem", + }, + ...(location === "top" && { + top: "-110%", + left: "50%", + transform: "translate(-50%, -50%) scale(0)", + transformOrigin: "bottom center", + "&.MuiSlider-valueLabelOpen": { + transform: "translate(-50%, -50%) scale(1)", + }, + "&::before": { + bottom: "0%", + left: "50%", + }, + }), + ...(location === "right" && { + top: "50%", + left: "150%", + transform: "translate(0, -50%) scale(0)", + transformOrigin: "left center", + "&.MuiSlider-valueLabelOpen": { + transform: "translate(0, -50%) scale(1)", + }, + "&::before": { + bottom: "50%", + left: "0", + }, + }), + ...(location === "left" && { + // top: "50%", + // right: "50%", + // transform: "translate(-50%, -50%) scale(0)", + // transformOrigin: "bottom center", + // "&.MuiSlider-valueLabelOpen": { + // transform: "translate(-50%, -50%) scale(1)", + // }, + // "&::before": { + // bottom: "50%", + // left: "100%", + // }, + }), + }, + }, + "& .MuiSlider-markLabel": { + fontSize: "1.4rem", + color: "var(--dark_550_color)", + whiteSpace: "nowrap", + }, + "& .MuiSlider-markLabelActive": { + color: "var(--primary_300_color)", + }, + }; + return ( -
{t("config_page.vr.x_position")} @@ -205,8 +249,16 @@ const PositionControls = ({settings, onchangeFunction, selectFunction, ui_config min={ui_configs.x_pos.min} max={ui_configs.x_pos.max} onchangeFunction={(value) => onchangeFunction("x_pos", value)} + valueLabelDisplay={x_variable_display} + valueLabelDisplayLocation="top" /> +
{t("config_page.vr.y_position")} @@ -221,8 +273,16 @@ const PositionControls = ({settings, onchangeFunction, selectFunction, ui_config max={ui_configs.y_pos.max} onchangeFunction={(value) => onchangeFunction("y_pos", value)} orientation="vertical" + valueLabelDisplay={y_variable_display} + valueLabelDisplayLocation="right" /> +
{t("config_page.vr.z_position")} @@ -237,69 +297,127 @@ const PositionControls = ({settings, onchangeFunction, selectFunction, ui_config max={ui_configs.z_pos.max} onchangeFunction={(value) => onchangeFunction("z_pos", value)} orientation="vertical" + valueLabelDisplay={z_variable_display} + valueLabelDisplayLocation="left" /> +
{t("config_page.vr.x_rotation")}
-
{t("config_page.vr.y_rotation")}
-
{t("config_page.vr.z_rotation")}
-
{label}
); +}; + + + +const useVariableControl = (key, settings, onchangeFunction, ui_configs) => { + const [variable_display, setVariableDisplay] = useState("auto"); + + const [is_max, setIsMax] = useState(settings[key] >= ui_configs[key].max); + const [is_min, setIsMin] = useState(settings[key] <= ui_configs[key].min); + + const timerRef = useRef(); + + // アンマウント時にタイマーをクリアする + useEffect(() => { + return () => { + clearTimeout(timerRef.current); + }; + }, []); + + const triggerDisplay = () => { + setVariableDisplay("on"); + clearTimeout(timerRef.current); + timerRef.current = setTimeout(() => { + setVariableDisplay("auto"); + }, 2000); + }; + + useEffect(() => { + setIsMax(settings[key] >= ui_configs[key].max); + setIsMin(settings[key] <= ui_configs[key].min); + }, [settings[key]]); + + const countUp = () => { + if (is_max) return; + const step = ui_configs[key].step; + const new_value = parseFloat((settings[key] + step).toFixed(2)); + onchangeFunction(key, new_value); + triggerDisplay(); + }; + + const countDown = () => { + if (is_min) return; + const step = ui_configs[key].step; + const new_value = parseFloat((settings[key] - step).toFixed(2)); + onchangeFunction(key, new_value); + triggerDisplay(); + }; + + return { + variable_display, + is_max, + is_min, + countUp, + countDown, + }; }; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/vr/Vr.module.scss b/src-ui/app/config_page/setting_section/setting_box/vr/Vr.module.scss index 35798530..eb37c7ea 100644 --- a/src-ui/app/config_page/setting_section/setting_box/vr/Vr.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/vr/Vr.module.scss @@ -16,7 +16,7 @@ justify-content: center; width: 100%; max-width: 56rem; - gap: 2rem; + gap: 4rem; } .controller_type_switch { @@ -58,12 +58,13 @@ .sample_text_button_wrapper { position: absolute; - bottom: 0; - left: -74%; + bottom: -12%; + left: -80%; display: flex; justify-content: center; align-items: center; flex-direction: column; + // transform: translate(-50%, -50%); } .sample_text_button { background-color: var(--dark_850_color); @@ -121,20 +122,20 @@ } .x_position_label { position: absolute; - bottom: -4.6rem; + bottom: -5rem; right: -46%; justify-content: end; } .y_position_label { position: absolute; - top: -44%; - left: 10%; - justify-content: start; + bottom: 110%; + right: 119%; + justify-content: end; } .z_position_label { position: absolute; - top: 30%; - left: 80%; + top: 14%; + left: 110%; } .x_position_slider { @@ -155,14 +156,72 @@ .z_position_slider { position: absolute; - bottom: 61%; - left: 61%; + bottom: 80%; + left: 88%; transform: translate(50%,50%) rotate(45deg); width: 0%; height: 100%; } +%variable-button { + width: 3.8rem; + border-radius: 0.4rem; + aspect-ratio: 1.2 / 1; + background-color: var(--dark_850_color); + display: flex; + justify-content: center; + align-items: center; + font-size: 1.6rem; + cursor: pointer; + + &:hover { + background-color: var(--primary_500_color); + } + &:active { + background-color: var(--primary_600_color); + } + &.is_disabled { + pointer-events: none; + background-color: var(--dark_875_color); + color: var(--dark_600_color); + } +} + +@mixin variable-button-wrapper($vertical-pos, $vertical-value, $horizontal-pos, $horizontal-value, $rotate: 0deg) { + position: absolute; + #{$vertical-pos}: $vertical-value; + #{$horizontal-pos}: $horizontal-value; + display: flex; + gap: 1.6rem; + flex-direction: column; + transform: translate(-50%) rotate($rotate); +} + +.y_position_button_wrapper { + @include variable-button-wrapper(top, 30%, left, -26%); +} +.y_position_button_up, +.y_position_button_down { + @extend %variable-button; +} + +.x_position_button_wrapper { + @include variable-button-wrapper(bottom, -38%, left, 46%, 90deg); +} +.x_position_button_up, +.x_position_button_down { + @extend %variable-button; +} + +.z_position_button_wrapper { + @include variable-button-wrapper(bottom, 26%, right, -4%, 45deg); +} +.z_position_button_up, +.z_position_button_down { + @extend %variable-button; +} + // .rotation_controls { @@ -175,19 +234,20 @@ .x_rotation_label { position: absolute; - top: -44%; - left: 10%; + bottom: 110%; + right: 119%; + justify-content: end; } .y_rotation_label { position: absolute; - bottom: -4.6rem; + bottom: -5rem; right: -46%; justify-content: end; } .z_rotation_label { position: absolute; - top: -10%; - right: -110%; + top: -20%; + right: -100%; } .x_rotation_slider { @@ -216,6 +276,34 @@ } + +.x_rotation_button_wrapper { + @include variable-button-wrapper(top, 30%, left, -26%); +} +.x_rotation_button_up, +.x_rotation_button_down { + @extend %variable-button; +} + +.y_rotation_button_wrapper { + @include variable-button-wrapper(bottom, -38%, left, 46%, 90deg); +} +.y_rotation_button_up, +.y_rotation_button_down { + @extend %variable-button; +} + +.z_rotation_button_wrapper { + @include variable-button-wrapper(bottom, 50%, right, -60%, -45deg); +} +.z_rotation_button_up, +.z_rotation_button_down { + @extend %variable-button; +} + + + + .slider_reset_button { background-color: var(--dark_875_color); padding: 0.6rem; diff --git a/src-ui/ui_configs.js b/src-ui/ui_configs.js index d6ef28eb..915d6a6b 100644 --- a/src-ui/ui_configs.js +++ b/src-ui/ui_configs.js @@ -7,12 +7,18 @@ export const ui_configs = { x_pos: { step: 0.05, min: -0.5, max: 0.5 }, y_pos: { step: 0.05, min: -0.8, max: 0.8 }, z_pos: { step: 0.05, min: -0.5, max: 1.5 }, + x_rotation: { min: -180, max: 180, step: 5 }, + y_rotation: { min: -180, max: 180, step: 5 }, + z_rotation: { min: -180, max: 180, step: 5 }, ui_scaling: { step: 10, min: 40, max: 200 }, }, overlay_large_log: { x_pos: { step: 0.05, min: -0.5, max: 0.5 }, y_pos: { step: 0.05, min: -0.8, max: 0.8 }, z_pos: { step: 0.05, min: -0.5, max: 1.5 }, + x_rotation: { min: -180, max: 180, step: 5 }, + y_rotation: { min: -180, max: 180, step: 5 }, + z_rotation: { min: -180, max: 180, step: 5 }, ui_scaling: { step: 10, min: 40, max: 200 }, },