Just4Fun - Аватарки!

4088

Здравствуйте, любители InstantCMS 2.x =)


Недавно на форуме была поднята тема в рамках которой я вспомнил об одной своей идее с цветными дефолтными аватарками. Хотя называть эту идею "своей" в корне не правильно, т.к. её я подсмотрел у mail.ru и google.

Наверняка многие видели эти цветные аватарки с буквами:
Записал идею в "список добрых дел" и отложил в дальний ящик, до наступления лучших дней свободного времени...

Основная идея заключается в уходе от серости стандартных аватарок тех пользователей которые не установили свою картинку для однозначной идентификации себя в сообществе ваших сайтов.

И вот, вчера вечером, я не смог удержаться от любопытства и набросал пару строк кода чтобы посмотреть как это может выглядеть в нашей любимой CMS.

Итак, кто не боится хаков (внесение изменений в ядро системы) может также поиграться с изменением аватарок. Для этого в файле ..\system\libs\template.helper.php немного модифицируем функцию html_avatar_image($avatars, $size_preset='small', $alt='') - 261-ая строка:
Код PHP:
  1. function html_avatar_image($avatars, $size_preset='small', $alt=''){
  2.  
  3. if (empty($avatars)){
  4.  
  5. // генерируем фоновый цвет из никнейма
  6. $bg_color = $alt
  7. ? substr( dechex(crc32($alt)), 0, 6 )
  8. : sprintf( '%02X%02X%02X', rand(0, 255), rand(0, 255), rand(0, 255) );
  9.  
  10. // выбираем контрастный цвет для текста
  11. $r = hexdec( substr($bg_color, 0, 2) );
  12. $g = hexdec( substr($bg_color, 2, 2) );
  13. $b = hexdec( substr($bg_color, 4, 2) );
  14. $yiq = (($r*299)+($g*587)+($b*114)) / 1000;
  15. $txt_color = ($yiq >= 128) ? 'black' : 'white';
  16.  
  17. // более простой метод определения контрастного цвета (менее точный)
  18. // $txt_color = (hexdec($bg_color) > 0xffffff/2) ? 'black' : 'white';
  19.  
  20. $wh = 64;
  21. if ($size_preset == 'normal') { $wh = 200; }
  22. if ($size_preset == 'micro') { $wh = 32; }
  23.  
  24. $style = "background-color: rgba({$r}, {$g}, {$b}, .7); " // "background-color: #{$bg_color}; "
  25. ."color: {$txt_color}; "
  26. ."width: {$wh}px; "
  27. ."height: {$wh}px; "
  28. ."line-height: {$wh}px;"
  29. ."font-size: ".round($wh*0.625)."px";
  30.  
  31. $type = $alt ? 'letter' : 'user-'.$txt_color;
  32. //$type = $alt ? 'user-'.$txt_color : 'letter';
  33.  
  34. return '<div class="avatar-colorbox '.$type.'" title="'.htmlspecialchars($alt).'" style="'.$style.'" data-letter="'.mb_substr($alt, 0, 1).'"></div>';
  35.  
  36. }
  37.  
  38. $size = $size_preset == 'micro' ? 'width="32" height="32"' : '';
  39.  
  40. $src = html_avatar_image_src($avatars, $size_preset);
  41.  
  42. return '<img src="'.$src.'" '.$size.' alt="'.htmlspecialchars($alt).'" />';
  43.  
  44. }
Здесь мы проверяем установлен ли аватар у пользователя, и если нет, собираем наш вариант. Получаем цвет из никнейма пользователя, который обычно передаётся в переменной $alt, но если его там не окажется, то цвет генерируется случайным образом. Кто хочет более тонкой настройки получаемого цвета может использовать вот эту функцию gist.github.com/mrkmg/1607621. Затем определяем цвет буквы аватара - белый или черный, так, чтобы он был контрастным фоновому цвету. В переменной $type мы указываем какой аватар хотим увидеть: с начальной буквой никнейма пользователя или иконкой человечка. Наконец, собираем html-тег и отправляем его вызывающей функции.

Теперь добавим немного стилей для наших аватаров (я добавил их в конец файла ..\templates\default\css\theme-gui.css):
Код CSS:
  1. .avatar-colorbox {
  2. margin: 0;
  3. padding: 0;
  4. background: no-repeat center;
  5. background-size: 1em;
  6. }
  7.  
  8. .avatar-colorbox.letter {
  9. position: relative;
  10. font-family: "Helvetica Neue",Helvetica,Arial,sans-serif!important;
  11. font-style: normal;
  12. font-weight: 300;
  13. text-align: center;
  14. text-transform: uppercase;
  15. -webkit-font-smoothing: antialiased;
  16. -moz-osx-font-smoothing: grayscale;
  17. }
  18.  
  19. .avatar-colorbox.letter:before {
  20. content: attr(data-letter);
  21. display: inline-block;
  22. position: absolute;
  23. left: 0;
  24. right: 0;
  25. margin-left: auto;
  26. margin-right: auto;
  27. }
  28.  
  29. .avatar-colorbox.user-white {
  30. background-image: url('data:image/svg+xml;utf8,<svg fill="#ffffff" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
  31. }
  32. .avatar-colorbox.user-black {
  33. background-image: url('data:image/svg+xml;utf8,<svg fill="#222222" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
  34. }
Всё! Запускаем сайт и смотрим изменения smile В стандартном исполнении аватарки можно увидеть на главной странице сайта в виджетах "Новые пользователи", "Активность" и "Комментарии", в списке пользователей и на странице профиля пользователя, а также во многих других местах =)
Пару скриншотов
Или можно глянуть на демо-сайте

Стоит отметить что проблема дефолтных аватарок существует достаточно давно и многие предлагают свои варианты ее решения:
https://randomuser.me/ - сервис предлагает свой API для генерации случайных данных пользователя, в том числе и аватаров;
http://8biticon.com/ - а здесь можно генерить случайные аватарки пользователей и использовать их в замен дефолтных. ( https://habrahabr.ru/post/163181/ - пост с описанием сервиса);
github.com/tequilarapido/letter-avatar - авторы предоставляют небольшую php-библиотеку для создания цветных буквенных-аватарок и сохранения их в картинки формата jpg и png;
MonsterID - библиотека для генерации уникальных монстроподобных изображений ( её плагин для WP);
Wavatars - еще одна php-библиотека;
http://scott.sherrillmix.com/blog/blogger/wp_identicon/ - WP-плагин для создания геометрических аватарок;
http://uifaces.com/ - множество аватарок для мокапов сайтов
Виджет "Карточка пользователя" | Предпросмотр для InstantCMS 2
Комментарии (31)
WebMan 20 марта 2016 в 23:38 +4
Интересное решение. Может быть даже не "Просто смеха ради", а вполне серьёзное, хотя и простое решение.

В никах часто бывает не одно слово, а несколько. Мне кажется, можно попробовать подставлять в аватар не по одной букве, а первые буквы из первых двух-трёх слов. Может быть через точку, чтобы не выглядело одним словом. Также можно добавлять точку после второй буквы в варианте с одной-двумя буквами в аватарке, если слов в нике больше двух. Тогда аватарки станут ещё более уникальными и наглядными.

Например, у "Олег Васильевич я" на аве будет "О.В" или "О.В." или "О.В.я", а у "Олег с клещами" - "О.с.к" или "О.с." или "О.с". (Простите, ребята, ничего личного. Вы просто оказались подходящими для примера). joke

Правда, при трёх буквах иногда могут получаться неприличные слова. Но это уже будут издержки производства. Зато в таком случае человек быстрее поменяет свою аву на что-то более подходящее ему. laugh
Val 21 марта 2016 в 00:08 +3
Ну выводить вместо одной буквы 2 или 3 проблем вообще нет =), нужно лишь подставить желаемые вариации и сочетания в атрибут data-letter.
WebMan 21 марта 2016 в 00:22 0
А как сделать автоматический подбор размера букв? Чтобы для одной буквы был такой, как есть, а для двух-трёх - меньше.
Val 21 марта 2016 в 00:31 +2
Ну в данном случае я пошел простым путем -> в стилях поставил text-transform: uppercase;, но никто же не мешает навести форматирование в PHP, записать данные в data-letter и просто отобразить их без лишних трансформаций))
Код PHP:
  1. $words = str_word_count($alt, 1);
  2. if (count($words)>1) {
  3. $nick = '';
  4. foreach ($words as $word) {
  5. $nick += mb_substr($word, 0, 1);
  6. }
  7. }
  8. ...
  9. 'data-letter="'.$nick.'"
Val 21 марта 2016 в 00:34 +1
Это не готовый код, а лишь направление мыслей)))
WebMan 21 марта 2016 в 01:33 +1
Спасибо, Val, когда доберусь до этой темы, поэкспериментирую.
Андрей 21 марта 2016 в 00:29 -1
Креативно smile
Dost 21 марта 2016 в 00:22 +1
Классно, мне нравится. Провал поставить, у меня цветные квадраты без букв получилось. Кто будет ставить отпишите плиз, у вас нормально стало. Автор молодец!
Val 21 марта 2016 в 00:35 +1
Ставили на чистую систему? На локалке или на хостинге - есть возможность глянуть что да как?
Iceman 22 марта 2016 в 16:52 0
Есть такая проблема, судя по всему она возникает из-за того, что у изображения банально отсутствует атрибут alt. в функции он есть, но почему-то не подтягивается и остается пустым, а следовательно не работает и показ символа и определение цвета.
Iceman 22 марта 2016 в 17:38 0
В моем случае проблема была в том, что в виджет списка пользователей действительно не подтягивался alt.
заменил
Код PHP:
  1. html_avatar_image($profile['avatar'], 'small');
на
Код PHP:
  1. html_avatar_image($profile['avatar'], 'small', $profile['nickname']);
и все стало как надо.
Val 22 марта 2016 в 18:54 +3
Странно(( на случай отсутствия $alt стоят условия по которым также генерится цвет фона, а на выходе вместо буквы показывается иконка пользователя:
Iceman 22 марта 2016 в 18:59 0
Видимо это условие не срабатывало, поскольку собственно "alt" там выводился даже без переменной с содержимым, но при этом он был пустой, от него только отрезалось ="".
Val 22 марта 2016 в 19:17 +1
по коду alt и должен выводиться в любом случае: return '<img src="'.$src.'" '.$size.' alt="'.htmlspecialchars($alt).'" />';

Вы можете мне скинуть какой тег на выходе у вас получается при отсутствии $alt?
Должно быть что-то похожее на это:
Код HTML:
  1. <div class="avatar-colorbox user-white" title="" style="background-color: rgba(44, 102, 170, .7); color: white; width: 64px; height: 64px; line-height: 64px;font-size: 40px" data-letter=""></div>
Iceman 22 марта 2016 в 20:45 +1
На удивление: убрал сейчас для проверки переменную с alt и отобразились силуэты, так что повторить проблему не вышло, хотя вроде больше ничего не менял в этой стороне. Тег соответственно вышел как Вы и написали.
lezginka.ru 21 марта 2016 в 00:28 +2
+++
жаль что без вмешательства в ядро не получается...
Val 21 марта 2016 в 00:37 +7
Первоначально была (а может и есть)) ) идея сделать отдельным дополнением. Вероятно по пути перехвата процесса регистрации и генерации картинки для нового пользователя.
Данный вариант делался любопытства ради.
WebMan 21 марта 2016 в 01:34 +3
Это отличная идея! joke
Datiks 21 марта 2016 в 07:33 +4
будем очень ждать отдельным дополнением ++++
F_a_R_i_D 21 марта 2016 в 00:44 0
Отображает буквы только на кирилице и латинице?
Val 21 марта 2016 в 00:46 +1
Восточные языки не проверял, но должно показывать все символы, которые поддерживаются utf-8
Олег Васильевич я 21 марта 2016 в 01:05 +1
Прикольненько.
Может кому-то пригодится: вариант для тех, кто таки боится хаков.
Андрей 21 марта 2016 в 23:36 -2
есть еще прикольный вариант Загрузка аватара при регистрации от камрада Evanescence
Jestik 21 марта 2016 в 10:51 +3
А может что бы не боятся сразу в коробку?) zst
Val 21 марта 2016 в 15:51 +3
Это не ко мне вопрос)) Но для коробки код надо творчески переработать
Fuze 21 марта 2016 в 23:52 +5
Универсальности ради надо:

1. сделать опцию в компоненте авторизация регистрация "формировать аватары автоматически"
2. если опция включена, то формировать готовый аватар (картинку) по указанному алгоритму, думаю вполне реально
3. все удобно, гибко и универсально.

имхо)
WebMan 5 апреля 2016 в 01:34 0
Я тоже сразу подумал про генерацию и сохранение картинок для аватара. Но простая логика показывает, что если хранить в профиле массив с несколькими параметрами (цветами и размерами букв), а потом подставлять их в html-шаблон дефолтной аватарки, то работать будет быстрее, чем запросы к серверу за картинками, даже с учётом их кэширования в браузере. Да и шаблон таких аватарок всегда можно легко поменять при необходимости.
Pocus 7 февраля 2017 в 18:04 +2
Хех :)
Когда оно в офф. версии появилось? Наверное с 2.6?
Я пару месяцев пользовался этим хаком и радовался.
А после выхода 2.7 полез восстанавливать и... заметил переменную $is_html_empty_avatar
Вот только не нашел где её в админке включить.
Val 7 февраля 2017 в 18:22 +1
Уверяю вас этот хак я выложил раньше чем функционал появился в коробке)) Я ничего не копипастил.
Pocus 7 февраля 2017 в 18:26 +1
Ясно дело, я ж не в упрёк вам. Я про собственную невнимательность.
Кстати, спасибо, и эта и другие ваши работы очень радуют.
WebMan 7 февраля 2017 в 18:55 0
Такой опции в Админке нет.