mirror of
https://github.com/Xevion/100prisoners.git
synced 2025-12-14 16:11:00 -06:00
Per-box arrow refactor, stateful
This commit is contained in:
@@ -6,37 +6,43 @@ import Chance from "chance";
|
|||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
|
|
||||||
const chance = new Chance();
|
const chance = new Chance();
|
||||||
const sources = range(1, 100);
|
|
||||||
const destinations = chance.shuffle(sources);
|
|
||||||
const boxes: [number, number][] = sources.map((e, i) => [e, destinations[i] as number])
|
|
||||||
|
|
||||||
const BoxTable = () => {
|
const BoxTable = () => {
|
||||||
const [line, setLine] = useState<[string, string] | null>(null);
|
const [sources] = useState<number[]>(range(1, 100));
|
||||||
|
const [destinations] = useState<number[]>(chance.shuffle(sources));
|
||||||
|
const [boxes] = useState<[number, number][]>(sources.map((e, i) => [e, destinations[i] as number]))
|
||||||
|
|
||||||
const showLine = (from: number, to: number) => {
|
|
||||||
setLine([from.toString(), to.toString()]);
|
const [enabledLines, setEnabledLines] = useState<Record<number, boolean>>(Object.fromEntries(
|
||||||
|
sources.map(n => [n, false])
|
||||||
|
));
|
||||||
|
|
||||||
|
const showLine = (from: number) => {
|
||||||
|
setEnabledLines((prev) => ({...prev, [from]: true}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideLine = () => {
|
const hideLine = (from: number) => {
|
||||||
setLine(null);
|
setEnabledLines((prev) => ({...prev, [from]: false}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const columns = Math.ceil(Math.sqrt(boxes.length));
|
const columns = Math.ceil(Math.sqrt(boxes.length));
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{line != null ? <Xarrow color={"red"} start={line[0]} end={line[1]} zIndex={50}/> : null}
|
|
||||||
<div className="grid w-full space-y-2"
|
<div className="grid w-full space-y-2"
|
||||||
style={{gridTemplateColumns: `repeat(${Math.max(3, columns)}, minmax(0, 1fr))`}}>
|
style={{gridTemplateColumns: `repeat(${Math.max(3, columns)}, minmax(0, 1fr))`}}>
|
||||||
{boxes.map(([source, destination]) =>
|
{boxes.map(([source, destination]) =>
|
||||||
<div key={source} className="col-span-1 px-2" onMouseEnter={() => showLine(source, destination)}
|
<div key={source} className="col-span-1 px-2" onMouseEnter={() => showLine(source)}
|
||||||
onMouseLeave={hideLine}>
|
onMouseLeave={() => hideLine(source)}>
|
||||||
<div
|
<div
|
||||||
className="box flex items-center justify-center aspect-square relative">
|
className="box flex items-center justify-center aspect-square relative">
|
||||||
<div className="text absolute pt-[30%] cursor-pointer">{destination}</div>
|
<div className="text absolute pt-[30%] cursor-pointer">{destination}</div>
|
||||||
<BoxGraphic id={source.toString()} className="transition-all cursor-pointer relative z-30">
|
<BoxGraphic id={source.toString()} className="transition-all cursor-pointer relative z-30">
|
||||||
{source}
|
{source}
|
||||||
</BoxGraphic>
|
</BoxGraphic>
|
||||||
|
{enabledLines[source] ?
|
||||||
|
<Xarrow color={"red"} start={source.toString()} end={destination.toString()}
|
||||||
|
zIndex={50 + source}/> : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user