commit
f8f25c36b3
16
src/Home.tsx
16
src/Home.tsx
@ -21,7 +21,7 @@ import { v4 } from "uuid";
|
|||||||
import { Menu, MenuButton, MenuItem } from "@szhsin/react-menu";
|
import { Menu, MenuButton, MenuItem } from "@szhsin/react-menu";
|
||||||
import "@szhsin/react-menu/dist/index.css";
|
import "@szhsin/react-menu/dist/index.css";
|
||||||
import "@szhsin/react-menu/dist/transitions/slide.css";
|
import "@szhsin/react-menu/dist/transitions/slide.css";
|
||||||
import { getColorByLuminance } from "./util/ColorUtil";
|
import { getColorByBrightness } from "./util/ColorUtil";
|
||||||
import { Theme } from "./theme/Theme";
|
import { Theme } from "./theme/Theme";
|
||||||
|
|
||||||
type ConnectionState = "connecting" | "error" | "connected" | "reconnecting";
|
type ConnectionState = "connecting" | "error" | "connected" | "reconnecting";
|
||||||
@ -183,7 +183,7 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
<Button
|
<Button
|
||||||
context={context}
|
context={context}
|
||||||
text={context.texts.NewGame}
|
text={context.texts.NewGame}
|
||||||
color={context.themeManager.theme.primary}
|
color={context.themeManager.theme.holeColor}
|
||||||
onClick={newGameClick}
|
onClick={newGameClick}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -200,10 +200,10 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
}
|
}
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
const menuTextColor = getColorByLuminance(
|
const menuTextColor = getColorByBrightness(
|
||||||
context.themeManager.theme.appBarBgColor,
|
context.themeManager.theme.appBarBgColor,
|
||||||
context.themeManager.theme.primary,
|
context.themeManager.theme.textColor,
|
||||||
context.themeManager.theme.primaryLight
|
context.themeManager.theme.textLightColor
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -225,8 +225,8 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
borderTopRightRadius: "1vw",
|
borderTopRightRadius: "1vw",
|
||||||
minWidth: "10vw",
|
minWidth: "10vw",
|
||||||
minHeight: "1vw",
|
minHeight: "1vw",
|
||||||
background: context.themeManager.theme.primary,
|
background: context.themeManager.theme.textColor,
|
||||||
color: context.themeManager.theme.primaryLight,
|
color: context.themeManager.theme.textLightColor,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{connectionStateText()}
|
{connectionStateText()}
|
||||||
@ -313,7 +313,7 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
(game?.state === "playing" || game?.state === "initial") && (
|
(game?.state === "playing" || game?.state === "initial") && (
|
||||||
<Button
|
<Button
|
||||||
context={context}
|
context={context}
|
||||||
color={context.themeManager.theme.primary}
|
color={context.themeManager.theme.holeColor}
|
||||||
text={context.texts.Leave}
|
text={context.texts.Leave}
|
||||||
onClick={leaveGame}
|
onClick={leaveGame}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { v4 } from "uuid";
|
|||||||
import { Context } from "../context";
|
import { Context } from "../context";
|
||||||
import BoardViewModelFactory from "../factory/BoardViewModelFactory";
|
import BoardViewModelFactory from "../factory/BoardViewModelFactory";
|
||||||
import { PitViewModelFactory } from "../factory/PitViewModelFactory";
|
import { PitViewModelFactory } from "../factory/PitViewModelFactory";
|
||||||
import { getColorByLuminance } from "../util/ColorUtil";
|
import { getColorByBrightness } from "../util/ColorUtil";
|
||||||
import BoardViewModel from "../viewmodel/BoardViewModel";
|
import BoardViewModel from "../viewmodel/BoardViewModel";
|
||||||
|
|
||||||
const animationUpdateInterval = 300;
|
const animationUpdateInterval = 300;
|
||||||
@ -131,7 +131,7 @@ export default class PitAnimator {
|
|||||||
pitViewModel.pitColor = theme.pitGetRivalStonePitAnimateColor;
|
pitViewModel.pitColor = theme.pitGetRivalStonePitAnimateColor;
|
||||||
pitViewModel.stoneCount = 0;
|
pitViewModel.stoneCount = 0;
|
||||||
}
|
}
|
||||||
pitViewModel.stoneColor = getColorByLuminance(
|
pitViewModel.stoneColor = getColorByBrightness(
|
||||||
pitViewModel.pitColor,
|
pitViewModel.pitColor,
|
||||||
theme.stoneColor,
|
theme.stoneColor,
|
||||||
theme.stoneLightColor
|
theme.stoneLightColor
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Bank, MancalaGame, Pit } from "mancala.js";
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { FunctionComponent, useState } from "react";
|
import { FunctionComponent, useState } from "react";
|
||||||
import { Context } from "../context";
|
import { Context } from "../context";
|
||||||
import { getColorByLuminance } from "../util/ColorUtil";
|
import { getColorByBrightness } from "../util/ColorUtil";
|
||||||
import BoardViewModel from "../viewmodel/BoardViewModel";
|
import BoardViewModel from "../viewmodel/BoardViewModel";
|
||||||
import PitViewModel from "../viewmodel/PitViewModel";
|
import PitViewModel from "../viewmodel/PitViewModel";
|
||||||
|
|
||||||
@ -68,10 +68,10 @@ const StoreView: FunctionComponent<{
|
|||||||
const balls = [...range(pitViewModel.stoneCount)].map((i) => (
|
const balls = [...range(pitViewModel.stoneCount)].map((i) => (
|
||||||
<BallView color={pitViewModel.stoneColor} />
|
<BallView color={pitViewModel.stoneColor} />
|
||||||
));
|
));
|
||||||
const textColor = getColorByLuminance(
|
const textColor = getColorByBrightness(
|
||||||
pitViewModel.pitColor,
|
pitViewModel.pitColor,
|
||||||
context.themeManager.theme.primary,
|
context.themeManager.theme.textColor,
|
||||||
context.themeManager.theme.primaryLight
|
context.themeManager.theme.textLightColor
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { FunctionComponent } from "react";
|
import { FunctionComponent } from "react";
|
||||||
import { Context } from "../context";
|
import { Context } from "../context";
|
||||||
import { getColorByLuminance } from "../util/ColorUtil";
|
import { getColorByBrightness } from "../util/ColorUtil";
|
||||||
|
|
||||||
const Button: FunctionComponent<{
|
const Button: FunctionComponent<{
|
||||||
context: Context;
|
context: Context;
|
||||||
@ -9,10 +9,10 @@ const Button: FunctionComponent<{
|
|||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
color: string;
|
color: string;
|
||||||
}> = ({ context, text, color, onClick }) => {
|
}> = ({ context, text, color, onClick }) => {
|
||||||
const textColor = getColorByLuminance(
|
const textColor = getColorByBrightness(
|
||||||
color,
|
color,
|
||||||
context.themeManager.theme.primary,
|
context.themeManager.theme.textColor,
|
||||||
context.themeManager.theme.primaryLight
|
context.themeManager.theme.textLightColor
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { MancalaGame } from "mancala.js";
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { FunctionComponent } from "react";
|
import { FunctionComponent } from "react";
|
||||||
import { Context } from "../context";
|
import { Context } from "../context";
|
||||||
import { getColorByLuminance } from "../util/ColorUtil";
|
import { getColorByBrightness } from "../util/ColorUtil";
|
||||||
|
|
||||||
function getInfoPanelTextByGameState(params: {
|
function getInfoPanelTextByGameState(params: {
|
||||||
context: Context;
|
context: Context;
|
||||||
@ -86,11 +86,11 @@ const InfoPanel: FunctionComponent<{
|
|||||||
const isUserTurn = game?.checkIsPlayerTurn(userKey);
|
const isUserTurn = game?.checkIsPlayerTurn(userKey);
|
||||||
const containerColor = isUserTurn
|
const containerColor = isUserTurn
|
||||||
? context.themeManager.theme.playerTurnColor
|
? context.themeManager.theme.playerTurnColor
|
||||||
: context.themeManager.theme.holeColor;
|
: context.themeManager.theme.boardColor;
|
||||||
const textColor = getColorByLuminance(
|
const textColor = getColorByBrightness(
|
||||||
containerColor,
|
containerColor,
|
||||||
context.themeManager.theme.primary,
|
context.themeManager.theme.textColor,
|
||||||
context.themeManager.theme.primaryLight
|
context.themeManager.theme.textLightColor
|
||||||
);
|
);
|
||||||
const text = getInfoPanelTextByGameState({
|
const text = getInfoPanelTextByGameState({
|
||||||
context,
|
context,
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
import { Theme } from "./Theme";
|
|
||||||
|
|
||||||
// https://colorhunt.co/palette/525252414141313131ec625f
|
|
||||||
const colors = {
|
|
||||||
primary: "#414141",
|
|
||||||
secondary: "#313131",
|
|
||||||
tertiary: "#606060",
|
|
||||||
quaternary: "#808080",
|
|
||||||
};
|
|
||||||
|
|
||||||
const colorSpecial = "#337a44";
|
|
||||||
|
|
||||||
const darkGreyTheme: Theme = {
|
|
||||||
id: "3",
|
|
||||||
name: "Dark Grey Theme",
|
|
||||||
background: colors.primary,
|
|
||||||
appBarBgColor: colors.secondary,
|
|
||||||
primary: colors.primary,
|
|
||||||
primaryLight: "#aaaaaa",
|
|
||||||
playerTurnColor: colors.secondary,
|
|
||||||
boardColor: colors.secondary,
|
|
||||||
holeColor: colors.tertiary,
|
|
||||||
pitSelectedColor: colors.secondary,
|
|
||||||
stoneColor: "#252525",
|
|
||||||
stoneLightColor: "#252525",
|
|
||||||
pitGameMoveAnimateColor: colors.quaternary,
|
|
||||||
pitEmptyPitAnimateColor: colorSpecial,
|
|
||||||
pitLastStoneInBankPitAnimateColor: colorSpecial,
|
|
||||||
pitGetRivalStonePitAnimateColor: colorSpecial,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default darkGreyTheme;
|
|
||||||
@ -1,28 +1,28 @@
|
|||||||
import { Theme } from "./Theme";
|
import { Theme } from "./Theme";
|
||||||
|
|
||||||
// from https://colorhunt.co/palette/0f0e0e5412128b9a46eeeeee
|
// https://colorhunt.co/palette/525252414141313131ec625f
|
||||||
const colors = {
|
const colors = {
|
||||||
primary: "#541212",
|
primary: "#414141",
|
||||||
secondary: "#0F0E0E",
|
secondary: "#313131",
|
||||||
tertiary: "#8B9A46",
|
tertiary: "#606060",
|
||||||
quaternary: "#EEEEEE",
|
quaternary: "#808080",
|
||||||
};
|
};
|
||||||
|
|
||||||
const colorSpecial = "#990000";
|
const colorSpecial = "#337a44";
|
||||||
|
|
||||||
const darkTheme: Theme = {
|
const darkTheme: Theme = {
|
||||||
id: "2",
|
id: "2",
|
||||||
name: "Dark Theme",
|
name: "Dark Theme",
|
||||||
background: colors.primary,
|
background: colors.primary,
|
||||||
appBarBgColor: colors.secondary,
|
appBarBgColor: colors.secondary,
|
||||||
primary: colors.primary,
|
textColor: colors.primary,
|
||||||
primaryLight: colors.quaternary,
|
textLightColor: "#AAAAAA",
|
||||||
playerTurnColor: colors.secondary,
|
playerTurnColor: colors.tertiary,
|
||||||
boardColor: colors.secondary,
|
boardColor: colors.secondary,
|
||||||
holeColor: colors.tertiary,
|
holeColor: colors.tertiary,
|
||||||
pitSelectedColor: colors.tertiary,
|
pitSelectedColor: colors.secondary,
|
||||||
stoneColor: colors.primary,
|
stoneColor: "#252525",
|
||||||
stoneLightColor: colors.tertiary,
|
stoneLightColor: "#252525",
|
||||||
pitGameMoveAnimateColor: colors.quaternary,
|
pitGameMoveAnimateColor: colors.quaternary,
|
||||||
pitEmptyPitAnimateColor: colorSpecial,
|
pitEmptyPitAnimateColor: colorSpecial,
|
||||||
pitLastStoneInBankPitAnimateColor: colorSpecial,
|
pitLastStoneInBankPitAnimateColor: colorSpecial,
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
import { Theme } from "./Theme";
|
|
||||||
|
|
||||||
// https://colorhunt.co/palette/7d5a50b4846ce5b299fcdec0
|
|
||||||
const colors = {
|
|
||||||
primary: "#7D5A50",
|
|
||||||
secondary: "#B4846C",
|
|
||||||
tertiary: "#E5B299",
|
|
||||||
quaternary: "#FCDEC0",
|
|
||||||
};
|
|
||||||
|
|
||||||
const colorSpecial = "#F6A9A9";
|
|
||||||
|
|
||||||
const defaultTheme: Theme = {
|
|
||||||
id: "1",
|
|
||||||
name: "Default Light Theme",
|
|
||||||
background: "#EEEEEE",
|
|
||||||
appBarBgColor: colors.quaternary,
|
|
||||||
primary: colors.primary,
|
|
||||||
primaryLight: colors.quaternary,
|
|
||||||
playerTurnColor: colors.secondary,
|
|
||||||
boardColor: colors.secondary,
|
|
||||||
holeColor: colors.quaternary,
|
|
||||||
pitSelectedColor: colors.tertiary,
|
|
||||||
stoneColor: colors.primary,
|
|
||||||
stoneLightColor: colors.tertiary,
|
|
||||||
pitGameMoveAnimateColor: colors.tertiary,
|
|
||||||
pitEmptyPitAnimateColor: colorSpecial,
|
|
||||||
pitLastStoneInBankPitAnimateColor: colorSpecial,
|
|
||||||
pitGetRivalStonePitAnimateColor: colorSpecial,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default defaultTheme;
|
|
||||||
@ -1,12 +1,12 @@
|
|||||||
import { Theme } from "./Theme";
|
import { Theme } from "./Theme";
|
||||||
|
|
||||||
const oldTheme: Theme = {
|
const greyTheme: Theme = {
|
||||||
id: "0",
|
id: "1",
|
||||||
name: "Old Theme",
|
name: "Grey Theme",
|
||||||
background: "#EEEEEE",
|
background: "#EEEEEE",
|
||||||
appBarBgColor: "#e4e4e4",
|
appBarBgColor: "#e4e4e4",
|
||||||
primary: "#4D606E",
|
textColor: "#4D606E",
|
||||||
primaryLight: "#EEEEEE",
|
textLightColor: "#EEEEEE",
|
||||||
playerTurnColor: "#84b8a6",
|
playerTurnColor: "#84b8a6",
|
||||||
boardColor: "#4D606E",
|
boardColor: "#4D606E",
|
||||||
holeColor: "#D3D4D8",
|
holeColor: "#D3D4D8",
|
||||||
@ -19,4 +19,4 @@ const oldTheme: Theme = {
|
|||||||
pitGetRivalStonePitAnimateColor: "#ff3d44",
|
pitGetRivalStonePitAnimateColor: "#ff3d44",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default oldTheme;
|
export default greyTheme;
|
||||||
24
src/theme/LightTheme.ts
Normal file
24
src/theme/LightTheme.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { Theme } from "./Theme";
|
||||||
|
|
||||||
|
const colorSpecial = "#8B8B8B";
|
||||||
|
|
||||||
|
const lightTheme: Theme = {
|
||||||
|
id: "1",
|
||||||
|
name: "Light Theme",
|
||||||
|
background: "#BBBBBB",
|
||||||
|
appBarBgColor: "#7B7B7B",
|
||||||
|
textColor: "#5B5B5B",
|
||||||
|
textLightColor: "#EBEBEB",
|
||||||
|
playerTurnColor: "#6B6B6B",
|
||||||
|
boardColor: "#9B9B9B",
|
||||||
|
holeColor: "#B8B8B8",
|
||||||
|
pitSelectedColor: "#9B9B9B",
|
||||||
|
stoneColor: "#5B5B5B",
|
||||||
|
stoneLightColor: "#3B3B3B",
|
||||||
|
pitGameMoveAnimateColor: "#ABABAB",
|
||||||
|
pitEmptyPitAnimateColor: colorSpecial,
|
||||||
|
pitLastStoneInBankPitAnimateColor: colorSpecial,
|
||||||
|
pitGetRivalStonePitAnimateColor: colorSpecial,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default lightTheme;
|
||||||
@ -1,8 +1,8 @@
|
|||||||
export type Theme = {
|
export type Theme = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
primary: string;
|
textColor: string;
|
||||||
primaryLight: string;
|
textLightColor: string;
|
||||||
background: string;
|
background: string;
|
||||||
appBarBgColor: string;
|
appBarBgColor: string;
|
||||||
playerTurnColor: string;
|
playerTurnColor: string;
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
import darkGreyTheme from "./DarkGrey";
|
import lightTheme from "./LightTheme";
|
||||||
import darkTheme from "./DarkTheme";
|
import greyTheme from "./GreyTheme";
|
||||||
import defaultTheme from "./DefaultTheme";
|
|
||||||
import oldTheme from "./OldTheme";
|
|
||||||
import { Theme } from "./Theme";
|
import { Theme } from "./Theme";
|
||||||
|
import darkTheme from "./DarkTheme";
|
||||||
|
|
||||||
export const themes = [defaultTheme, darkGreyTheme, darkTheme, oldTheme];
|
export const themes = [lightTheme, darkTheme, greyTheme];
|
||||||
|
|
||||||
const THEME_ID = "theme_id";
|
const THEME_ID = "theme_id";
|
||||||
|
|
||||||
@ -12,7 +11,7 @@ export default class ThemeManager {
|
|||||||
_theme: Theme;
|
_theme: Theme;
|
||||||
onThemeChange: (theme: Theme) => void;
|
onThemeChange: (theme: Theme) => void;
|
||||||
constructor() {
|
constructor() {
|
||||||
this._theme = this.readFromLocalStorage() || defaultTheme;
|
this._theme = this.readFromLocalStorage() || lightTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get theme() {
|
public get theme() {
|
||||||
|
|||||||
@ -1,31 +1,11 @@
|
|||||||
//from this gist https://gist.github.com/jfsiii/5641126
|
|
||||||
|
|
||||||
// from http://www.w3.org/TR/WCAG20/#relativeluminancedef
|
export function getBrightness(r: number, g: number, b: number) {
|
||||||
export function relativeLuminanceW3C(
|
return (r * 299 + g * 587 + b * 114) / 1000;
|
||||||
R8bit: number,
|
|
||||||
G8bit: number,
|
|
||||||
B8bit: number
|
|
||||||
) {
|
|
||||||
const RsRGB = R8bit / 255;
|
|
||||||
const GsRGB = G8bit / 255;
|
|
||||||
const BsRGB = B8bit / 255;
|
|
||||||
|
|
||||||
const R =
|
|
||||||
RsRGB <= 0.03928 ? RsRGB / 12.92 : Math.pow((RsRGB + 0.055) / 1.055, 2.4);
|
|
||||||
const G =
|
|
||||||
GsRGB <= 0.03928 ? GsRGB / 12.92 : Math.pow((GsRGB + 0.055) / 1.055, 2.4);
|
|
||||||
const B =
|
|
||||||
BsRGB <= 0.03928 ? BsRGB / 12.92 : Math.pow((BsRGB + 0.055) / 1.055, 2.4);
|
|
||||||
|
|
||||||
// For the sRGB colorspace, the relative luminance of a color is defined as:
|
|
||||||
const L = 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
|
||||||
|
|
||||||
return L;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function relativeLuminanceW3CHexColor(hexColor: string): number {
|
export function getBrightnessFromHexColor(hexColor: string): number {
|
||||||
const [r, g, b] = hexToRgb(hexColor);
|
const [r, g, b] = hexToRgb(hexColor);
|
||||||
return relativeLuminanceW3C(r, g, b);
|
return getBrightness(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from https://www.codegrepper.com/code-examples/javascript/javascript+convert+color+string+to+rgb
|
// from https://www.codegrepper.com/code-examples/javascript/javascript+convert+color+string+to+rgb
|
||||||
@ -42,10 +22,10 @@ export function hexToRgb(
|
|||||||
//returns [23, 14, 45] -> reformat if needed
|
//returns [23, 14, 45] -> reformat if needed
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getColorByLuminance(
|
export function getColorByBrightness(
|
||||||
color: string,
|
color: string,
|
||||||
lightColor: string,
|
lightColor: string,
|
||||||
darkColor: string
|
darkColor: string
|
||||||
): string {
|
): string {
|
||||||
return relativeLuminanceW3CHexColor(color) < 0.5 ? darkColor : lightColor;
|
return getBrightnessFromHexColor(color) < 125 ? darkColor : lightColor;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user