--- /dev/null
+import React from 'react';
+
+import Dungeons from './Dungeons';
+import Items from './Items';
+import Map from './Map';
+import { shouldShowDungeonItem } from '../../helpers/tracker';
+import { useTracker } from '../../hooks/tracker';
+
+const LAYOUTS = {
+ defaultHorizontal: {
+ width: 100,
+ height: 60,
+ itemsTransform: 'translate(1 1) scale(22)',
+ dungeonColumns: 4,
+ dungeonsTransform: 'translate(1 39) scale(98)',
+ mapTransform: 'translate(24 0) scale(76)',
+ },
+ defaultVertical: {
+ width: 100,
+ height: 100,
+ itemsTransform: 'translate(10 1) scale(30)',
+ dungeonColumns: 2,
+ dungeonsTransform: 'translate(1 51) scale(48)',
+ mapTransform: 'translate(50 0) scale(50)',
+ },
+ manyDungeonItemsVertical: {
+ width: 80,
+ height: 100,
+ itemsTransform: 'translate(1 1) scale(27)',
+ dungeonColumns: 1,
+ dungeonsTransform: 'translate(1 48) scale(24)',
+ mapTransform: 'translate(30 0) scale(50)',
+ },
+};
+
+const Canvas = () => {
+ const { config } = useTracker();
+
+ const layout = React.useMemo(() => {
+ if (config.mapLayout === 'vertical') {
+ let count = 0;
+ if (shouldShowDungeonItem(config, 'Map')) {
+ ++count;
+ }
+ if (shouldShowDungeonItem(config, 'Compass')) {
+ ++count;
+ }
+ if (shouldShowDungeonItem(config, 'Small')) {
+ ++count;
+ }
+ if (shouldShowDungeonItem(config, 'Big')) {
+ ++count;
+ }
+ return count > 2 ? LAYOUTS.manyDungeonItemsVertical : LAYOUTS.defaultVertical;
+ } else {
+ return LAYOUTS.defaultHorizontal;
+ }
+ }, [config]);
+
+ return <svg
+ xmlns="http://www.w3.org/2000/svg"
+ className="canvas"
+ width={layout.width}
+ height={layout.height}
+ viewBox={`0 0 ${layout.width} ${layout.height}`}
+ onContextMenu={(e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ }}
+ >
+ <g className="items" transform={layout.itemsTransform}>
+ <Items />
+ </g>
+ <g className="dungeons" transform={layout.dungeonsTransform}>
+ <Dungeons columns={layout.dungeonColumns} />
+ </g>
+ <g className="tracker-map" transform={layout.mapTransform}>
+ <Map />
+ </g>
+ </svg>;
+};
+
+export default Canvas;
+import PropTypes from 'prop-types';
import React from 'react';
import CountDisplay from './CountDisplay';
} from '../../helpers/tracker';
import { useTracker } from '../../hooks/tracker';
-const Dungeons = () => {
+const Dungeons = ({ columns }) => {
const { config, dungeons, state } = useTracker();
const layout = React.useMemo(() => {
const countX = shouldShowDungeonItem(config, 'Big') ? bigX + 1 : bigX;
const bossX = countX + 1;
const prizeX = bossX + 1;
- const dungeonWidth = prizeX + 1;
- const width = (4 * dungeonWidth) + 2;
+ const dungeonWidth = Math.max(5, prizeX + 1);
+ const width = (columns * dungeonWidth) + Math.max(0, columns - 1);
const height = 4;
- const viewBox = `0 0 ${width} ${height}`;
+
+ const transform = (col, row) =>
+ `scale(${1 / width}) translate(${
+ (col * dungeonWidth) + 0.5 + (col ? col - (columns > 3 ? 1 : 0) : 0)
+ } ${row + 0.5})`;
+
+ const transforms = {
+ tag: '',
+ map: `translate(${mapX} 0) scale(0.9)`,
+ compass: `translate(${compassX} 0) scale(0.9)`,
+ small: `translate(${smallX} 0) scale(0.9)`,
+ big: `translate(${bigX} 0) scale(0.9)`,
+ checks: `translate(${countX} 0) scale(0.9)`,
+ boss: `translate(${bossX} 0)`,
+ prize: `translate(${prizeX} 0)`,
+ hc: transform(0, 0),
+ ct: transform(0, 1),
+ gt: transform(0, 2),
+ gtBoss1: `translate(${bossX - 2} 1)`,
+ gtBoss2: `translate(${bossX - 1} 1)`,
+ gtBoss3: `translate(${bossX} 1)`,
+ };
+
+ if (columns === 1) {
+ transforms.ep = transform(0, 4);
+ transforms.dp = transform(0, 5);
+ transforms.th = transform(0, 6);
+ transforms.pd = transform(0, 8);
+ transforms.sp = transform(0, 9);
+ transforms.sw = transform(0, 10);
+ transforms.tt = transform(0, 11);
+ transforms.ip = transform(0, 12);
+ transforms.mm = transform(0, 13);
+ transforms.tr = transform(0, 14);
+ } else if (columns === 2) {
+ transforms.ep = transform(0, 4);
+ transforms.dp = transform(0, 5);
+ transforms.th = transform(0, 6);
+ transforms.pd = transform(1, 0);
+ transforms.sp = transform(1, 1);
+ transforms.sw = transform(1, 2);
+ transforms.tt = transform(1, 3);
+ transforms.ip = transform(1, 4);
+ transforms.mm = transform(1, 5);
+ transforms.tr = transform(1, 6);
+ } else {
+ transforms.ep = transform(1, 0);
+ transforms.dp = transform(1, 1);
+ transforms.th = transform(1, 2);
+ transforms.pd = transform(2, 0);
+ transforms.sp = transform(2, 1);
+ transforms.sw = transform(2, 2);
+ transforms.tt = transform(2, 3);
+ transforms.ip = transform(3, 0);
+ transforms.mm = transform(3, 1);
+ transforms.tr = transform(3, 2);
+ }
+
return {
width,
height,
- viewBox,
- transform: {
- tag: '',
- map: `translate(${mapX} 0) scale(0.9)`,
- compass: `translate(${compassX} 0) scale(0.9)`,
- small: `translate(${smallX} 0) scale(0.9)`,
- big: `translate(${bigX} 0) scale(0.9)`,
- checks: `translate(${countX} 0) scale(0.9)`,
- boss: `translate(${bossX} 0)`,
- prize: `translate(${prizeX} 0)`,
- hc: 'translate(0.5, 0.5)',
- ct: 'translate(0.5, 1.5)',
- gt: 'translate(0.5, 2.5)',
- gtBoss1: `translate(${bossX - 2} 1)`,
- gtBoss2: `translate(${bossX - 1} 1)`,
- gtBoss3: `translate(${bossX} 1)`,
- ep: `translate(${dungeonWidth + 0.5}, 0.5)`,
- dp: `translate(${dungeonWidth + 0.5}, 1.5)`,
- th: `translate(${dungeonWidth + 0.5}, 2.5)`,
- pd: `translate(${(2 * dungeonWidth) + 1.5}, 0.5)`,
- sp: `translate(${(2 * dungeonWidth) + 1.5}, 1.5)`,
- sw: `translate(${(2 * dungeonWidth) + 1.5}, 2.5)`,
- tt: `translate(${(2 * dungeonWidth) + 1.5}, 3.5)`,
- ip: `translate(${(3 * dungeonWidth) + 2.5}, 0.5)`,
- mm: `translate(${(3 * dungeonWidth) + 2.5}, 1.5)`,
- tr: `translate(${(3 * dungeonWidth) + 2.5}, 2.5)`,
- },
+ transforms,
};
}, [config, dungeons]);
- return <svg
- xmlns="http://www.w3.org/2000/svg"
- className="dungeons"
- width={layout.width}
- height={layout.height}
- viewBox={layout.viewBox}
- onContextMenu={(e) => {
- e.preventDefault();
- e.stopPropagation();
- }}
- >
+ return <>
{dungeons.map(dungeon =>
<g
className={`dungeon dungeon-${dungeon.id}`}
key={dungeon.id}
- transform={layout.transform[dungeon.id]}
+ transform={layout.transforms[dungeon.id]}
>
- <g transform={layout.transform.tag}>
+ <g transform={layout.transforms.tag}>
<text className="dungeon-tag">{dungeon.id.toUpperCase()}</text>
</g>
{shouldShowDungeonItem(config, 'Map') ?
- <g transform={layout.transform.map}>
+ <g transform={layout.transforms.map}>
<ToggleIcon
controller={ToggleIcon.dungeonController(dungeon)}
icons={['map']}
</g>
: null}
{shouldShowDungeonItem(config, 'Compass') ?
- <g transform={layout.transform.compass}>
+ <g transform={layout.transforms.compass}>
<ToggleIcon
controller={ToggleIcon.dungeonController(dungeon)}
icons={['compass']}
</g>
: null}
{shouldShowDungeonItem(config, 'Small') ?
- <g transform={layout.transform.small}>
+ <g transform={layout.transforms.small}>
<ToggleIcon
controller={ToggleIcon.dungeonCountController(dungeon, dungeon.sk)}
icons={['small-key']}
</g>
: null}
{shouldShowDungeonItem(config, 'Big') ?
- <g transform={layout.transform.big}>
+ <g transform={layout.transforms.big}>
<ToggleIcon
controller={ToggleIcon.dungeonController(dungeon)}
icons={['big-key']}
/>
</g>
: null}
- <g transform={layout.transform.checks}>
+ <g transform={layout.transforms.checks}>
<ToggleIcon
controller={ToggleIcon.dungeonCheckController(dungeon)}
icons={['open-chest', 'chest']}
<CountDisplay count={getDungeonRemainingItems(state, dungeon)} />
</g>
{dungeon.boss ?
- <g transform={layout.transform.boss}>
+ <g transform={layout.transforms.boss}>
<ToggleIcon
controller={ToggleIcon.dungeonBossController(dungeon)}
icons={dungeon.bosses}
</g>
: null}
{dungeon.prize ?
- <g transform={layout.transform.prize}>
+ <g transform={layout.transforms.prize}>
<ToggleIcon
controller={ToggleIcon.dungeonPrizeController(dungeon)}
icons={[
</g>
: null}
{dungeon.id === 'gt' && config.bossShuffle ? <>
- <g transform={layout.transform.gtBoss1}>
+ <g transform={layout.transforms.gtBoss1}>
<ToggleIcon
controller={ToggleIcon.gtBossController('bot')}
icons={BOSSES}
svg
/>
</g>
- <g transform={layout.transform.gtBoss2}>
+ <g transform={layout.transforms.gtBoss2}>
<ToggleIcon
controller={ToggleIcon.gtBossController('mid')}
icons={BOSSES}
svg
/>
</g>
- <g transform={layout.transform.gtBoss3}>
+ <g transform={layout.transforms.gtBoss3}>
<ToggleIcon
controller={ToggleIcon.gtBossController('top')}
icons={BOSSES}
</> : null}
</g>
)}
- </svg>;
+ </>;
+};
+
+Dungeons.propTypes = {
+ columns: PropTypes.number,
+};
+
+Dungeons.defaultProps = {
+ columns: 4,
};
export default Dungeons;