Skip to content

Commit

Permalink
some UX improvements to color game
Browse files Browse the repository at this point in the history
  • Loading branch information
ryqndev committed May 11, 2024
1 parent dcae5b0 commit 34bd36e
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 30 deletions.
4 changes: 3 additions & 1 deletion src/app/pages/ColorGame/ColorGame.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from "./components/HexColorInput/HexColorInput";
import { Results } from "./components/Results/Results";
import Auto from "react-animate-height";
import { Instructions } from "./components/Instructions/Instructions";
const generateRandomHexString = () => {
const randomHex = [];

Expand All @@ -24,6 +25,7 @@ export const ColorGame = memo(function ColorGame() {
const [color, setColor] = useState(generateRandomHexString);
const [report, setReport] = useState();
const [height, setHeight] = useState("auto");
const contentRef = useRef(null);

const resetColor = useCallback(
() => setColor(generateRandomHexString()),
Expand All @@ -41,7 +43,6 @@ export const ColorGame = memo(function ColorGame() {

return () => resizeObserver.disconnect();
}, []);
const contentRef = useRef(null);

return (
<div className={cn.page}>
Expand Down Expand Up @@ -72,6 +73,7 @@ export const ColorGame = memo(function ColorGame() {
{report && <Results report={report} />}
</Auto>
<Leaderboard report={report} />
<Instructions />
</div>
);
});
3 changes: 2 additions & 1 deletion src/app/pages/ColorGame/ColorGame.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
gap: 20px;
margin: 0 auto;

padding: 20px;
padding: 20px 20px 80px;
box-sizing: border-box;


Expand All @@ -31,6 +31,7 @@
width: 200px;
border-radius: 8px;
margin-bottom: 0px;
transition: width 250ms;
}

@media screen and (max-width: 900px) {
Expand Down
14 changes: 11 additions & 3 deletions src/app/pages/ColorGame/components/HexColorInput/HexColorInput.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createRef, memo, useMemo, useState } from "react";
import { createRef, memo, useEffect, useMemo, useState } from "react";
import cn from "./HexColorInput.module.scss";
import clsx from "clsx";
import { generateReport } from "./generateReport";
Expand Down Expand Up @@ -36,10 +36,15 @@ export const HexColorInput = memo(function HexColorInput({
resetColor,
}) {
const [guess, setGuess] = useState(EMPTY_GUESS);
const [showErrorMessage, setErrorMessage] = useState(false);
const [input] = useState(() => Array.from({ length: 6 }, createRef));

const guessIsValid = useMemo(() => guess.join("").length === 6, [guess]);

useEffect(() => {
if (showErrorMessage) setTimeout(() => setErrorMessage(false), 2500);
}, [showErrorMessage]);

const ignoreEvent = (event) => {
event.preventDefault();
};
Expand All @@ -61,7 +66,7 @@ export const HexColorInput = memo(function HexColorInput({
const handleInput = (index) => (event) => {
const userKeyInput = event.nativeEvent.data.toUpperCase();

if (!DIGITS.includes(userKeyInput)) return;
if (!DIGITS.includes(userKeyInput)) return setErrorMessage(true);

setGuess((prev) => {
const next = [...prev];
Expand Down Expand Up @@ -96,7 +101,7 @@ export const HexColorInput = memo(function HexColorInput({
return;

case "ArrowRight":
if (index > 5) return;
if (index > 4) return;
focusEndOfInput(input[index + 1].current);
return;

Expand Down Expand Up @@ -144,6 +149,9 @@ export const HexColorInput = memo(function HexColorInput({
<img alt="refresh" src={REFRESH_ICON} />
</button>
</div>
<div className={clsx(cn.error, showErrorMessage && cn.visible)}>
Only 0-9 and A-F are valid hex values.
</div>
</form>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
grid-template-columns: auto auto;
gap: 20px;
min-width: 600px;
transition: width 250ms;

@media screen and (max-width: 1000px) {
grid-template-columns: auto;
Expand All @@ -16,7 +17,7 @@
}

}

.actions {
display: grid;
grid-template-columns: auto auto;
Expand All @@ -27,7 +28,7 @@
display: grid;
grid-template-columns: repeat(7, 32px);
gap: 8px;

input {
border: none;
border-bottom: 2px solid var(--gray);
Expand All @@ -37,15 +38,15 @@
&::placeholder {
opacity: 0.1;
}

&.underline {
color: var(--gray);
border: none;
}
}
}
button{

button {
border: 2px solid var(--silver);
padding: 0 20px;
border-radius: 8px;
Expand All @@ -57,12 +58,12 @@
color: var(--silver);
font-weight: bold;
cursor: not-allowed;

&.allowed {
color: var(--green);
border-color: var(--green);
cursor: pointer;

&:hover {
background-color: var(--green);
color: var(--white);
Expand All @@ -84,4 +85,26 @@
}

}
}

.error {
display: grid;
grid-column: 1 / 3;
color: transparent;

transition: color 250ms;
font-size: 0.9em;
text-align: center;

height: 0;
overflow: visible;

&.visible {
color: var(--red);
}

@media screen and (max-width: 1000px) {
height: auto;
grid-column: 1/ 2;
}
}
}
33 changes: 33 additions & 0 deletions src/app/pages/ColorGame/components/Instructions/Instructions.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import clsx from "clsx";
import { memo, useRef } from "react";
import cn from "./Instructions.module.scss";
import { Text } from "app/components";
import COLOR_BREAKDOWN from "./breakdown.png";

export const Instructions = memo(function Instructions() {
return (
<div className={clsx(cn.container, "slim")}>
<div className={cn.header}>
<Text color="blue" className={clsx(cn.title, "bold")} size="L">
How to play
</Text>
</div>
<p>
Hex colors are made up of 6 hexadecimal characters (hexadecimals
are numbers that go from 0-9, A, B, C, D, E, F, rather than just
0-9 in our normal decimal system) and are split into 3 sections:
Red, Green and Blue - commonly known as RGB.
</p>
<img
src={COLOR_BREAKDOWN}
alt="color hex code with individual groups color coded with highlights"
/>
<p>
Each hex color is essentially a blend of these three primary
colors. Compared to traditional print (CYMK), adding more of
each color makes the overall color brighter so #FFFFFF would be
white and #000000 would be black.
</p>
</div>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.container {
padding: 20px;
border: 2px solid var(--silver);
border-radius: 18px;
// width: min-content;

.header {
display: grid;
grid-template-columns: 1fr auto;
width: 100%;
}

p {
margin: 20px 0;
line-height: 1.3em;
width: fit-content;
font-size: 1.3em;

@media screen and (max-width: 1000px) {
font-size: 1em;
}

}
img {
margin: 0 auto;
max-height: 200px;

@media screen and (max-width: 1000px) {
max-height: 100px;
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 9 additions & 13 deletions src/app/pages/ColorGame/components/Leaderboard/Leaderboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Auto from "react-animate-height";
import { Text } from "app/components";
import { ScoreItem } from "./components/ScoreItem";

const PADDING = 40;
const PADDING = 16;
const HIGHSCORE_LOCALSTORAGE_KEY = "@duci/color-game-highscore";

export const Leaderboard = memo(function Leaderboard({ report }) {
Expand Down Expand Up @@ -45,16 +45,12 @@ export const Leaderboard = memo(function Leaderboard({ report }) {
}, []);

return (
<Auto
duration={500}
height={height}
className={clsx(cn.container, "slim")}
>
<div ref={contentRef}>
<Text color="blue" className={clsx(cn.title, "bold")} size="L">
High Scores
</Text>
<div className={cn.list}>
<div className={clsx(cn.container, "slim")}>
<Text color="blue" className={clsx(cn.title, "bold")} size="L">
High Scores
</Text>
<Auto duration={500} height={height} className={clsx(cn.list)}>
<div ref={contentRef}>
{!highscores.length && (
<div className={cn.empty}>
No previous scores to show.
Expand All @@ -64,7 +60,7 @@ export const Leaderboard = memo(function Leaderboard({ report }) {
<ScoreItem key={score.timestamp} report={score} />
))}
</div>
</div>
</Auto>
</Auto>
</div>
);
});
33 changes: 31 additions & 2 deletions src/app/pages/ColorGame/components/Results/Results.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,43 @@ import { memo } from "react";
import cn from "./Results.module.scss";

export const Results = memo(function Results({ report }) {
const actualColor = "#" + report.actual;
const guessColor = "#" + report.guess;

return (
<div className={cn.container}>
<Text size="L" className="color blue">
You were {report.similarityPercentage.toFixed(2)}% of the way
there!
</Text>
<div>answer: #{report.actual}</div>
<div> you guessed: #{report.guess} </div>
<div className={cn.split}>
<div className={cn.left}>
<div className={cn.description}>
<Text size="S" className="color gray">
ANSWER
</Text>
<br />
<p className={cn.color}>{actualColor}</p>
</div>
<div
className={cn.box}
style={{ backgroundColor: actualColor }}
></div>
</div>
<div className={cn.right}>
<div
className={cn.box}
style={{ backgroundColor: guessColor }}
></div>
<div className={cn.description}>
<Text size="S" className="color gray">
GUESS
</Text>
<br />
<p className={cn.color}>{guessColor}</p>
</div>
</div>
</div>
</div>
);
});
Loading

0 comments on commit 34bd36e

Please sign in to comment.