Skip to content

Instantly share code, notes, and snippets.

@click2install
Last active August 12, 2021 08:36
Show Gist options
  • Save click2install/f05467193e529bbad658445a609add19 to your computer and use it in GitHub Desktop.
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.
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>
);
}
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