mirror of
https://github.com/Vikeo/LifeTrinket.git
synced 2025-11-20 09:48:00 +00:00
stable state
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
@@ -1,15 +1,70 @@
|
||||
import './App.css';
|
||||
import Counters from './Components/Counters/Counters';
|
||||
import styled from 'styled-components';
|
||||
import { Player } from './Types/Player';
|
||||
|
||||
const MainWrapper = styled.div`
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const players: Player[] = [
|
||||
{
|
||||
key: 1,
|
||||
color: "grey",
|
||||
settings: {
|
||||
useCommanderDamage: true,
|
||||
usePartner: true,
|
||||
useEnergy: true,
|
||||
useExperience: true,
|
||||
usePoison: true,
|
||||
flipped: true,
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
color: "mintcream",
|
||||
settings: {
|
||||
useCommanderDamage: true,
|
||||
usePartner: false,
|
||||
useEnergy: true,
|
||||
useExperience: true,
|
||||
usePoison: true,
|
||||
flipped: true,
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
color: "gold",
|
||||
settings: {
|
||||
useCommanderDamage: true,
|
||||
usePartner: false,
|
||||
useEnergy: true,
|
||||
useExperience: true,
|
||||
usePoison: true,
|
||||
flipped: false,
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
color: "aquamarine",
|
||||
settings: {
|
||||
useCommanderDamage: true,
|
||||
usePartner: true,
|
||||
useEnergy: true,
|
||||
useExperience: true,
|
||||
usePoison: true,
|
||||
flipped: false,
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<MainWrapper>
|
||||
<Counters/>
|
||||
<Counters players={players} />
|
||||
</MainWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
61
my-app/src/Components/Buttons/AddLifeButton.tsx
Normal file
61
my-app/src/Components/Buttons/AddLifeButton.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import { useRef, useState } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
export const StyledLifeCounterButton = styled.button<{ align?: string }>`
|
||||
width: 50%;
|
||||
height: auto;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
font-size: 4rem;
|
||||
font-weight: 600;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 0 28px;
|
||||
text-align: ${props => props.align || "center"};
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
type AddLifeButtonProps = {
|
||||
lifeTotal: number;
|
||||
setLifeTotal: (lifeTotal: number) => void;
|
||||
};
|
||||
|
||||
const AddLifeButton = ({ lifeTotal, setLifeTotal }: AddLifeButtonProps) => {
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||
|
||||
const handleLifeChange = (increment: number) => {
|
||||
setLifeTotal(lifeTotal + increment);
|
||||
};
|
||||
|
||||
const handleDownInput = () => {
|
||||
setTimeoutFinished(false);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
handleLifeChange(10);
|
||||
setTimeoutFinished(true);
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const handleUpInput = () => {
|
||||
if (!timeoutFinished) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
handleLifeChange(1);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledLifeCounterButton
|
||||
onPointerDown={handleDownInput}
|
||||
onPointerUp={handleUpInput}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
align="right"
|
||||
>
|
||||
+
|
||||
</StyledLifeCounterButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddLifeButton;
|
||||
174
my-app/src/Components/Buttons/CommanderDamageBar.tsx
Normal file
174
my-app/src/Components/Buttons/CommanderDamageBar.tsx
Normal file
@@ -0,0 +1,174 @@
|
||||
import { useRef, useState } from "react";
|
||||
import { Player } from "../../Types/Player";
|
||||
import styled from "styled-components";
|
||||
|
||||
const CommanderDamageGrid = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const CommanderDamageContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const CommanderDamageButton = styled.button<{ backgroundColor?: string }>`
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
height: 10vh;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: ${props => props.backgroundColor || "antiquewhite"};
|
||||
`;
|
||||
|
||||
const CommanderDamageButtonText = styled.p`
|
||||
position: relative;
|
||||
margin: auto;
|
||||
font-size: 1.5rem;
|
||||
text-align: center;
|
||||
text-size-adjust: auto;
|
||||
font-variant-numeric: tabular-nums;
|
||||
pointer-events: none;
|
||||
width: 2rem;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const VerticalSeperator = styled.div`
|
||||
width: 1px;
|
||||
background-color: rgba(0, 0, 0, 1);
|
||||
`;
|
||||
|
||||
|
||||
|
||||
type CommanderDamageBarProps = {
|
||||
lifeTotal: number;
|
||||
setLifeTotal: (lifeTotal: number) => void;
|
||||
opponents: Player[];
|
||||
};
|
||||
|
||||
const CommanderDamageBar = ({ opponents, lifeTotal, setLifeTotal }: CommanderDamageBarProps) => {
|
||||
const [commanderDamage, setCommanderDamage] = useState<number[]>(
|
||||
Array(opponents.length).fill(0)
|
||||
);
|
||||
const [partnerCommanderDamage, setPartnerCommanderDamage] = useState<number[]>(
|
||||
Array(opponents.length).fill(0)
|
||||
);
|
||||
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||
|
||||
const handleCommanderDamageChange = (index: number, increment: number) => {
|
||||
const currentCommanderDamage = commanderDamage[index];
|
||||
if (currentCommanderDamage === 0 && increment === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentCommanderDamage === 21 && increment === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedCommanderDamage = [...commanderDamage];
|
||||
updatedCommanderDamage[index] += increment;
|
||||
setCommanderDamage(updatedCommanderDamage);
|
||||
setLifeTotal(lifeTotal - increment);
|
||||
};
|
||||
|
||||
const handlePartnerCommanderDamageChange = (index: number, increment: number) => {
|
||||
const currentPartnerCommanderDamage = partnerCommanderDamage[index];
|
||||
if (currentPartnerCommanderDamage === 0 && increment === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedPartnerCommanderDamage = [...partnerCommanderDamage];
|
||||
updatedPartnerCommanderDamage[index] += increment;
|
||||
|
||||
setPartnerCommanderDamage(updatedPartnerCommanderDamage);
|
||||
setLifeTotal(lifeTotal - increment);
|
||||
};
|
||||
|
||||
const handleDownInput = (index: number) => {
|
||||
setTimeoutFinished(false);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setTimeoutFinished(true);
|
||||
handleCommanderDamageChange(index, -1);
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const handleUpInput = (index: number) => {
|
||||
if (!timeoutFinished) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
handleCommanderDamageChange(index, 1);
|
||||
}
|
||||
clearTimeout(timeoutRef.current);
|
||||
}
|
||||
|
||||
const handlePartnerDownInput = (index: number) => {
|
||||
setTimeoutFinished(false);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setTimeoutFinished(true);
|
||||
handlePartnerCommanderDamageChange(index, -1);
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const handlePartnerUpInput = (index: number) => {
|
||||
if (!timeoutFinished) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
handlePartnerCommanderDamageChange(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<CommanderDamageGrid>
|
||||
{opponents.map((opponent, index) => {
|
||||
return (
|
||||
<CommanderDamageContainer>
|
||||
<CommanderDamageButton
|
||||
key={index}
|
||||
onPointerDown={() => handleDownInput(index)}
|
||||
onPointerUp={() => handleUpInput(index)}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
backgroundColor={opponent.color}
|
||||
>
|
||||
<CommanderDamageButtonText>
|
||||
{commanderDamage[index] > 0 ? commanderDamage[index] : ""}
|
||||
</CommanderDamageButtonText>
|
||||
</CommanderDamageButton>
|
||||
|
||||
{opponent.settings.usePartner && (
|
||||
<>
|
||||
<VerticalSeperator />
|
||||
<CommanderDamageButton
|
||||
key={index}
|
||||
onPointerDown={() => handlePartnerDownInput(index)}
|
||||
onPointerUp={() => handlePartnerUpInput(index)}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
backgroundColor={opponent.color}
|
||||
>
|
||||
<CommanderDamageButtonText>
|
||||
{partnerCommanderDamage[index] > 0 ? partnerCommanderDamage[index] : ""}
|
||||
</CommanderDamageButtonText>
|
||||
</CommanderDamageButton>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
</CommanderDamageContainer>
|
||||
)
|
||||
})}
|
||||
</CommanderDamageGrid>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommanderDamageBar;
|
||||
56
my-app/src/Components/Buttons/CommanderTaxButton.tsx
Normal file
56
my-app/src/Components/Buttons/CommanderTaxButton.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { useRef, useState } from "react";
|
||||
import CommanderTaxIcon from "../../Icons/CommanderTaxIcon";
|
||||
import styled from "styled-components";
|
||||
|
||||
export const StyledCommanderTaxButton = styled.button`
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const CommanderTaxButton = () => {
|
||||
const [commanderTax, setCommanderTax] = useState(0);
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||
|
||||
const handleCommanderTaxChange = (increment: number) => {
|
||||
setCommanderTax(commanderTax + increment);
|
||||
};
|
||||
|
||||
const handleDownInput = () => {
|
||||
setTimeoutFinished(false);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setTimeoutFinished(true);
|
||||
handleCommanderTaxChange(-1);
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const handleUpInput = () => {
|
||||
if (!timeoutFinished) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
handleCommanderTaxChange(1);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledCommanderTaxButton
|
||||
onPointerDown={handleDownInput}
|
||||
onPointerUp={handleUpInput}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
>
|
||||
<CommanderTaxIcon
|
||||
size="8vh"
|
||||
text={commanderTax ? commanderTax : undefined}
|
||||
/>
|
||||
</StyledCommanderTaxButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommanderTaxButton;
|
||||
@@ -0,0 +1,56 @@
|
||||
import { useRef, useState } from "react";
|
||||
import CommanderTaxIcon from "../../Icons/CommanderTaxIcon";
|
||||
import styled from "styled-components";
|
||||
|
||||
export const StyledCommanderTaxButton = styled.button`
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const PartnerCommanderTaxButton = () => {
|
||||
const [partnerCommanderTax, setPartnerCommanderTax] = useState(0);
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||
|
||||
const handlePartnerCommanderTaxChange = (increment: number) => {
|
||||
setPartnerCommanderTax(partnerCommanderTax + increment);
|
||||
};
|
||||
|
||||
|
||||
const handleDownInput = () => {
|
||||
setTimeoutFinished(false);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setTimeoutFinished(true);
|
||||
handlePartnerCommanderTaxChange(-1);
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const handleUpInput = () => {
|
||||
if (!timeoutFinished) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
handlePartnerCommanderTaxChange(1);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledCommanderTaxButton
|
||||
onPointerDown={handleDownInput}
|
||||
onPointerUp={handleUpInput}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
>
|
||||
<CommanderTaxIcon
|
||||
size="8vh"
|
||||
text={partnerCommanderTax ? partnerCommanderTax : undefined}
|
||||
/> 2
|
||||
</StyledCommanderTaxButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default PartnerCommanderTaxButton;
|
||||
61
my-app/src/Components/Buttons/SubtractLifeButton.tsx
Normal file
61
my-app/src/Components/Buttons/SubtractLifeButton.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import { useRef, useState } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
export const StyledLifeCounterButton = styled.button<{ align?: string }>`
|
||||
width: 50%;
|
||||
height: auto;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
font-size: 4rem;
|
||||
font-weight: 600;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 0 28px;
|
||||
text-align: ${props => props.align || "center"};
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
type SubtractLifeButtonProps = {
|
||||
lifeTotal: number;
|
||||
setLifeTotal: (lifeTotal: number) => void;
|
||||
};
|
||||
|
||||
const SubtractLifeButton = ({ lifeTotal, setLifeTotal }: SubtractLifeButtonProps) => {
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||
|
||||
const handleLifeChange = (increment: number) => {
|
||||
setLifeTotal(lifeTotal + increment);
|
||||
};
|
||||
|
||||
const handleDownInput = () => {
|
||||
setTimeoutFinished(false);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
handleLifeChange(-10);
|
||||
setTimeoutFinished(true);
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const handleUpInput = () => {
|
||||
if (!timeoutFinished) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
handleLifeChange(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledLifeCounterButton
|
||||
onPointerDown={handleDownInput}
|
||||
onPointerUp={handleUpInput}
|
||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
align="left"
|
||||
>
|
||||
−
|
||||
</StyledLifeCounterButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default SubtractLifeButton;
|
||||
@@ -1,9 +1,9 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
export const CountersWrapper = styled.div`
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #4f4f4f;
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
background-color: black;
|
||||
`;
|
||||
|
||||
export const CountersGrid = styled.div`
|
||||
@@ -11,16 +11,27 @@ export const CountersGrid = styled.div`
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 10px;
|
||||
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
|
||||
-moz-box-sizing: border-box; /* Firefox, other Gecko */
|
||||
box-sizing: border-box; /* Opera/IE 8+ */
|
||||
row-gap: 4px;
|
||||
column-gap: 4px;
|
||||
`;
|
||||
|
||||
export const GridItemContainer = styled.div`
|
||||
display: flex;
|
||||
width: 50%;
|
||||
height: 50vh;
|
||||
width: calc(50vw - 2px);
|
||||
height: calc(50vh - 2px);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
export const GridItemContainerFlipped = styled.div`
|
||||
display: flex;
|
||||
width: calc(50vw - 2px);
|
||||
height: calc(50vh - 2px);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transform: rotate(180deg);
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
import * as S from "./Counters.style";
|
||||
import LifeCounter from "../LifeCounter/LifeCounter";
|
||||
import { Player } from "../../Types/Player";
|
||||
|
||||
type CountersProps = {
|
||||
players: Player[];
|
||||
};
|
||||
|
||||
const Counters = () => {
|
||||
return (
|
||||
<S.CountersWrapper>
|
||||
<S.CountersGrid>
|
||||
<S.GridItemContainer>
|
||||
<LifeCounter backgroundColor="grey"/>
|
||||
</S.GridItemContainer>
|
||||
<S.GridItemContainer>
|
||||
<LifeCounter backgroundColor="pink"/>
|
||||
</S.GridItemContainer>
|
||||
<S.GridItemContainer>
|
||||
<LifeCounter backgroundColor="white"/>
|
||||
</S.GridItemContainer>
|
||||
<S.GridItemContainer>
|
||||
<LifeCounter backgroundColor="lightblue"/>
|
||||
</S.GridItemContainer>
|
||||
</S.CountersGrid>
|
||||
</S.CountersWrapper>
|
||||
);
|
||||
const Counters = ({ players }: CountersProps) => {
|
||||
return (
|
||||
<S.CountersWrapper>
|
||||
<S.CountersGrid>
|
||||
{players.map((player) => {
|
||||
if (player.settings.flipped) {
|
||||
return (
|
||||
<S.GridItemContainerFlipped>
|
||||
<LifeCounter backgroundColor={player.color} player={player} opponents={
|
||||
players.filter((opponent) => opponent.key !== player.key)
|
||||
} />
|
||||
</S.GridItemContainerFlipped>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<S.GridItemContainer>
|
||||
<LifeCounter backgroundColor={player.color} player={player} opponents={
|
||||
players.filter((opponent) => opponent.key !== player.key)
|
||||
} />
|
||||
</S.GridItemContainer>
|
||||
)
|
||||
})}
|
||||
</S.CountersGrid>
|
||||
</S.CountersWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
export default Counters;
|
||||
|
||||
@@ -1,36 +1,44 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
|
||||
//LifeCounterWrapper with a background color variable:
|
||||
export const LifeCounterWrapper = styled.div<{ backgroundColor?: string }>`
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: ${props => props.backgroundColor || "antiquewhite"};
|
||||
border-radius: 10px;
|
||||
|
||||
`;
|
||||
|
||||
export const LifeCounterButton = styled.button`
|
||||
export const LifeCountainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 5rem;
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
export const LifeCounterText = styled.p`
|
||||
font-size: 5rem;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 30vh;
|
||||
text-align: center;
|
||||
text-size-adjust: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
font-variant-numeric: tabular-nums;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
export const ExtraCountersGrid = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +1,35 @@
|
||||
import { useState } from "react";
|
||||
import * as S from "./LifeCounter.style";
|
||||
import { Player } from "../../Types/Player";
|
||||
import CommanderTaxButton from "../Buttons/CommanderTaxButton";
|
||||
import PartnerCommanderTaxButton from "../Buttons/PartnerCommanderTaxButton copy";
|
||||
import AddLifeButton from "../Buttons/AddLifeButton";
|
||||
import SubtractLifeButton from "../Buttons/SubtractLifeButton";
|
||||
import CommanderDamageBar from "../Buttons/CommanderDamageBar";
|
||||
|
||||
type LifeCounterProps = {
|
||||
player: Player;
|
||||
backgroundColor: string;
|
||||
}
|
||||
opponents: Player[];
|
||||
};
|
||||
|
||||
const LifeCounter = ({backgroundColor}: LifeCounterProps) => {
|
||||
const [life, setLife] = useState(40);
|
||||
const LifeCounter = ({ backgroundColor, player, opponents }: LifeCounterProps) => {
|
||||
const [lifeTotal, setLifeTotal] = useState(40);
|
||||
|
||||
return (
|
||||
<S.LifeCounterWrapper backgroundColor={backgroundColor}>
|
||||
<S.LifeCounterButton onClick={() => setLife(life - 1)}>-</S.LifeCounterButton>
|
||||
<S.LifeCounterText>{life}</S.LifeCounterText>
|
||||
<S.LifeCounterButton onClick={() => setLife(life + 1)}>+</S.LifeCounterButton>
|
||||
<CommanderDamageBar lifeTotal={lifeTotal} setLifeTotal={setLifeTotal} opponents={opponents} />
|
||||
<S.LifeCountainer>
|
||||
<SubtractLifeButton lifeTotal={lifeTotal} setLifeTotal={setLifeTotal}/>
|
||||
<S.LifeCounterText>{lifeTotal}</S.LifeCounterText>
|
||||
<AddLifeButton lifeTotal={lifeTotal} setLifeTotal={setLifeTotal} />
|
||||
</S.LifeCountainer>
|
||||
<S.ExtraCountersGrid>
|
||||
<CommanderTaxButton/>
|
||||
{player.settings.usePartner && <PartnerCommanderTaxButton/>}
|
||||
</S.ExtraCountersGrid>
|
||||
</S.LifeCounterWrapper>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default LifeCounter;
|
||||
39
my-app/src/Icons/CommanderTaxIcon.tsx
Normal file
39
my-app/src/Icons/CommanderTaxIcon.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
type CommanderTaxIconProps = {
|
||||
size?: string;
|
||||
text?: number;
|
||||
};
|
||||
|
||||
const CommanderTaxIcon = ({ size, text }: CommanderTaxIconProps) => {
|
||||
return (
|
||||
<div style={{ position: 'relative', display: 'inline-block'}}>
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 325 325" width={size || 'auto'} height={size || 'auto'}>
|
||||
<title>CommanderTaxIcon</title>
|
||||
<style>{`.s0 { fill: #000000; fill-opacity: 0.5}`}</style>
|
||||
<path
|
||||
id="Lager 1"
|
||||
className="s0"
|
||||
d="m162 168c-40.9 0-74-33.1-74-74 0-40.9 33.1-74 74-74 40.9 0 74 33.1 74 74 0 40.9-33.1 74-74 74z"
|
||||
/>
|
||||
<path
|
||||
id="Form 1"
|
||||
className="s0"
|
||||
d="m159.9 351.8c-11.4 0.3-22.5 0.7-33.2 1.2-10.6 0.6-20.8 1.3-30.5 1.8-9.6 0.5-18.8 0.6-27.2 0.5-8.4-0.6-16.1-1.6-23-3.4-6.9-2.3-12.9-5.5-18.1-9.5-5-4.7-9.1-10.4-12.2-16.9-3.1-7.1-5.2-15-6.3-23.4-1.1-8.8-1.2-17.9-0.4-27.1 0.8-9.2 2.4-17.7 4.7-25.3 2.2-7.4 5.2-13.9 8.8-19.5 3.6-5.3 7.8-9.9 12.8-13.6 4.8-3.7 10.5-6.9 16.8-9.5 6.4-2.9 13.6-5.4 21.5-7.6 7.9-2.4 16.6-4.6 26-6.5 9.4-2.1 19.4-3.8 29.9-5 10.6-1.3 21.7-2 33-2 11.3 0 22.4 0.7 33 2 10.5 1.2 20.6 2.9 30 5 9.4 1.9 18.2 4.1 26.2 6.5 7.9 2.3 15.2 4.8 21.7 7.6 6.4 2.7 12.2 5.8 17.1 9.5 5.1 3.8 9.4 8.3 12.9 13.7 3.7 5.5 6.7 12.1 8.9 19.5 2.3 7.7 3.8 16.2 4.5 25.3 0.7 9.2 0.4 18.3-0.9 27.1-1.3 8.4-3.6 16.2-6.8 23.3-3.4 6.4-7.8 11.9-13.1 16.4-5.5 3.9-11.8 6.9-19 9.1-7.3 1.6-15.4 2.6-24.1 3-8.8 0.1-18.3-0.1-28.2-0.5-10-0.4-20.5-0.9-31.4-1.3-10.8-0.3-22-0.5-33.4-0.4z"
|
||||
/>
|
||||
</svg>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
fontSize: '8vh',
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommanderTaxIcon;
|
||||
15
my-app/src/Types/Player.ts
Normal file
15
my-app/src/Types/Player.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export type Player = {
|
||||
key: number;
|
||||
color: string;
|
||||
settings: PlayerSettings;
|
||||
}
|
||||
|
||||
type PlayerSettings = {
|
||||
useCommanderDamage: boolean;
|
||||
flipped?: boolean;
|
||||
usePartner?: boolean;
|
||||
usePoison?: boolean;
|
||||
useEnergy?: boolean;
|
||||
useExperience?: boolean;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user