Merge pull request #14 from jhalitaksoy/fix/themes

Fix/themes
This commit is contained in:
Halit Aksoy 2022-07-13 15:59:14 +03:00 committed by GitHub
commit f8f25c36b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 78 additions and 139 deletions

View File

@ -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}
/> />

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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
View 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;

View File

@ -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;

View File

@ -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() {

View File

@ -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;
} }