Merge pull request '#9: make the user-chosen path more clear to see.' (#10) from feature/9-improve-display-of-solution into main
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Reviewed-on: #10
This commit is contained in:
commit
9b52470f6b
5 changed files with 137 additions and 12 deletions
|
@ -22,14 +22,88 @@
|
||||||
border-left-color: var(--color-maze-border);
|
border-left-color: var(--color-maze-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.user{
|
.userSELF {
|
||||||
background-color: var(--color-maze-cell-user);
|
background: radial-gradient(
|
||||||
|
ellipse 16% 16% at center,
|
||||||
|
var(--color-maze-cell-user) 0,
|
||||||
|
var(--color-maze-cell-user) 100%,
|
||||||
|
#0000 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.user:hover {
|
.userSELF:hover {
|
||||||
background-color: var(--color-maze-cell-user-highlight);
|
background: radial-gradient(
|
||||||
|
ellipse 33% 33% at center,
|
||||||
|
var(--color-maze-cell-user) 0,
|
||||||
|
var(--color-maze-cell-user) 80%,
|
||||||
|
#0000 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.solution.user {
|
.marker {
|
||||||
background-color: #c8ff00;
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marker:hover {
|
||||||
|
background: #fc08;
|
||||||
|
}
|
||||||
|
|
||||||
|
.userUP .marker.UP {
|
||||||
|
height: 50%;
|
||||||
|
width: 100%;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
#0000 0,
|
||||||
|
#0000 33%,
|
||||||
|
var(--color-maze-cell-user) 33%,
|
||||||
|
var(--color-maze-cell-user) 66%,
|
||||||
|
#0000 66%,
|
||||||
|
#0000 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.userRIGHT .marker.RIGHT {
|
||||||
|
height: 100%;
|
||||||
|
width: 50%;
|
||||||
|
left: 50%;
|
||||||
|
background: linear-gradient(
|
||||||
|
0deg,
|
||||||
|
#0000 0,
|
||||||
|
#0000 33%,
|
||||||
|
var(--color-maze-cell-user) 33%,
|
||||||
|
var(--color-maze-cell-user) 66%,
|
||||||
|
#0000 66%,
|
||||||
|
#0000 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.userDOWN .marker.DOWN {
|
||||||
|
height: 50%;
|
||||||
|
width: 100%;
|
||||||
|
top: 50%;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
#0000 0,
|
||||||
|
#0000 33%,
|
||||||
|
var(--color-maze-cell-user) 33%,
|
||||||
|
var(--color-maze-cell-user) 66%,
|
||||||
|
#0000 66%,
|
||||||
|
#0000 100%
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.userLEFT .marker.LEFT {
|
||||||
|
height: 100%;
|
||||||
|
width: 50%;
|
||||||
|
background: linear-gradient(
|
||||||
|
0deg,
|
||||||
|
#0000 0,
|
||||||
|
#0000 33%,
|
||||||
|
var(--color-maze-cell-user) 33%,
|
||||||
|
var(--color-maze-cell-user) 66%,
|
||||||
|
#0000 66%,
|
||||||
|
#0000 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
height: 2em;
|
height: 2em;
|
||||||
width: 2em;
|
width: 2em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cell:hover {
|
.cell:hover {
|
||||||
|
|
|
@ -6,8 +6,41 @@ import "./cell.css";
|
||||||
import {State} from "./state/state.ts";
|
import {State} from "./state/state.ts";
|
||||||
import {ActionDispatch} from "react";
|
import {ActionDispatch} from "react";
|
||||||
|
|
||||||
function isMarked(x: number, y: number, marked: Coordinates[]): boolean {
|
function getMarkedDirections(coords: Coordinates, marked: Coordinates[]): Direction[] {
|
||||||
return !!marked.find(e => e.x === x && e.y === y);
|
const cellIndex: number = marked.findIndex(e => e.x === coords.x && e.y === coords.y);
|
||||||
|
if (cellIndex === -1) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (marked.length === 1) {
|
||||||
|
return [Direction.SELF];
|
||||||
|
}
|
||||||
|
if (cellIndex === 0) {
|
||||||
|
const next: Coordinates = marked[1];
|
||||||
|
return [Direction.SELF, getDirectionTo(coords, next)];
|
||||||
|
} else {
|
||||||
|
const previous = marked[cellIndex - 1];
|
||||||
|
if (cellIndex === marked.length - 1) {
|
||||||
|
return [Direction.SELF, getDirectionTo(coords, previous)];
|
||||||
|
}
|
||||||
|
const next: Coordinates = marked[cellIndex + 1];
|
||||||
|
return [Direction.SELF, getDirectionTo(coords, previous), getDirectionTo(coords, next)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDirectionTo(me: Coordinates, other: Coordinates): Direction {
|
||||||
|
const xDiff = me.x - other.x;
|
||||||
|
switch (xDiff) {
|
||||||
|
case -1:
|
||||||
|
return Direction.RIGHT;
|
||||||
|
case 1:
|
||||||
|
return Direction.LEFT;
|
||||||
|
default:
|
||||||
|
const yDiff = me.y - other.y;
|
||||||
|
if (yDiff === -1) {
|
||||||
|
return Direction.DOWN;
|
||||||
|
}
|
||||||
|
return Direction.UP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Cell({x, y, state, dispatch}:
|
export default function Cell({x, y, state, dispatch}:
|
||||||
|
@ -24,8 +57,10 @@ export default function Cell({x, y, state, dispatch}:
|
||||||
if (cell.bottom) classes += " bottom";
|
if (cell.bottom) classes += " bottom";
|
||||||
if (cell.left) classes += " left";
|
if (cell.left) classes += " left";
|
||||||
if (cell.solution && state.showSolution) classes += " solution";
|
if (cell.solution && state.showSolution) classes += " solution";
|
||||||
const marked = isMarked(x, y, state.userPath);
|
const markedDirections = getMarkedDirections({x, y}, state.userPath);
|
||||||
if (marked) classes += " user";
|
for (let i = 0; i < markedDirections.length; i++) {
|
||||||
|
classes += ` user${Direction[markedDirections[i]]}`;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className={styles.cell + classes}
|
<div className={styles.cell + classes}
|
||||||
onMouseEnter={(e) => {
|
onMouseEnter={(e) => {
|
||||||
|
@ -37,6 +72,14 @@ export default function Cell({x, y, state, dispatch}:
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch(actionClickedCell(x, y));
|
dispatch(actionClickedCell(x, y));
|
||||||
}}>
|
}}>
|
||||||
|
<div className={"marker UP"}></div>
|
||||||
|
<div className={"marker RIGHT"}></div>
|
||||||
|
<div className={"marker DOWN"}></div>
|
||||||
|
<div className={"marker LEFT"}></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Direction {
|
||||||
|
UP, RIGHT, DOWN, LEFT, SELF
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import {ActionDispatch, FormEvent, useState} from 'react';
|
import {ActionDispatch, FormEvent, useState} from 'react';
|
||||||
import ValidatingInputNumberField, {ValidatorFunction} from "./validating-input-number-field.tsx";
|
import ValidatingInputNumberField, {ValidatorFunction} from "./validating-input-number-field.tsx";
|
||||||
import {Action, actionLoadedMaze, actionLoadingFailed, actionStartedLoading} from "./state/action.ts";
|
import {
|
||||||
|
Action,
|
||||||
|
actionLoadedMaze,
|
||||||
|
actionLoadingFailed,
|
||||||
|
actionStartedLoading,
|
||||||
|
actionToggledShowSolution
|
||||||
|
} from "./state/action.ts";
|
||||||
import styles from "./input-form.module.css";
|
import styles from "./input-form.module.css";
|
||||||
import "./input-form.css";
|
import "./input-form.css";
|
||||||
import {State} from "@/app/state/state.ts";
|
import {State} from "@/app/state/state.ts";
|
||||||
|
@ -17,10 +23,10 @@ export default function InputForm({state, dispatch}: {
|
||||||
const handleSubmit = (e: FormEvent) => {
|
const handleSubmit = (e: FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
dispatch(actionStartedLoading());
|
dispatch(actionStartedLoading());
|
||||||
|
dispatch(actionToggledShowSolution(false));
|
||||||
const url = `https://manuel.friedli.info/labyrinth/create/json?w=${width}&h=${height}&id=${id || ''}&algorithm=${algorithm}`;
|
const url = `https://manuel.friedli.info/labyrinth/create/json?w=${width}&h=${height}&id=${id || ''}&algorithm=${algorithm}`;
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
// .then(result => new Promise(resolve => setTimeout(resolve, 600, result)))
|
|
||||||
.then(result => {
|
.then(result => {
|
||||||
dispatch(actionLoadedMaze(result));
|
dispatch(actionLoadedMaze(result));
|
||||||
})
|
})
|
||||||
|
|
|
@ -25,6 +25,7 @@ export default function Home() {
|
||||||
<h1>The Maze ({state.maze!.width}x{state.maze!.height}, Algorithm: {state.maze!.algorithm},
|
<h1>The Maze ({state.maze!.width}x{state.maze!.height}, Algorithm: {state.maze!.algorithm},
|
||||||
ID: {state.maze!.id})</h1>
|
ID: {state.maze!.id})</h1>
|
||||||
<input type={"checkbox"}
|
<input type={"checkbox"}
|
||||||
|
checked={state.showSolution}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
dispatch(actionToggledShowSolution(e.target.checked));
|
dispatch(actionToggledShowSolution(e.target.checked));
|
||||||
}}
|
}}
|
||||||
|
|
Loading…
Reference in a new issue