#9: make the user-chosen path more clear to see.
This commit is contained in:
		
							parent
							
								
									78b8772eff
								
							
						
					
					
						commit
						9efd718c9c
					
				
					 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue