give movement controls transition animations

This commit is contained in:
HF 2024-01-24 02:51:43 +01:00
parent ad200cfcad
commit 2457382052
5 changed files with 101 additions and 88 deletions

View File

@ -39,7 +39,7 @@ persistStore(store, {}, () => {
window.imMobile = function checkMobile() {
delete window.imMobile;
store.dispatch(setMobile(true));
}
};
document.addEventListener('touchstart', window.imMobile, { once: true });
// listen for resize

View File

@ -20,22 +20,16 @@ const UI = () => {
isHistoricalView,
is3D,
isOnMobile,
showMvmCtrls,
holdPaint,
] = useSelector((state) => [
state.canvas.isHistoricalView,
state.canvas.is3D,
state.user.isOnMobile,
state.gui.showMvmCtrls,
state.gui.holdPaint,
], shallowEqual);
return (
<>
<Alert />
{(showMvmCtrls
|| (isOnMobile && (is3D || (holdPaint > 0) && !isHistoricalView))
) && <MovementControls />}
<MovementControls />
{(isHistoricalView) ? (
<HistorySelect />
) : (

View File

@ -3,13 +3,8 @@
* Menu for WASD keys for mobile users
*/
import React, {
useCallback,
} from 'react';
import {
useSelector,
useDispatch,
} from 'react-redux';
import React, { useState, useCallback, useEffect } from 'react';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import {
PiMagnifyingGlassMinus,
PiMagnifyingGlassPlus,
@ -22,96 +17,103 @@ import {
} from 'react-icons/pi';
import {
setMoveU,
setMoveV,
setMoveW,
cancelMove,
setMoveU, setMoveV, setMoveW, cancelMove,
} from '../../store/actions';
const btnStyle = {
// fontSize: 34,
};
import { selectMovementControlProps } from '../../store/selectors/gui';
const MovementControls = () => {
const is3D = useSelector((state) => state.canvas.is3D);
const [render, setRender] = useState(false);
const [is3D, open] = useSelector(
selectMovementControlProps,
shallowEqual,
);
const dispatch = useDispatch();
const onPressStart = useCallback((event) => {
event.preventDefault();
switch (event.currentTarget.id) {
case 'forwardbtn':
dispatch(setMoveV(-1));
break;
case 'backwardbtn':
dispatch(setMoveV(1));
break;
case 'leftbtn':
dispatch(setMoveU(-1));
break;
case 'rightbtn':
dispatch(setMoveU(1));
break;
case 'upbtn':
dispatch(setMoveW(-1));
break;
case 'downbtn':
dispatch(setMoveW(1));
break;
default:
}
}, [dispatch]);
const onPressStop = useCallback((event) => {
event.preventDefault();
switch (event.currentTarget.id) {
case 'forwardbtn':
dispatch(setMoveV(0));
break;
case 'backwardbtn':
dispatch(setMoveV(0));
break;
case 'leftbtn':
dispatch(setMoveU(0));
break;
case 'rightbtn':
dispatch(setMoveU(0));
break;
case 'upbtn':
dispatch(setMoveW(0));
break;
case 'downbtn':
dispatch(setMoveW(0));
break;
default:
}
}, [dispatch]);
const onCancel = useCallback((event) => {
event.preventDefault();
dispatch(cancelMove());
}, [dispatch]);
useEffect(() => {
if (open) window.setTimeout(() => setRender(true), 10);
}, [open]);
const refCallBack = useCallback((node) => {
if (!node) {
return;
}
const onPressStart = (event) => {
event.preventDefault();
switch (event.currentTarget.id) {
case 'forwardbtn':
dispatch(setMoveV(-1));
break;
case 'backwardbtn':
dispatch(setMoveV(1));
break;
case 'leftbtn':
dispatch(setMoveU(-1));
break;
case 'rightbtn':
dispatch(setMoveU(1));
break;
case 'upbtn':
dispatch(setMoveW(-1));
break;
case 'downbtn':
dispatch(setMoveW(1));
break;
default:
}
};
const onPressStop = (event) => {
event.preventDefault();
switch (event.currentTarget.id) {
case 'forwardbtn':
dispatch(setMoveV(0));
break;
case 'backwardbtn':
dispatch(setMoveV(0));
break;
case 'leftbtn':
dispatch(setMoveU(0));
break;
case 'rightbtn':
dispatch(setMoveU(0));
break;
case 'upbtn':
dispatch(setMoveW(0));
break;
case 'downbtn':
dispatch(setMoveW(0));
break;
default:
}
};
const onCancel = (event) => {
event.preventDefault();
dispatch(cancelMove());
};
node.addEventListener('touchstart', onPressStart, { passive: false });
node.addEventListener('mousedown', onPressStart, { passive: false });
node.addEventListener('touchend', onPressStop, { passive: false });
node.addEventListener('mouseup', onPressStop, { passive: false });
node.addEventListener('mouseleave', onCancel, { passive: false });
node.addEventListener('touchcancel', onCancel, { passive: false });
}, [onPressStart, onPressStop, onCancel]);
}, [dispatch]);
return (
<>
return ((render || open) && (
<div
id="mvmctrls"
className={render && open ? 'show' : ''}
onTransitionEnd={() => !open && setRender(false)}
>
<div
className="actionbuttons"
id="forwardbtn"
role="button"
key="forward"
tabIndex={0}
style={{
...btnStyle,
left: 57,
bottom: 139,
}}
@ -123,9 +125,9 @@ const MovementControls = () => {
className="actionbuttons"
id="backwardbtn"
role="button"
key="backward"
tabIndex={0}
style={{
...btnStyle,
left: 57,
bottom: 98,
}}
@ -137,9 +139,9 @@ const MovementControls = () => {
className="actionbuttons"
id="leftbtn"
role="button"
key="left"
tabIndex={0}
style={{
...btnStyle,
left: 16,
bottom: 98,
}}
@ -151,9 +153,9 @@ const MovementControls = () => {
className="actionbuttons"
id="rightbtn"
role="button"
key="right"
tabIndex={0}
style={{
...btnStyle,
left: 98,
bottom: 98,
}}
@ -165,6 +167,7 @@ const MovementControls = () => {
className="actionbuttons"
id="upbtn"
role="button"
key="up"
tabIndex={0}
style={{
left: 16,
@ -178,6 +181,7 @@ const MovementControls = () => {
className="actionbuttons"
id="downbtn"
role="button"
key="down"
tabIndex={0}
style={{
left: 98,
@ -187,8 +191,8 @@ const MovementControls = () => {
>
{(is3D) ? <PiCaretDoubleDown /> : <PiMagnifyingGlassPlus />}
</div>
</>
);
</div>
));
};
export default MovementControls;

View File

@ -7,3 +7,10 @@
export const selectIsDarkMode = (state) => (
state.gui.style.indexOf('dark') !== -1
);
export const selectMovementControlProps = (state) => [
state.canvas.is3D,
state.gui.showMvmCtrls || (state.user.isOnMobile
&& (state.canvas.is3D || (state.gui.holdPaint > 0)
&& !state.canvas.isHistoricalView)),
];

View File

@ -994,6 +994,14 @@ table td span {
background-color: #d2d2d2cc;
}
#mvmctrls {
transition: opacity 0.25s ease;
opacity: 0;
}
#mvmctrls.show {
opacity: 1;
}
#palettebox {
z-index: 1;
bottom: 59px;
@ -1024,7 +1032,7 @@ table td span {
}
.modal.show, .Alert.show, .overlay.show, .window.show {
opacity: 1;
opacity: 1;
}
.vemb {