fix text styling

This commit is contained in:
Viktor Rådberg
2023-08-02 15:03:38 +02:00
parent ca85cfbebd
commit 627b639775
15 changed files with 497 additions and 403 deletions

View File

@@ -54,7 +54,7 @@ const App = () => {
const handlePlayerChange = (updatedPlayer: Player) => {
const updatedPlayers = players.map((player) =>
player.key === updatedPlayer.key ? updatedPlayer : player
player.index === updatedPlayer.index ? updatedPlayer : player
);
setPlayers(updatedPlayers);
};

View File

@@ -0,0 +1,273 @@
import styled, { css } from 'styled-components';
import { Player, Rotation } from '../../Types/Player';
import { useRef, useState } from 'react';
import { OutlinedText } from '../Text/OutlinedText';
const CommanderDamageContainer = styled.div<{
rotation: number;
}>`
display: flex;
flex-direction: row;
flex-grow: 1;
width: 100%;
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
flex-direction: column;
`;
}
}}
`;
const CommanderDamageButton = styled.button<{
backgroundColor?: string;
rotation: number;
}>`
display: flex;
flex-grow: 1;
border: none;
height: 10vmin;
width: 50%;
outline: none;
cursor: pointer;
background-color: ${(props) => props.backgroundColor || 'antiquewhite'};
margin: 0;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
padding: 0;
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
width: 10vmin;
height: auto;
`;
}
}}
`;
const CommanderDamageTextContainer = styled.p<{
rotation: number;
}>`
position: relative;
top: 25%;
left: 50%;
transform: translate(-50%, -50%);
font-variant-numeric: tabular-nums;
pointer-events: none;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
rotate: 180deg;
text-orientation: sideways;
writing-mode: vertical-lr;
height: 1rem;
width: auto;
`;
}
}}
`;
const LmaoContainer = styled.div`
/* top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px; */
`;
const PartnerDamageSeperator = styled.div<{
rotation: number;
}>`
width: 1px;
background-color: rgba(0, 0, 0, 1);
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
width: auto;
height: 1px;
`;
}
}}
`;
type CommanderDamageButtonComponentProps = {
player: Player;
opponent: Player;
onPlayerChange: (updatedPlayer: Player) => void;
setLifeTotal: (lifeTotal: number) => void;
};
type InputProps = {
opponentIndex: number;
isPartner: boolean;
};
export const CommanderDamage = ({
player,
opponent,
onPlayerChange,
setLifeTotal,
}: CommanderDamageButtonComponentProps) => {
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
const [timeoutFinished, setTimeoutFinished] = useState(false);
const [hasPressedDown, setHasPressedDown] = useState(false);
const handleCommanderDamageChange = (
index: number,
increment: number,
isPartner: boolean
) => {
const currentCommanderDamage = player.commanderDamage[index];
if (isPartner) {
if (currentCommanderDamage.partnerDamageTotal === 0 && increment === -1) {
return;
}
const updatedCommanderDamage = [...player.commanderDamage];
updatedCommanderDamage[index].partnerDamageTotal += increment;
const updatedPlayer = {
...player,
commanderDamage: updatedCommanderDamage,
};
onPlayerChange(updatedPlayer);
setLifeTotal(player.lifeTotal - increment);
return;
}
if (currentCommanderDamage.damageTotal === 0 && increment === -1) {
return;
}
const updatedCommanderDamage = [...player.commanderDamage];
updatedCommanderDamage[index].damageTotal += increment;
const updatedPlayer = {
...player,
commanderDamage: updatedCommanderDamage,
};
onPlayerChange(updatedPlayer);
setLifeTotal(player.lifeTotal - increment);
};
const handleDownInput = ({ opponentIndex, isPartner }: InputProps) => {
setTimeoutFinished(false);
setHasPressedDown(true);
timeoutRef.current = setTimeout(() => {
setTimeoutFinished(true);
handleCommanderDamageChange(opponentIndex, -1, isPartner);
}, 500);
};
const handleUpInput = ({ opponentIndex, isPartner }: InputProps) => {
if (!(hasPressedDown && !timeoutFinished)) {
return;
}
clearTimeout(timeoutRef.current);
handleCommanderDamageChange(opponentIndex, 1, isPartner);
setHasPressedDown(false);
};
const handleLeaveInput = () => {
setTimeoutFinished(true);
clearTimeout(timeoutRef.current);
setHasPressedDown(false);
};
const opponentIndex = opponent.index;
const fontSize = '5vmin';
const fontWeight = 'bold';
const strokeWidth = '0.5vmin';
return (
<CommanderDamageContainer
key={opponentIndex}
rotation={player.settings.rotation}
>
<CommanderDamageButton
key={opponentIndex}
rotation={player.settings.rotation}
onPointerDown={() =>
handleDownInput({ opponentIndex, isPartner: false })
}
onPointerUp={() => handleUpInput({ opponentIndex, isPartner: false })}
onPointerLeave={handleLeaveInput}
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
}}
backgroundColor={opponent.color}
>
<CommanderDamageTextContainer rotation={player.settings.rotation}>
<OutlinedText
fontSize={fontSize}
fontWeight={fontWeight}
strokeWidth={strokeWidth}
>
{player.commanderDamage[opponentIndex].damageTotal > 0
? player.commanderDamage[opponentIndex].damageTotal
: ''}
</OutlinedText>
</CommanderDamageTextContainer>
</CommanderDamageButton>
{opponent.settings.usePartner && (
<>
<PartnerDamageSeperator rotation={player.settings.rotation} />
<CommanderDamageButton
key={opponentIndex}
rotation={player.settings.rotation}
onPointerDown={() =>
handleDownInput({ opponentIndex, isPartner: true })
}
onPointerUp={() =>
handleUpInput({ opponentIndex, isPartner: true })
}
onPointerLeave={handleLeaveInput}
onContextMenu={(
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault();
}}
backgroundColor={opponent.color}
>
<CommanderDamageTextContainer rotation={player.settings.rotation}>
<OutlinedText
fontSize={fontSize}
fontWeight={fontWeight}
strokeWidth={strokeWidth}
>
{player.commanderDamage[opponentIndex].partnerDamageTotal > 0
? player.commanderDamage[opponentIndex].partnerDamageTotal
: ''}
</OutlinedText>
</CommanderDamageTextContainer>
</CommanderDamageButton>
</>
)}
</CommanderDamageContainer>
);
};

View File

@@ -1,299 +0,0 @@
import { useRef, useState } from 'react';
import { Player, Rotation } from '../../Types/Player';
import styled, { css } from 'styled-components';
const CommanderDamageGrid = styled.div<{ rotation: number }>`
display: flex;
flex-direction: row;
flex-grow: 1;
width: 100%;
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
flex-direction: column;
height: 100%;
width: auto;
`;
}
}}
`;
const CommanderDamageContainer = styled.div<{
rotation: number;
}>`
display: flex;
flex-direction: row;
flex-grow: 1;
width: 100%;
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
flex-direction: column;
`;
}
}}
`;
const CommanderDamageButton = styled.button<{
backgroundColor?: string;
rotation: number;
}>`
display: flex;
flex-grow: 1;
border: none;
height: 10vmin;
width: 50%;
outline: none;
cursor: pointer;
background-color: ${(props) => props.backgroundColor || 'antiquewhite'};
margin: 0;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
padding: 0;
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
width: 10vmin;
height: auto;
`;
}
}}
`;
const CommanderDamageButtonText = styled.p<{
rotation: number;
}>`
margin: auto;
font-size: 5vmin;
text-size-adjust: auto;
font-variant-numeric: tabular-nums;
pointer-events: none;
text-shadow: -1px -1px 0 #ffffff, 1px -1px 0 #ffffff, -1px 1px 0 #ffffff,
1px 1px 0 #ffffff;
color: #000000;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
rotate: 180deg;
text-orientation: sideways;
writing-mode: vertical-lr;
height: 1rem;
width: auto;
`;
}
}}
`;
const PartnerDamageSeperator = styled.div<{
rotation: number;
}>`
width: 1px;
background-color: rgba(0, 0, 0, 1);
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
width: auto;
height: 1px;
`;
}
}}
`;
type CommanderDamageBarProps = {
lifeTotal: number;
opponents: Player[];
player: Player;
onPlayerChange: (updatedPlayer: Player) => void;
setLifeTotal: (lifeTotal: number) => void;
};
const CommanderDamageBar = ({
opponents,
lifeTotal,
player,
onPlayerChange,
setLifeTotal,
}: CommanderDamageBarProps) => {
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
const [timeoutFinished, setTimeoutFinished] = useState(false);
const [hasPressedDown, setHasPressedDown] = useState(false);
const handleCommanderDamageChange = (
index: number,
increment: number,
isPartner: boolean
) => {
const currentCommanderDamage = player.commanderDamage[index];
if (isPartner) {
if (currentCommanderDamage.partnerDamageTotal === 0 && increment === -1) {
return;
}
const updatedCommanderDamage = [...player.commanderDamage];
updatedCommanderDamage[index].partnerDamageTotal += increment;
const updatedPlayer = {
...player,
commanderDamage: updatedCommanderDamage,
};
onPlayerChange(updatedPlayer);
setLifeTotal(lifeTotal - increment);
return;
}
if (currentCommanderDamage.damageTotal === 0 && increment === -1) {
return;
}
const updatedCommanderDamage = [...player.commanderDamage];
updatedCommanderDamage[index].damageTotal += increment;
const updatedPlayer = {
...player,
commanderDamage: updatedCommanderDamage,
};
onPlayerChange(updatedPlayer);
setLifeTotal(lifeTotal - increment);
};
const handleDownInput = (index: number) => {
setTimeoutFinished(false);
setHasPressedDown(true);
timeoutRef.current = setTimeout(() => {
setTimeoutFinished(true);
handleCommanderDamageChange(index, -1, false);
}, 500);
};
const handleUpInput = (index: number) => {
if (!(hasPressedDown && !timeoutFinished)) {
return;
}
clearTimeout(timeoutRef.current);
handleCommanderDamageChange(index, 1, false);
setHasPressedDown(false);
};
const handleLeaveInput = () => {
setTimeoutFinished(true);
clearTimeout(timeoutRef.current);
setHasPressedDown(false);
};
const handlePartnerDownInput = (index: number) => {
setTimeoutFinished(false);
setHasPressedDown(true);
timeoutRef.current = setTimeout(() => {
setTimeoutFinished(true);
handleCommanderDamageChange(index, -1, true);
}, 500);
};
const handlePartnerUpInput = (index: number) => {
if (!(hasPressedDown && !timeoutFinished)) {
return;
}
clearTimeout(timeoutRef.current);
handleCommanderDamageChange(index, 1, true);
setHasPressedDown(false);
};
const handlePartnerLeaveInput = () => {
setTimeoutFinished(true);
clearTimeout(timeoutRef.current);
setHasPressedDown(false);
};
return (
<CommanderDamageGrid rotation={player.settings.rotation}>
{opponents.map((opponent, index) => {
if (!opponent.settings.useCommanderDamage) {
return null;
}
return (
<CommanderDamageContainer
key={index}
rotation={player.settings.rotation}
>
<CommanderDamageButton
key={index}
rotation={player.settings.rotation}
onPointerDown={() => handleDownInput(index)}
onPointerUp={() => handleUpInput(index)}
onPointerLeave={handleLeaveInput}
onContextMenu={(
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault();
}}
backgroundColor={opponent.color}
>
<CommanderDamageButtonText rotation={player.settings.rotation}>
{player.commanderDamage[index].damageTotal > 0
? player.commanderDamage[index].damageTotal
: ''}
</CommanderDamageButtonText>
</CommanderDamageButton>
{opponent.settings.usePartner && (
<>
<PartnerDamageSeperator rotation={player.settings.rotation} />
<CommanderDamageButton
key={index}
rotation={player.settings.rotation}
onPointerDown={() => handlePartnerDownInput(index)}
onPointerUp={() => handlePartnerUpInput(index)}
onPointerLeave={handlePartnerLeaveInput}
onContextMenu={(
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
e.preventDefault();
}}
backgroundColor={opponent.color}
>
<CommanderDamageButtonText
rotation={player.settings.rotation}
>
{player.commanderDamage[index].partnerDamageTotal > 0
? player.commanderDamage[index].partnerDamageTotal
: ''}
</CommanderDamageButtonText>
</CommanderDamageButton>
</>
)}
</CommanderDamageContainer>
);
})}
</CommanderDamageGrid>
);
};
export default CommanderDamageBar;

View File

@@ -1,6 +1,7 @@
import { ReactNode, useRef, useState } from 'react';
import styled, { css } from 'styled-components';
import { CounterType, Rotation } from '../../Types/Player';
import { OutlinedText } from '../Text/OutlinedText';
const ExtraCounterContainer = styled.div`
display: flex;
@@ -29,11 +30,11 @@ export const CenteredText = styled.div`
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 7vmin;
font-size: 6vmin;
font-weight: bold;
-webkit-text-stroke: 0.3vmin #ffffff; /* Add a 2-pixel black stroke */
-webkit-text-stroke: 0.4vmin #ffffff;
-webkit-text-fill-color: #000000;
color: #000000;
color: #b5b2b2;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
@@ -42,6 +43,13 @@ export const CenteredText = styled.div`
-ms-user-select: none;
`;
const CenteredTextOutline = styled.span`
position: absolute;
left: 0;
-webkit-text-stroke: 0;
pointer-events: none;
`;
const IconContainer = styled.div<{
rotation: number;
}>`
@@ -122,7 +130,13 @@ const ExtraCounter = ({
>
<IconContainer rotation={rotation}>
{Icon}
<CenteredText>{counterTotal ? counterTotal : undefined}</CenteredText>
<OutlinedText
fontSize="6vmin"
fontWeight="bold"
strokeWidth="0.6vmin"
>
{counterTotal ? counterTotal : undefined}
</OutlinedText>
</IconContainer>
</StyledExtraCounterButton>
</ExtraCounterContainer>

View File

@@ -0,0 +1,57 @@
import { Player, Rotation } from '../../Types/Player';
import styled, { css } from 'styled-components';
import { CommanderDamage } from '../Buttons/CommanderDamage';
const CommanderDamageGrid = styled.div<{ rotation: number }>`
display: flex;
flex-direction: row;
flex-grow: 1;
width: 100%;
${(props) => {
if (
props.rotation === Rotation.SideFlipped ||
props.rotation === Rotation.Side
) {
return css`
flex-direction: column;
height: 100%;
width: auto;
`;
}
}}
`;
type CommanderDamageBarProps = {
opponents: Player[];
player: Player;
onPlayerChange: (updatedPlayer: Player) => void;
setLifeTotal: (lifeTotal: number) => void;
};
const CommanderDamageBar = ({
opponents,
player,
onPlayerChange,
setLifeTotal,
}: CommanderDamageBarProps) => {
return (
<CommanderDamageGrid rotation={player.settings.rotation}>
{opponents.map((opponent) => {
if (!opponent.settings.useCommanderDamage) {
return null;
}
return (
<CommanderDamage
player={player}
opponent={opponent}
setLifeTotal={setLifeTotal}
onPlayerChange={onPlayerChange}
/>
);
})}
</CommanderDamageGrid>
);
};
export default CommanderDamageBar;

View File

@@ -58,14 +58,14 @@ const Counters = ({
) {
return (
<GridItemContainer
key={player.key}
gridArea={`player${player.key}`}
key={player.index}
gridArea={`player${player.index}`}
>
<LifeCounter
backgroundColor={player.color}
player={player}
opponents={players.filter(
(opponent) => opponent.key !== player.key
(opponent) => opponent.index !== player.index
)}
onPlayerChange={onPlayerChange}
resetCurrentGame={resetCurrentGame}
@@ -75,14 +75,14 @@ const Counters = ({
}
return (
<GridItemContainer
key={player.key}
gridArea={`player${player.key}`}
key={player.index}
gridArea={`player${player.index}`}
>
<LifeCounter
backgroundColor={player.color}
player={player}
opponents={players.filter(
(opponent) => opponent.key !== player.key
(opponent) => opponent.index !== player.index
)}
onPlayerChange={onPlayerChange}
resetCurrentGame={resetCurrentGame}

View File

@@ -1,13 +1,12 @@
import { useState, useEffect } from 'react';
import { Player } from '../../Types/Player';
import { useSwipeable } from 'react-swipeable';
import CommanderDamageBar from '../Buttons/CommanderDamageBar';
import PlayerMenu from '../PlayerMenu/PlayerMenu';
import SettingsButton from '../Buttons/SettingsButton';
import ExtraCountersBar from '../Counters/ExtraCountersBar';
import { useEffect, useState } from 'react';
import styled, { css, keyframes } from 'styled-components';
import { Rotation } from '../../Types/Player';
import { Player, Rotation } from '../../Types/Player';
import LifeCounterButton from '../Buttons/LifeCounterButton';
import SettingsButton from '../Buttons/SettingsButton';
import CommanderDamageBar from '../Counters/CommanderDamageBar';
import ExtraCountersBar from '../Counters/ExtraCountersBar';
import PlayerMenu from '../PlayerMenu/PlayerMenu';
import { OutlinedText } from '../Text/OutlinedText';
export const LifeCounterWrapper = styled.div<{
backgroundColor: string;
@@ -79,24 +78,16 @@ export const LifeCountainer = styled.div<{
}}
`;
export const LifeCounterText = styled.p<{
export const LifeCounterTextContainer = styled.p<{
rotation: Rotation;
}>`
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
font-size: 30vmin;
text-align: center;
text-size-adjust: auto;
margin: 0;
padding: 0;
font-variant-numeric: tabular-nums;
pointer-events: none;
text-shadow: -1px -1px 0 #ffffff, 1px -1px 0 #ffffff, -1px 1px 0 #ffffff,
1px 1px 0 #ffffff;
color: #000000;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
@@ -133,6 +124,7 @@ export const RecentDifference = styled.span`
transform: translate(-50%, -50%);
text-shadow: none;
background-color: rgba(255, 255, 255, 0.6);
font-variant-numeric: tabular-nums;
border-radius: 50%;
padding: 5px 10px;
font-size: 8vmin;
@@ -175,23 +167,10 @@ const LifeCounter = ({
return () => clearTimeout(timer);
}, [recentDifference]);
const swipeHandlers = useSwipeable({
onSwipedUp: () => {
// player.settings.flipped ? setShowPlayerMenu(true) : null;
},
onSwipedDown: () => {
// player.settings.flipped ? null : setShowPlayerMenu(true);
},
});
return (
<LifeCounterWrapper backgroundColor={backgroundColor}>
<LifeCounterContentContainer
{...swipeHandlers}
rotation={player.settings.rotation}
>
<LifeCounterContentContainer rotation={player.settings.rotation}>
<CommanderDamageBar
lifeTotal={player.lifeTotal}
opponents={opponents}
player={player}
onPlayerChange={onPlayerChange}
@@ -211,15 +190,17 @@ const LifeCounter = ({
operation="subtract"
increment={-1}
/>
<LifeCounterText rotation={player.settings.rotation}>
<LifeCounterTextContainer rotation={player.settings.rotation}>
<OutlinedText fontSize="30vmin" strokeWidth="1.5vmin">
{player.lifeTotal}
</OutlinedText>
{recentDifference !== 0 && (
<RecentDifference key={key}>
{recentDifference > 0 ? '+' : ''}
{recentDifference}
</RecentDifference>
)}
</LifeCounterText>
</LifeCounterTextContainer>
<LifeCounterButton
lifeTotal={player.lifeTotal}
setLifeTotal={handleLifeChange}

View File

@@ -0,0 +1,68 @@
import styled from 'styled-components';
import { theme } from '../../Data/theme';
export const CenteredText = styled.div<{
strokeWidth?: string;
strokeColor?: string;
fillColor?: string;
fontSize?: string;
fontWeight?: string;
}>`
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: ${(props) => props.fontWeight || ''};
font-variant-numeric: tabular-nums;
color: #b5b2b2;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
-moz-user-select: -moz-none;
-webkit-user-select: none;
-ms-user-select: none;
font-size: ${(props) => props.fontSize || '6vmin'};
-webkit-text-stroke: ${(props) => props.strokeWidth || '1vmin'}
${(props) => props.strokeColor || theme.palette.common.white};
-webkit-text-fill-color: ${(props) =>
props.fillColor || theme.palette.common.black};
`;
const CenteredTextOutline = styled.span`
position: absolute;
left: 0;
-webkit-text-stroke: 0;
pointer-events: none;
`;
type OutlinedTextProps = {
children?: React.ReactNode;
fontSize?: string;
fontWeight?: string;
strokeWidth?: string;
strokeColor?: string;
fillColor?: string;
};
export const OutlinedText: React.FC<OutlinedTextProps> = ({
children,
fontSize,
fontWeight,
strokeWidth,
strokeColor,
fillColor,
}) => {
return (
<CenteredText
fontSize={fontSize}
fontWeight={fontWeight}
strokeWidth={strokeWidth}
strokeColor={strokeColor}
fillColor={fillColor}
>
{children}
<CenteredTextOutline aria-hidden>{children}</CenteredTextOutline>
</CenteredText>
);
};

View File

@@ -1,6 +1,6 @@
import React from 'react';
import styled from 'styled-components';
import { GridTemplateAreas } from '../../../Data/getGridTemplateAreas';
import { GridTemplateAreas } from '../../../Data/GridTemplateAreas';
import { FormControlLabel, Radio, RadioGroup } from '@mui/material';
import OnePlayerLandscape from '../../../Icons/Layouts/OnePlayerLandscape';
import OnePlayerPortrait from '../../../Icons/Layouts/OnePlayerPortrait';

View File

@@ -2,7 +2,7 @@ import { Button, FormControl, FormLabel, Switch } from '@mui/material';
import Slider from '@mui/material/Slider';
import { useEffect, useState } from 'react';
import styled from 'styled-components';
import { GridTemplateAreas } from '../../../Data/getGridTemplateAreas';
import { GridTemplateAreas } from '../../../Data/GridTemplateAreas';
import {
InitialSettings,
createInitialPlayers,
@@ -196,7 +196,7 @@ const Start = ({
/>
<FormLabel>Layout</FormLabel>
{/* Use the new LayoutOptions component */}
<LayoutOptions
numberOfPlayers={playerOptions.numberOfPlayers}
gridAreas={playerOptions.gridAreas}

View File

@@ -0,0 +1,15 @@
export enum GridTemplateAreas {
OnePlayerLandscape = '"player0 player0"',
OnePlayerPortrait = '"player0" "player0"',
TwoPlayersOppositeLandscape = '"player0" "player1"',
TwoPlayersOppositePortrait = '"player0 player1" "player0 player1"',
TwoPlayersSameSide = '"player0 player1"',
ThreePlayers = '"player0 player0" "player1 player2"',
ThreePlayersSide = '"player0 player0 player0 player2" "player1 player1 player1 player2"',
FourPlayers = '"player0 player1" "player2 player3"',
FourPlayersSide = '"player0 player1 player1 player1 player3" "player0 player2 player2 player2 player3"',
FivePlayers = '"player0 player0 player0 player1 player1 player1" "player2 player2 player3 player3 player4 player4"',
FivePlayersSide = '"player0 player0 player0 player0 player0 player1 player1 player1 player1 player1 player2" "player3 player3 player3 player3 player3 player4 player4 player4 player4 player4 player2"',
SixPlayers = '"player0 player1 player2" "player3 player4 player5"',
SixPlayersSide = '"player0 player1 player1 player1 player1 player2 player2 player2 player2 player3" "player0 player4 player4 player4 player4 player5 player5 player5 player5 player3"',
}

View File

@@ -1,15 +0,0 @@
export enum GridTemplateAreas {
OnePlayerLandscape = '"player1 player1"',
OnePlayerPortrait = '"player1" "player1"',
TwoPlayersOppositeLandscape = '"player1" "player2"',
TwoPlayersOppositePortrait = '"player1 player2" "player1 player2"',
TwoPlayersSameSide = '"player1 player2"',
ThreePlayers = '"player1 player1" "player2 player3"',
ThreePlayersSide = '"player1 player1 player1 player3" "player2 player2 player2 player3"',
FourPlayers = '"player1 player2" "player3 player4"',
FourPlayersSide = '"player1 player2 player2 player2 player4" "player1 player3 player3 player3 player4"',
FivePlayers = '"player1 player1 player1 player2 player2 player2" "player3 player3 player4 player4 player5 player5"',
FivePlayersSide = '"player1 player1 player1 player1 player1 player2 player2 player2 player2 player2 player3" "player4 player4 player4 player4 player4 player5 player5 player5 player5 player5 player3"',
SixPlayers = '"player1 player2 player3" "player4 player5 player6"',
SixPlayersSide = '"player1 player2 player2 player2 player2 player3 player3 player3 player3 player4" "player1 player5 player5 player5 player5 player6 player6 player6 player6 player4"',
}

View File

@@ -1,5 +1,5 @@
import { Player, Rotation } from '../Types/Player';
import { GridTemplateAreas } from './getGridTemplateAreas';
import { GridTemplateAreas } from './GridTemplateAreas';
export type InitialSettings = {
startingLifeTotal: number;
@@ -30,9 +30,9 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.TwoPlayersOppositePortrait) {
switch (index) {
case 1:
case 0:
return Rotation.SideFlipped;
case 2:
case 1:
return Rotation.Side;
default:
return Rotation.Normal;
@@ -41,9 +41,9 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.TwoPlayersOppositeLandscape) {
switch (index) {
case 1:
case 0:
return Rotation.Flipped;
case 2:
case 1:
return Rotation.Normal;
default:
return Rotation.Normal;
@@ -52,9 +52,9 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.TwoPlayersSameSide) {
switch (index) {
case 1:
case 0:
return Rotation.Normal;
case 2:
case 1:
return Rotation.Normal;
default:
return Rotation.Normal;
@@ -63,11 +63,11 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.ThreePlayers) {
switch (index) {
case 1:
case 0:
return Rotation.Flipped;
case 2:
case 1:
return Rotation.Normal;
case 3:
case 2:
return Rotation.Normal;
default:
return Rotation.Normal;
@@ -76,11 +76,11 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.ThreePlayersSide) {
switch (index) {
case 1:
case 0:
return Rotation.Flipped;
case 2:
case 1:
return Rotation.Normal;
case 3:
case 2:
return Rotation.Side;
default:
return Rotation.Normal;
@@ -89,13 +89,13 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.FourPlayers) {
switch (index) {
case 0:
return Rotation.Flipped;
case 1:
return Rotation.Flipped;
case 2:
return Rotation.Flipped;
case 3:
return Rotation.Normal;
case 4:
case 3:
return Rotation.Normal;
default:
return Rotation.Normal;
@@ -104,13 +104,13 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.FourPlayersSide) {
switch (index) {
case 1:
case 0:
return Rotation.SideFlipped;
case 2:
case 1:
return Rotation.Flipped;
case 3:
case 2:
return Rotation.Normal;
case 4:
case 3:
return Rotation.Side;
default:
return Rotation.Normal;
@@ -119,16 +119,16 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.FivePlayers) {
switch (index) {
case 0:
return Rotation.Flipped;
case 1:
return Rotation.Flipped;
case 2:
return Rotation.Flipped;
return Rotation.Normal;
case 3:
return Rotation.Normal;
case 4:
return Rotation.Normal;
case 5:
return Rotation.Normal;
default:
return Rotation.Normal;
}
@@ -136,15 +136,15 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.FivePlayersSide) {
switch (index) {
case 0:
return Rotation.Flipped;
case 1:
return Rotation.Flipped;
case 2:
return Rotation.Flipped;
case 3:
return Rotation.Side;
case 4:
case 3:
return Rotation.Normal;
case 5:
case 4:
return Rotation.Normal;
default:
return Rotation.Normal;
@@ -153,18 +153,18 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.SixPlayers) {
switch (index) {
case 0:
return Rotation.Flipped;
case 1:
return Rotation.Flipped;
case 2:
return Rotation.Flipped;
case 3:
return Rotation.Flipped;
return Rotation.Normal;
case 4:
return Rotation.Normal;
case 5:
return Rotation.Normal;
case 6:
return Rotation.Normal;
default:
return Rotation.Normal;
}
@@ -172,17 +172,17 @@ const getRotation = (index: number, gridAreas: GridTemplateAreas): Rotation => {
if (gridAreas === GridTemplateAreas.SixPlayersSide) {
switch (index) {
case 1:
case 0:
return Rotation.SideFlipped;
case 1:
return Rotation.Flipped;
case 2:
return Rotation.Flipped;
case 3:
return Rotation.Flipped;
case 4:
return Rotation.Side;
case 5:
case 4:
return Rotation.Normal;
case 6:
case 5:
return Rotation.Normal;
default:
return Rotation.Normal;
@@ -201,7 +201,7 @@ export const createInitialPlayers = ({
const players: Player[] = [];
const availableColors = [...presetColors]; // Create a copy of the colors array
for (let i = 1; i <= numberOfPlayers; i++) {
for (let i = 0; i <= numberOfPlayers - 1; i++) {
const colorIndex = Math.floor(Math.random() * availableColors.length);
const color = availableColors[colorIndex];
@@ -209,19 +209,19 @@ export const createInitialPlayers = ({
availableColors.splice(colorIndex, 1);
const commanderDamage = [];
for (let j = 1; j <= numberOfPlayers; j++) {
for (let j = 0; j <= numberOfPlayers - 1; j++) {
commanderDamage.push({
source: j,
damageTotal: 0,
partnerDamageTotal: 0,
});
}
const rotation = getRotation(i, gridAreas);
console.log(rotation);
const player: Player = {
lifeTotal: startingLifeTotal,
key: i,
index: i,
color,
settings: {
useCommanderDamage,

View File

@@ -19,7 +19,7 @@ export const theme = createTheme({
disabled: '#5E714C',
},
common: {
white: '#ffffff',
white: '#F9FFE3',
black: '#000000',
},
},

View File

@@ -1,6 +1,6 @@
export type Player = {
lifeTotal: number;
key: number;
index: number;
color: string;
settings: PlayerSettings;
commanderDamage: CommanderDamage[];