Generate single color for each result

Asked

Viewed 1,589 times

5

then. i have a system of comments anonymously in a project of mine that in place of the avatar it puts the abbreviation of the person’s name, for example:

Vinicius Eduardo -> VE

and I want to create a system or function that generates a unique COLOR for each abbreviation, so the user can be identified more easily.

In short, I have an array containing 24 colors in "#VLVLVL" format and for each abbreviation it will give a unique color, for example VE -> #cccccc ED -> #000000 and if the VE comment again its color repeats as #cccc

  • So it will be at most 24 abbreviations? What if a twenty-fifth appears?

  • Agree, only 24? O_O Good, but if the site is small I see no problem :D

  • I used 24 as an example, if by chance we could solve this question I would increase the color table over time.

  • OK, the solution I posted supports as many colors as you have in the array, the more the better, but if the number of users exceeds the number of colors the script for.

  • 1

    Playing Interaction Design: What’s the Goal from the user’s perspective? It is really differentiate two people with the same abbreviation (Vinicius Eduardo and Valeria Escobar, for example) or just differentiate the abbreviations in the comments showoff on a screen? If it is the second one, the number of colors required tends to be much lower if they are not fixed. Also, perhaps the contrast between colors is more important than the choice of color itself.

  • 1

    If it is the first case (differentiate people), perhaps you can consider differentiation by occurrence of duplicity. Like, it wouldn’t matter if there was a red AP and a red VE, but if there were more than one VE there they would be differentiated by very different colors (despite having a rather large color combination in the RGB, the concern to make them have sufficient contrast should decrease a bit that number).

  • I like the way you think, I’ll adapt and use!

Show 2 more comments

2 answers

7


Considering an array of colors like this:

$cores = array('#000', '#333', '#666', '#999'); // do tamanho que você precisar

I would create a second array, associative, where you save colors for each user. It starts empty:

$coresPorUsuario = array();

And the idea is that it will contain the colors of the users as they arise. For example, array('VE' => '#000', 'ED' => '#333').

To control everything, use a function. It receives the user’s initials and returns the corresponding color. If the user already exists in $coresPorUsuario, take the color that is there. If it does not exist, take the next available color, associate it to the user, and return that color. You will also need a variable to control which is the next available color.

$proxima = 0;    
function corUsuario($usuario) {

    global $cores;
    global $coresPorUsuario;
    global $proxima;

    // Usuário ainda não existe na array
    if(empty($coresPorUsuario[$usuario])) {
        // Guarda a cor do usuário e avança para a próxima cor disponível
        $coresPorUsuario[$usuario] = $cores[$proxima++];

        // Se passou da quantidade de cores disponíveis, começa novamente da primeira
        $proxima = $proxima == count($cores) ? 0 : $proxima;
    }

    // Retorna a cor do usuário
    return $coresPorUsuario[$usuario];
}

WARNING: The above example uses global variables as a short path as an example. You may want to implement this function as a class method. In this case, use instance properties instead of global variables.

Testing:

echo corUsuario('AA') . "\n"; // #000
echo corUsuario('AB') . "\n"; // #333
echo corUsuario('AC') . "\n"; // #666
echo corUsuario('AA') . "\n"; // #000
echo corUsuario('AD') . "\n"; // #999
echo corUsuario('AE') . "\n"; // #000

Demonstration

  • Good this solution, if the number of colors runs out, it restarts from 0,

  • Yeah, that’s up to whoever uses the code to decide whether to add more colors or let the function rotate.

  • 1

    Hahah! enough to be good to see a script working properly, thank you very much worked!

4

You can create an array for the colors already used and another for each user’s colors.

I could use a shorter and more practical solution, (and which alias uses less CPU..) but I wanted the colors to be random.. but as users (ordered by ID) are already random enough, I find the bfavaretto solution better. Although I find his solution more practical and light, I will keep my case I still have some use...

I made a simple "illustration".

<?php
// Array para as cores de cada usuário.
# "NomeDeUsuario" => "COR HEX";
$usersColors = array();

// Array para as cores disponiveis [usei cores aleatorias]
$avaliableColors = array(
    0 => "#ececea",
    1 => "#efefef",
    2 => "#abcdef"
);

// Primeiro pegamos os usuários, eles são a parte importantes
$users = array(
    'banana123',
    'SouEUmesmo',
    'kitKat159',
);

// Se tiver mais usuários do que cores, abortar execução
if ( count($users) > count($avaliableColors) ) {
    die("ERRO: existem mais usuários do que cores.");
}

// Vamos criar uma array que guarda as cores ja usadas, pra não repeti-las
$alreadyUsed = array();
$userCount = count($users);
$colorCount = count($avaliableColors);

// Definindo uma cor aleatoria para cada um
for ($i=0;$i<$userCount;++$i) {
    // Numero aleatorio representando uma das cores.
    $max = $colorCount-1;
    $numeroAleatorio = rand(0, $max);

    if (in_array($numeroAleatorio, $alreadyUsed)) {
        // Se o numero ja tiver sido usado, ficar até encontrar um não utilizado
        $numeroNaoUsadoEncontrado = false;

        while ($numeroNaoUsadoEncontrado != true) {
            $numeroAleatorio = rand(0, $max);

            // Se o numero não tiver sido utilziado aidna
            if (!in_array($numeroAleatorio, $alreadyUsed)) {
                // Sair do loop de tentativas
                $numeroNaoUsadoEncontrado = true;

                // Colocar esse numero como já usado.
                $alreadyUsed[] = $numeroAleatorio;
            }
        }
    }
    else {
        // Colocar esse numero como já usado.
        $alreadyUsed[] = $numeroAleatorio;
    }

    // Agora que a cor ja foi escolhida, atribuir ela ao usuário
    $userName = $users[$i];
    $usersColors[$userName] = $avaliableColors[$numeroAleatorio];
}


# DEBUG
echo "<br>";
foreach ($usersColors as $user => $color) {
    echo $user . " -> " . $color . "<br/>\n";
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.