Last active
August 12, 2021 08:36
-
-
Save click2install/f05467193e529bbad658445a609add19 to your computer and use it in GitHub Desktop.
[Avatar] - A React avatar component for autogenrating avatar based on a given name.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { Avatar } from "./Avatar"; | |
export default function App() | |
{ | |
return ( | |
<div className="App"> | |
<Avatar name="display middle name" background="#1FDA8A" size={32} highContrast={false} rounded={false} bold={true} /> | |
</div> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
export function Avatar({ name, size = 32, background, rounded = false, bold = true, highContrast = true }) | |
{ | |
const svgStyle = | |
{ | |
fill: invertColor(background, highContrast), | |
textTransform: "uppercase", | |
pointerEvents: "none", | |
userSelect: "none", | |
width: size, | |
height: size, | |
fontWeight: bold ? "bold" : "normal" | |
}; | |
const [first, last] = splitName(name); | |
return ( | |
<svg style={svgStyle} preserveAspectRatio="xMidYMid meet"> | |
{rounded | |
? <circle cx={size / 2} cy={size / 2} r={size / 2} fill={background} /> | |
: <rect width={size} height={size} fill={background} />} | |
<text x="50%" y="50%" dy=".1em" fontSize={`${size * 0.5}`} textAnchor="middle" dominantBaseline="middle"> | |
{first}{last} | |
</text> | |
</svg> | |
); | |
} | |
// splits the string on space and | |
// - uses the first character of the first and last values | |
// - or the first and second character of the first value | |
// - or the first character of the first value | |
function splitName(name = "") | |
{ | |
if (name.length < 1) | |
{ | |
throw new Error("Invalid name."); | |
} | |
const split = name.split(" "); | |
const firstItem = split[0]; | |
const lastItem = split.slice(-1); | |
const first = firstItem[0]; | |
const last = split.length > 1 && lastItem.length > 0 | |
? lastItem[0][0] | |
: firstItem.length > 1 ? firstItem[1] : ""; | |
return [first, last]; | |
} | |
function invertColor(hex, highContrast = true) | |
{ | |
let color = hex.indexOf("#") === 0 ? hex.slice(1) : hex; | |
if (color.length === 3) | |
{ | |
color = color | |
.split("") | |
.reduce((acc, cur) => acc.concat([cur, cur]), []) | |
.join(""); | |
} | |
if (color.length < 6) | |
{ | |
throw new Error("Invalid HEX color."); | |
} | |
let r = parseInt(color.slice(0, 2), 16); | |
let g = parseInt(color.slice(2, 4), 16); | |
let b = parseInt(color.slice(4, 6), 16); | |
if (highContrast) | |
{ | |
// http://stackoverflow.com/a/3943023/112731 | |
return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? "#000000" : "#FFFFFF"; | |
} | |
// invert color components and pad each with zeros | |
r = (255 - r).toString(16).padStart(2, "0"); | |
g = (255 - g).toString(16).padStart(2, "0"); | |
b = (255 - b).toString(16).padStart(2, "0"); | |
return `#${r}${g}${b}`; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment