fangpenlin / avataaars

React component for avataaars
MIT License
785 stars 168 forks source link

Random seed #8

Open stevenleeg opened 6 years ago

stevenleeg commented 6 years ago

Hey there!

This library looks amazing and I'm about to implement it into a project now. Any chance you'd be interested in having an avatar generated given a seed phrase? It could look something like this:

<Avatar seed="[some-random-string]" />

Any time Avatar received that seed string it would output the same avatar, similar to the way you can replicate Minecraft worlds by providing it with the same seed phrase upon generation.

Awesome work and thanks for building this!!

fangpenlin commented 6 years ago

Hey @stevenleeg, thanks for the feedback, I think that's a good idea. However, unfortunately I don't have bandwidth to do this for now. If you can open a new PR for it, I am happy to review it.

elis commented 6 years ago

Hey, I needed something like this.

Here's my implementation:

import React from 'react'
import Avatar from 'avataaars'

const Avataaar = props => (
  <Avatar
    avatarStyle='Circle'
    {...props}
  />
)

export const SeededAvataaar = ({seed}) => {
  const items = seed.match(/.{1,2}/g).map(e => parseInt(e, 16))
  const options = { }
  const keys = [...configsKeys]

  keys.map((e, i) => Object.assign(options, {[e]: configs[e][items[i] % configs[e].length]}))

  return (
    <Avataaar {...options} />
  )
}

const configs = {
  topType: [
    'NoHair',
    'Eyepatch',
    'Hat',
    'Hijab',
    'Turban',
    'WinterHat1',
    'WinterHat2',
    'WinterHat3',
    'WinterHat4',
    'LongHairBigHair',
    'LongHairBob',
    'LongHairBun',
    'LongHairCurly',
    'LongHairCurvy',
    'LongHairDreads',
    'LongHairFrida',
    'LongHairFro',
    'LongHairFroBand',
    'LongHairNotTooLong',
    'LongHairShavedSides',
    'LongHairMiaWallace',
    'LongHairStraight',
    'LongHairStraight2',
    'LongHairStraightStrand',
    'ShortHairDreads01',
    'ShortHairDreads02'
  ],
  accessoriesType: [
    'Blank',
    'Kurt',
    'Prescription01',
    'Prescription02',
    'Round',
    'Sunglasses',
    'Wayfarers'
  ],
  hatColor: [
    'Black',
    'Blue01',
    'Blue02',
    'Blue03',
    'Gray01',
    'Gray02',
    'Heather',
    'PastelBlue',
    'PastelGreen',
    'PastelOrange',
    'PastelRed',
    'PastelYellow',
    'Pink',
    'Red',
    'White'
  ],
  hairColor: [
    'Auburn',
    'Black',
    'Blonde',
    'BlondeGolden',
    'Brown',
    'BrownDark',
    'PastelPink',
    'Platinum',
    'Red',
    'SilverGray'
  ],
  facialHairType: [
    'Blank',
    'BeardMedium',
    'BeardLight',
    'BeardMajestic',
    'MoustacheFancy',
    'MoustacheMagnum'
  ],
  facialHairColor: [
    'Auburn',
    'Black',
    'Blonde',
    'BlondeGolden',
    'Brown',
    'BrownDark',
    'Platinum',
    'Red'
  ],
  clotheType: [
    'BlazerShirt',
    'BlazerSweater',
    'CollarSweater',
    'GraphicShirt',
    'Hoodie',
    'Overall',
    'ShirtCrewNeck',
    'ShirtScoopNeck',
    'ShirtVNeck'
  ],
  clotheColor: [
    'Black',
    'Blue01',
    'Blue02',
    'Blue03',
    'Gray01',
    'Gray02',
    'Heather',
    'PastelBlue',
    'PastelGreen',
    'PastelOrange',
    'PastelRed',
    'PastelYellow',
    'Pink',
    'Red',
    'White'
  ],
  graphicType: [
    'Bat',
    'Cumbia',
    'Deer',
    'Diamond',
    'Hola',
    'Pizza',
    'Resist',
    'Selena',
    'Bear',
    'SkullOutline',
    'Skull'
  ],
  eyeType: [
    'Close',
    'Cry',
    'Default',
    'Dizzy',
    'EyeRoll',
    'Happy',
    'Hearts',
    'Side',
    'Squint',
    'Surprised',
    'Wink',
    'WinkWacky'
  ],
  eyebrowType: [
    'Angry',
    'AngryNatural',
    'Default',
    'DefaultNatural',
    'FlatNatural',
    'RaisedExcited',
    'RaisedExcitedNatural',
    'SadConcerned',
    'SadConcernedNatural',
    'UnibrowNatural',
    'UpDown',
    'UpDownNatural'
  ],
  mouthType: [
    'Concerned',
    'Default',
    'Disbelief',
    'Eating',
    'Grimace',
    'Sad',
    'ScreamOpen',
    'Serious',
    'Smile',
    'Tongue',
    'Twinkle',
    'Vomit'
  ],
  skinColor: [
    'Tanned',
    'Yellow',
    'Pale',
    'Light',
    'Brown',
    'DarkBrown',
    'Black'
  ]
}

const configsKeys = Object.keys(configs)

Note that the seed is expected to be a large hexadecimal string - by large I mean at least 12 pairs of hex characters (see seeded avataaat implementation as to why or how it's used).

kaibakker commented 6 years ago

@elis your implementation looks good.

What is exactly your mapping 1 bytes => 1 attribute? I think it would be interesting if empty/blank attributes would show up when a byte is 0x00. What do you think would be the right distribution of the different items. Show every item the same number of times?

PS: Your current implementation shows styles at the beginning of the list more often than the ones at the end, because how you use the modulo "%".

FlorianKoerner commented 5 years ago

You could use https://avatars.dicebear.com. Support for avatars has been added recently.

jay-khatri commented 4 years ago

@FlorianKoerner @fangpenlin @elis I'd love to have a way to generate an avatar deterministically based on arbitrary id. The problem I see with https://avatars.dicebear.com is that it requires a web request. If I'm rendering 100s of avatars on the same screen, this is really costly.

Is there still interest in a PR to do something like this? (In a client-only fashion).

FlorianKoerner commented 4 years ago

@jay-khatri

You can also use DiceBear Avatars without HTTP API / Web Request. You just have to install the NPM packages. See: https://github.com/DiceBear/avatars/tree/v4/packages/avatars-avataaars-sprites#npm

jay-khatri commented 4 years ago

Didn't know that, thanks 🙏 .