Avatar Color Generator

by Erick Petrucelli

HTML

<div id="app"></div>

SCSS

body {
  background: #20262E;
  padding: 0;
  margin: 0;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  transition: all 0.2s;
}

.app {
  padding: 1rem;
  transition: 0.25s;
  &.Light {
    background-color: #fff;
    color: #222;
  }
  &.Dark {
    background-color: #222;
    color: #fff;
  }
  h1 {
    margin-bottom: 1rem;
    font-size: 2rem;
  }
}

.inputs {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  
  .singleInput {
    margin-bottom: 0.5rem;
    display: flex;
    font-size: 0.75rem;
    .inputLabel {
      width: 6rem;
    }
    input, select {
      margin-right: 1rem;
      width: 15rem;
    }
  }
}

.row {
  display: inline-flex;
  width: 50%;
  min-width: 15rem;
  align-items: center;
  margin-bottom: 0.5rem;
}
.userName {
  width: 50%;
}
.avatarColor {
  width: 2.5rem;
  height: 2.5rem;
  margin-right: 0.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  &.Light {
    color: #fff;
  }
  &.Dark {
    color: #333;
  }
}

React

const getHashOfString = (str) => {
  let hash = 0;
  for (let i = str.length - 1; i > -1; i--) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash);
  }
  hash = Math.abs(hash);
  return hash;
};

const normalizeHash = (hash, min, max) => {
  return Math.floor((hash % (max - min)) + min);
};

const generateHSL = (name, saturationRange, lightnessRange) => {
  const hash = getHashOfString(name);
  const h = normalizeHash(hash, 0, 360);
  const s = normalizeHash(hash, saturationRange[0], saturationRange[1]);
  const l = normalizeHash(hash, lightnessRange[0], lightnessRange[1]);
  return [h, s, l];
};

const HSLtoString = (hsl) => {
  return `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
};

const generateColorHsl = (id, saturationRange, lightnessRange) => {
  return HSLtoString(generateHSL(id, saturationRange, lightnessRange));
};

const getInitials = (user) => {
	return `${user.name.first[0]}${user.name.last[0]}`
}

const setValue = (functionFor) => {
	return (e) => {
  	const value = parseInt(e.target.value);
    functionFor(value);
  }
};

const getRange = (value, range) => {
	return [Math.max(0, value-range), Math.min(value+range, 100)];
}

const fetchUsers = () => {
	return fetch("https://randomuser.me/api/?results=13&inc=name,email")
  	.then((response) => response.json().then((json) =>
    	[{name:{first: 'Erick', last: 'Petrucelli'}}, ...json.results]
    ));
}

const Users = (props) => {
  const [users, setUsers] = React.useState([]);
  const [range, setRange] = React.useState(10);
  const [saturation, setSaturation] = React.useState(30);
  const [lightness, setLightness] = React.useState(40);
  const [theme, setTheme] = React.useState('Light');
  
  React.useEffect(() => {
    fetchUsers().then((usersList) => setUsers(usersList));
  }, []);
  
  const saturationRange = getRange(saturation, range);
  const lightnessRange = getRange(lightness, range);
  	
  return (
  	<div className={`app ${theme}`}>
      <h1>Avatar Color Generator</h1>
      <div...