feat: adding average color to profile hero

This commit is contained in:
Chubby Granny Chaser 2024-06-17 23:04:10 +01:00
parent e7ba7b87b6
commit 2ae10decf7
No known key found for this signature in database
3 changed files with 30 additions and 12 deletions

View file

@ -1,5 +1,7 @@
import type { GameShop } from "@types"; import type { GameShop } from "@types";
import Color from "color";
export const steamUrlBuilder = { export const steamUrlBuilder = {
library: (objectID: string) => library: (objectID: string) =>
`https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/header.jpg`, `https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/header.jpg`,
@ -40,3 +42,6 @@ export const buildGameDetailsPath = (
const searchParams = new URLSearchParams({ title: game.title, ...params }); const searchParams = new URLSearchParams({ title: game.title, ...params });
return `/game/${game.shop}/${game.objectID}?${searchParams.toString()}`; return `/game/${game.shop}/${game.objectID}?${searchParams.toString()}`;
}; };
export const darkenColor = (color: string, amount: number) =>
new Color(color).darken(amount).toString();

View file

@ -1,16 +1,15 @@
import { UserGame, UserProfile } from "@types"; import { UserGame, UserProfile } from "@types";
import cn from "classnames"; import cn from "classnames";
import { average } from "color.js"; import { average } from "color.js";
import Color from "color";
import * as styles from "./user.css"; import * as styles from "./user.css";
import { SPACING_UNIT, vars } from "@renderer/theme.css"; import { SPACING_UNIT, vars } from "@renderer/theme.css";
import { useMemo } from "react"; import { useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import SteamLogo from "@renderer/assets/steam-logo.svg?react"; import SteamLogo from "@renderer/assets/steam-logo.svg?react";
import { useDate } from "@renderer/hooks"; import { useDate } from "@renderer/hooks";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { buildGameDetailsPath } from "@renderer/helpers"; import { buildGameDetailsPath, darkenColor } from "@renderer/helpers";
import { PersonIcon } from "@primer/octicons-react"; import { PersonIcon } from "@primer/octicons-react";
import { Button } from "@renderer/components"; import { Button } from "@renderer/components";
import { useUserAuth } from "@renderer/hooks/use-user-auth"; import { useUserAuth } from "@renderer/hooks/use-user-auth";
@ -25,6 +24,10 @@ export const UserContent = ({ userProfile }: ProfileContentProps) => {
const { userAuth, signOut } = useUserAuth(); const { userAuth, signOut } = useUserAuth();
const profileImageRef = useRef<HTMLImageElement | null>(null);
const [backgroundColors, setBackgroundColors] = useState<string[]>([]);
const navigate = useNavigate(); const navigate = useNavigate();
const numberFormatter = useMemo(() => { const numberFormatter = useMemo(() => {
@ -62,25 +65,29 @@ export const UserContent = ({ userProfile }: ProfileContentProps) => {
}; };
const handleAvatarLoad = async () => { const handleAvatarLoad = async () => {
console.log(userProfile.profileImageUrl); const output = await average(profileImageRef.current!, {
const output = await average(userProfile.profileImageUrl!, {
amount: 1, amount: 1,
format: "hex", format: "hex",
}); });
const backgroundColor = output setBackgroundColors([
? (new Color(output).darken(0.7).toString() as string) darkenColor(output as string, 0.6),
: ""; darkenColor(output as string, 0.7),
]);
console.log(backgroundColor);
}; };
return ( return (
<> <>
<section className={styles.profileContentBox}> <section
className={styles.profileContentBox}
style={{
backgroundImage: `linear-gradient(135deg, ${backgroundColors[0]}, ${backgroundColors[1]})`,
}}
>
<div className={styles.profileAvatarContainer}> <div className={styles.profileAvatarContainer}>
{userProfile.profileImageUrl ? ( {userProfile.profileImageUrl ? (
<img <img
ref={profileImageRef}
className={styles.profileAvatar} className={styles.profileAvatar}
alt={userProfile.displayName} alt={userProfile.displayName}
src={userProfile.profileImageUrl} src={userProfile.profileImageUrl}

View file

@ -11,13 +11,15 @@ export const wrapper = style({
export const profileContentBox = style({ export const profileContentBox = style({
display: "flex", display: "flex",
gap: `${SPACING_UNIT + SPACING_UNIT / 2}px`, gap: `${SPACING_UNIT * 3}px`,
padding: `${SPACING_UNIT * 4}px ${SPACING_UNIT * 2}px`, padding: `${SPACING_UNIT * 4}px ${SPACING_UNIT * 2}px`,
alignItems: "center", alignItems: "center",
borderRadius: "4px", borderRadius: "4px",
border: `solid 1px ${vars.color.border}`, border: `solid 1px ${vars.color.border}`,
width: "100%", width: "100%",
overflow: "hidden", overflow: "hidden",
boxShadow: "0px 0px 15px 0px rgba(0, 0, 0, 0.7)",
transition: "all ease 0.3s",
}); });
export const profileAvatarContainer = style({ export const profileAvatarContainer = style({
@ -30,17 +32,21 @@ export const profileAvatarContainer = style({
backgroundColor: vars.color.background, backgroundColor: vars.color.background,
position: "relative", position: "relative",
overflow: "hidden", overflow: "hidden",
border: `solid 1px ${vars.color.border}`,
boxShadow: "0px 0px 5px 0px rgba(0, 0, 0, 0.7)",
}); });
export const profileAvatar = style({ export const profileAvatar = style({
width: "96px", width: "96px",
height: "96px", height: "96px",
objectFit: "cover",
}); });
export const profileInformation = style({ export const profileInformation = style({
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "flex-start", alignItems: "flex-start",
color: "#c0c1c7",
}); });
export const profileContent = style({ export const profileContent = style({