import { ActionIcon, Box, createStyles, Stack, Text, Transition } from '@mantine/core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { useState } from 'react'; import { useNuiEvent } from '../../../hooks/useNuiEvent'; import { debugData } from '../../../utils/debugData'; import { fetchNui } from '../../../utils/fetchNui'; const radius = 60; // https://codesandbox.io/embed/circular-menu-e94ug function getTransform(index: number, totalItems: number) { const value = index / totalItems; const x = radius * Math.cos(Math.PI * 2 * (value - 0.25)); const y = radius * Math.sin(Math.PI * 2 * (value - 0.25)); return `translate(${x}px, ${y}px)`; } interface MenuItem { icon: IconProp; label: string; } debugData<{ items: MenuItem[]; sub?: boolean }>([ { action: 'openRadialMenu', data: { items: [ // TODO: Fix wheel being broken when there's only one item { icon: 'palette', label: 'Paint' }, { icon: 'warehouse', label: 'Garage' }, { icon: 'palette', label: 'Quite long text' }, { icon: 'palette', label: 'Paint' }, { icon: 'warehouse', label: 'Garage' }, ], sub: false, }, }, ]); const useStyles = createStyles((theme) => ({ wrapper: { position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', }, sector: { fill: theme.colors.dark[6], color: theme.colors.dark[0], '&:hover': { fill: theme.fn.primaryColor(), cursor: 'pointer', '> g > text, > g > svg > path': { fill: '#fff', }, }, '> g > text': { fill: theme.colors.dark[0], }, }, backgroundCircle: { fill: theme.colors.dark[6], }, centerCircle: { fill: theme.fn.primaryColor(), color: '#fff', '&:hover': { fill: theme.colors[theme.primaryColor][theme.fn.primaryShade() - 1], cursor: 'pointer', }, }, centerIcon: { color: '#fff', pointerEvents: 'none', }, })); const degToRad = (deg: number) => deg * (Math.PI / 180); const RadialMenu: React.FC = () => { const { classes } = useStyles(); const [visible, setVisible] = useState(false); const [menu, setMenu] = useState<{ items: MenuItem[]; sub?: boolean }>({ items: [], sub: false, }); useNuiEvent('openRadialMenu', (data: { items: MenuItem[]; sub?: boolean }) => { setMenu(data); setVisible(true); }); const handleItemClick = (index: number) => { // fetchNui('planetClick', index) // setVisible(false); }; return ( <> {/*Fixed issues with background circle extending the circle when there's less than 3 items*/} {menu.items.length >= 3 && ( )} {menu.items.map((item, index) => { const pieAngle = 360 / menu.items.length; const angle = degToRad(pieAngle / 2 + 90); const radius = 175 * 0.65; const iconX = 175 + Math.sin(angle) * radius; const iconY = 175 + Math.cos(angle) * radius; return ( <> {item.label} ); })} ); }; export default RadialMenu;