mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Add fading to context menu
This commit is contained in:
parent
78c25c21ee
commit
083f5ff0f3
@ -174,13 +174,18 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
setInfoStandEvent(null);
|
setInfoStandEvent(null);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const clearName = useCallback(() =>
|
||||||
|
{
|
||||||
|
setName(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const currentView = useMemo(() =>
|
const currentView = useMemo(() =>
|
||||||
{
|
{
|
||||||
if(isGameMode) return null;
|
if(isGameMode) return null;
|
||||||
|
|
||||||
if(decorateView) return decorateView;
|
if(decorateView) return decorateView;
|
||||||
|
|
||||||
if(name) return <AvatarInfoWidgetNameView event={ name } />;
|
if(name) return <AvatarInfoWidgetNameView nameData={ name } close={ clearName } />;
|
||||||
|
|
||||||
if(infoStandEvent)
|
if(infoStandEvent)
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@ export const AvatarInfoWidgetDecorateView: FC<AvatarInfoWidgetDecorateViewProps>
|
|||||||
const { userId = -1, userName = '', roomIndex = -1, setIsDecorating = null } = props;
|
const { userId = -1, userName = '', roomIndex = -1, setIsDecorating = null } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ roomIndex } category={ RoomObjectCategory.UNIT } onClose={ null }>
|
<ContextMenuView objectId={ roomIndex } category={ RoomObjectCategory.UNIT } close={ null }>
|
||||||
<ContextMenuListView>
|
<ContextMenuListView>
|
||||||
<ContextMenuListItemView onClick={ event => setIsDecorating(false) }>
|
<ContextMenuListItemView onClick={ event => setIsDecorating(false) }>
|
||||||
{ LocalizeText('widget.avatar.stop_decorating') }
|
{ LocalizeText('widget.avatar.stop_decorating') }
|
||||||
|
@ -1,21 +1,23 @@
|
|||||||
import { FC, useCallback } from 'react';
|
import { FC, useMemo } from 'react';
|
||||||
|
import { GetSessionDataManager } from '../../../../../../api';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
||||||
|
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
||||||
import { AvatarInfoWidgetNameViewProps } from './AvatarInfoWidgetNameView.types';
|
import { AvatarInfoWidgetNameViewProps } from './AvatarInfoWidgetNameView.types';
|
||||||
|
|
||||||
export const AvatarInfoWidgetNameView: FC<AvatarInfoWidgetNameViewProps> = props =>
|
export const AvatarInfoWidgetNameView: FC<AvatarInfoWidgetNameViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { event = null } = props;
|
const { nameData = null, close = null } = props;
|
||||||
|
|
||||||
const onClose = useCallback(() =>
|
const fades = useMemo(() =>
|
||||||
{
|
{
|
||||||
|
return (nameData.id !== GetSessionDataManager().userId);
|
||||||
}, []);
|
}, [ nameData ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ event.roomIndex } category={ event.category } onClose= { onClose }>
|
<ContextMenuView objectId={ nameData.roomIndex } category={ nameData.category } fades={ fades } close= { close }>
|
||||||
<div className="d-flex justify-content-center align-items-center bg-dark border border-dark">
|
<ContextMenuHeaderView>
|
||||||
{ event.name }
|
{ nameData.name }
|
||||||
</div>
|
</ContextMenuHeaderView>
|
||||||
</ContextMenuView>
|
</ContextMenuView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,6 @@ import { RoomWidgetObjectNameEvent } from '../../../../events';
|
|||||||
|
|
||||||
export interface AvatarInfoWidgetNameViewProps
|
export interface AvatarInfoWidgetNameViewProps
|
||||||
{
|
{
|
||||||
event: RoomWidgetObjectNameEvent;
|
nameData: RoomWidgetObjectNameEvent;
|
||||||
|
close: () => void;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
const isRidingHorse = IsRidingHorse();
|
const isRidingHorse = IsRidingHorse();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } onClose={ close }>
|
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } close={ close }>
|
||||||
<ContextMenuHeaderView>
|
<ContextMenuHeaderView>
|
||||||
{ userData.name }
|
{ userData.name }
|
||||||
</ContextMenuHeaderView>
|
</ContextMenuHeaderView>
|
||||||
|
@ -1,24 +1,45 @@
|
|||||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
|
import { GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
|
||||||
import { ContextMenuViewFadeOptions, ContextMenuViewProps } from './ContextMenuView.types';
|
import { ContextMenuViewProps } from './ContextMenuView.types';
|
||||||
|
|
||||||
|
const fadeDelay = 3000;
|
||||||
|
const fadeLength = 75;
|
||||||
|
|
||||||
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { objectId = -1, category = -1, fades = false, onClose = null, children = null } = props;
|
const { objectId = -1, category = -1, fades = false, close = null, children = null } = props;
|
||||||
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: -1, y: -1});
|
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: -1, y: -1});
|
||||||
const [ opacity, setOpacity ] = useState(1);
|
const [ opacity, setOpacity ] = useState(1);
|
||||||
const [ fadeOptions, setFadeOptions ] = useState<ContextMenuViewFadeOptions>({
|
const [ isFading, setIsFading ] = useState(false);
|
||||||
firstFadeStarted: false,
|
const [ fadeTime, setFadeTime ] = useState(0);
|
||||||
fadeAfterDelay: true,
|
|
||||||
fadeLength: 75,
|
|
||||||
fadeTime: 0,
|
|
||||||
fadeStartDelay: 3000,
|
|
||||||
fadingOut: false
|
|
||||||
});
|
|
||||||
const elementRef = useRef<HTMLDivElement>();
|
const elementRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
const update = useCallback((time: number) =>
|
const update = useCallback((time: number) =>
|
||||||
{
|
{
|
||||||
|
let fadeTime = time;
|
||||||
|
let newOpacity = 1;
|
||||||
|
|
||||||
|
if(isFading)
|
||||||
|
{
|
||||||
|
setFadeTime(prevValue =>
|
||||||
|
{
|
||||||
|
fadeTime += prevValue;
|
||||||
|
|
||||||
|
return fadeTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
newOpacity = ((1 - (fadeTime / fadeLength)) * 1);
|
||||||
|
|
||||||
|
if(newOpacity <= 0)
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setOpacity(newOpacity);
|
||||||
|
}
|
||||||
|
|
||||||
const bounds = GetRoomObjectBounds(GetRoomSession().roomId, objectId, category);
|
const bounds = GetRoomObjectBounds(GetRoomSession().roomId, objectId, category);
|
||||||
|
|
||||||
if(!bounds || !elementRef.current) return;
|
if(!bounds || !elementRef.current) return;
|
||||||
@ -27,7 +48,7 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
|||||||
x: Math.round(((bounds.left + (bounds.width / 2)) - (elementRef.current.offsetWidth / 2))),
|
x: Math.round(((bounds.left + (bounds.width / 2)) - (elementRef.current.offsetWidth / 2))),
|
||||||
y: Math.round((bounds.top - elementRef.current.offsetHeight) + 10)
|
y: Math.round((bounds.top - elementRef.current.offsetHeight) + 10)
|
||||||
});
|
});
|
||||||
}, [ objectId, category ]);
|
}, [ objectId, category, isFading, close ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -39,8 +60,20 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, [ update ]);
|
}, [ update ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!fades) return;
|
||||||
|
|
||||||
|
const timeout = setTimeout(() => setIsFading(true), fadeDelay);
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
clearTimeout(timeout);
|
||||||
|
}
|
||||||
|
}, [ fades ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ elementRef } className={ 'nitro-context-menu position-absolute ' + (pos.x > -1 ? 'visible' : 'invisible') } style={ { left: pos.x, top: pos.y } }>
|
<div ref={ elementRef } className={ 'nitro-context-menu position-absolute ' + (pos.x > -1 ? 'visible' : 'invisible') } style={ { left: pos.x, top: pos.y, opacity: opacity } }>
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -3,15 +3,5 @@ export interface ContextMenuViewProps
|
|||||||
objectId: number;
|
objectId: number;
|
||||||
category: number;
|
category: number;
|
||||||
fades?: boolean;
|
fades?: boolean;
|
||||||
onClose: () => void;
|
close: () => void;
|
||||||
}
|
|
||||||
|
|
||||||
export interface ContextMenuViewFadeOptions
|
|
||||||
{
|
|
||||||
firstFadeStarted: boolean;
|
|
||||||
fadeAfterDelay: boolean;
|
|
||||||
fadeLength: number;
|
|
||||||
fadeTime: number;
|
|
||||||
fadeStartDelay: number;
|
|
||||||
fadingOut: boolean;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user