VkOMG. Разработка очередного никому не нужного сервиса

image
Меня всегда интересовали разнообразные «плюшки» для социальных сетей с точки зрения маркетинга. А именно то, как быстро войдет этот очередной бред в массовое пользование и то, сколько сил будет затрачено на достижение данного эффекта. Ниже я расскажу результат того, что я узнал на примере нашей последней работы vkomg.com

Уже несколько лет работаю фрилансом в американской компании, ориентирующейся на веб-разработках. Работа вполне стандартная для среднестатистической фриланс конторки: доработка кривого кода, доставшегося по наследству от прошлых разработчиков проекта, плюшки и плагины для CMS, иногда неплохие масштабные стартапы. Все это, конечно, хорошо. Но давно известно, что мелкие, на первый взгляд никому не нужные вещи приносят отдачи намного больше. Поэтому, в один прекрасный день, увидев на фейсбуке новые профили, мы разработали сервис по созданию очередного никому не нужного забавного аватарного эффекта.
image
Пару дней назад, увидев, что на родном ВКонтакте появился точно такой же блок с фотографиями около главного фото, мы загорелись идеей переделать имеющийся фейсбуковский проект под вконтакте в первый же день.
Добившись довольно интересных результатов в США, не выложив на продвижение никаких средств со своего кармана, начав всего с одной ссылки в собственном профиле, стало очень интересно какие результаты покажет Россия.
Конкретные цифры, история, результаты и куски кода в продолжении поста.

UPD: Хабраэффект в действии. Ругаемся с техподдержкой за несоответсвие обещаной максимальной нагрузки действительности.
UPD2: Хостер исправился. Сервер в полном здравии.



С чего начать?


В качестве языка для разработки первого варианта для фейсбука был выбран PHP. Уже имелся багаж готовых кусков кода, а запуск ранее других аналогов был одним из главных требований. Именно это стало главной причиной выбора этого языка.
Главными возможностями и требованиями были:
  • Ajax загрузка файла фотографии с индикатором прогресса;
  • Предзагрузка элементов интерфейса для большего удобства пользователей;
  • Легкая возможность позиционировать маску на фотографии;
  • Предпросмотр;
  • Возможность скачать готовые фотографии одним архивом;
  • Возможность отражения фотографии по горизонтали без перезагрузки страницы;
  • Отсутствие каких либо материальных вложений на рекламу.

Маска и формат файла


Сердцем, конечно же, является далеко не скрипт кропа фотографий, а JS маска, позволяющая пользователю наглядно выбрать именно тот кусок картинки, который будет использоваться в качестве будущего юзерпика.
image

Разумеется, как и любые другие ленивые разработчики, мы кинулись искать готовые скрипты, которые можно было бы доработать именно до того функционала, который нам нужен. После просмотра нескольких десятков страниц, выданных различными поисковиками, стало ясно, что придется писать с нуля свою собственную маску. Все готовые решения были либо очень кривыми, либо требовали не меньше времени на их доработку, чем написание собственного скрипта с нуля. Все делалось в сумасшедшей спешке, поэтому про оформление маски в виде нормального, адекватного плагина для jQuery не могло идти и речи. После того как основной функционал будет доделан, я планирую переписать скрипт с нуля в виде нормального плагина под jQuery с возможностью легкого использования в последующих продуктах.

Следующей интересной, но довольно простой в решении задачей было отражение фотографии по горизонтали. Требовалось выполнить это без перезагрузки страницы и, без какой либо дополнительной предварительной обработки фото на сервере и с поддержкой всех браузеров. Решение пришло довольно быстро. Отражение делается простым добавлением этого css класса к контейнеру фотографии.

.flip-x {
-moz-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
-o-transform: scaleX(-1); /* Поддержка Opera */
transform: scaleX(-1);
filter: fliph; /* Поддержка IE */
}


На практике я легко убедился, что данный метод работает отлично во всех браузерах, включая Opera и IE. Тем не менее, этот метод имеет один главный, но очень несущественный недостаток. Если применить этот класс к тегу img, то при попытке сохранить браузером картинку, сохранится неотраженный оригинал.
Все серверные преобразования изображения выполнены при помощи ImageMagick. Отражение по горизонтали, например, выполняется следующим образом:

system("convert -flop /path/to/file/original.jpg /path/to/file/tmp.jpg");

Также, благодаря ImageMagick, легко добиться поддержки огромного числа форматов. Не только стандартных jpg, gif и png. Так как в качестве результата пользователь получает jpg, имеет смысл воспользоваться конвертером еще на этапе загрузки фото.

system("convert /path/to/file/original.ext /path/to/file/out.jpg",$result);
if ($result===0) {
// Конвертация завершена успешно.
}


Загрузчик


Процесс загрузки фотографии — это также важный момент, которому стоит уделить достаточно внимания. Так как все создавалось в ужасной спешке, первая версия загрузчика представляла собой элементарную enctype=«multipart/form-data» форму, содержащую два элемента: поле выбора файла и кнопку отправки. Уже в первый день начали поступать сообщения от пользователей с жалобами на невозможность загрузить файл. После анализа сообщений выяснилось, что их можно разделить на 2 категории:
  • «Я нажимаю загрузить файл, а оно мне пишет, что сначала надо выбрать файл, но как я его выберу, если я даже не могу ничего загрузить?» (Да-да… полнейший бред, но не стоит недооценивать глупость пользователей, эти люди нажимали кнопку отправки, не выбрав файл в первом поле. Они считали, что сначала надо нажать кнопку «Загрузить фотографию», что приводило к неминуемой ошибке, которую они не были в силах осмыслить)
  • «Я выбираю файл, нажимаю „Загрузить фотографию“ и все зависает. Почему?». (Пользователь пытается загрузить слишком большой по размеру файл, либо скорость его подключения достаточно невысока)

Решение данной проблемы очевидно. То, что отсутствие нормального загрузчика подорвет юзабилити, также было очевидно изначально, но спешка, как всегда, все портит. Маловажные, на первый взгляд, моменты вызовут множество проблем в будущем.
Для исправления ситуации был использован плагин для jQuery под названием Uploadify.

image

Плагин позволяет легко реализовать загрузку файла с индикатором процесса загрузки. Метод довольно стандартен: использование элемента на flash для асинхронной передачи данных. Главным плюсом этого плагина является легкость в настройке (огромное число параметров и коллбеков) и возможность настройки внешнего вида при помощи CSS

image

Следует также предусмотреть вариант использования для ненавистников флеша. (использование все той же стандартной формы для пользователей без Flash). Первый же запрос к поисковику выдает интересные результат: библиотеку для определения версии Flash со всевозможными немыслимыми методами.

HTML содержит сразу две формы: обычную multipart и форму с флеш элементами. Флеш форма по умолчанию скрыта от глаз пользователя.

if(FlashDetect.installed) {
$('#plainform').hide();
$('#ajaxform').show();
}


Таким образом, обычная форма легко подменяется Uploadify формой при условии наличия у конечного пользователя Flash.

Предпросмотр


image

Предпросмотр — очередная вещь, которая облегчает жизнь простому пользователю. Идея проста: сгенерировать картинки, позиционировать картинки при помощи CSS на универсальной заготовке для фона. Углубляться в детали не буду. Единственное о чем здесь стоит рассказать — это popup скрипт. Совсем недавно я столкнулся с продуктом под названием TopUp, который показал себя довольно убедительно и за долгую историю использования не вызвал ни одной проблемы.

Предзагрузка


Чтобы улучшить user experience на странице с формой, было принято решение осуществить предзагрузку всех картинок, использующихся на странице с маской (например, все медиа ресурсы TopUp, чтобы всплывающее окно появлялось мгновенно, без загрузки на глазах у пользователя). Причем подгрузка этих элементов не должна влиять на скорость рендера страницы с загрузчиком. Первое, что пришло на ум — подгрузка картинок при помощи JS:

function preload(sources)
{
var images = [];
for (i = 0, length = sources.length; i < length; ++i) {
images[i] = new Image();
images[i].src = sources[i];
}
}
$(window).load(function() {
$("#preload").attr('src','preload-step2.php');
preload([
"res/images/preview.png",
"res/images/top_up/dashboard/sprite.png",
"res/images/top_up/dashboard/close_link.png",
"res/images/top_up/dashboard/bottom_left.png",
"res/images/top_up/dashboard/top_right.png",
"res/images/top_up/dashboard/bottom_right.png",
..........................
..........................
"res/images/btn-flip.gif"]
)
});


Водяной знак


Далее встал вопрос о создании полупрозрачного водяного знака. Вспомнив, сколько манипуляций требуется для реализации водяного знака при помощи GD, я решил привлечь для этой цели все тот же ImageMagick.

system("composite -gravity south -alpha on /path/to/file/watermark.png /path/to/file/profile.jpg /path/to/file/profile.jpg');

image

Удаление устаревших файлов


Так как пользователь будет забирать архив с результатом не сразу, а спустя какое-то время, необходимо предусмотреть сценарий удаления устаревших временных файлов. Для каждого пользователя создается временная директория, содержащая все файлы данной сессии. Задача: ежедневно удалять все директории, созданные более 24 часов назад.

#!/bin/bash
for i in `find /path/to/dirs/ -maxdepth 1 -type d -mtime +1 -print`; do rm -rf $i; done


Цифры


А теперь, самое интересное — результат.
На раскрутку фейсбуковского оригинала не было затрачено никаких усилий и средств. Все, что мы сделали — это изменили свои собственные юзерпики и опубликовали url в ленте новостей на обозрение своим друзьям. Тем не менее, фейсбуковский оригинал вчера достиг посещаемости в 4000 уникальных посетителей в день (очень нескромный результат, для проекта возрастом менее месяца).

image

VkOMG начинался аналогично. Смена собственного аватара и публикация статуса с URL + одна таргет реклама с бюджетом 25 рублей, которая принесла всего 50 реферралов на официальную страницу ВКонтакте (именно на страницу ВК, а не на внешний url).
Тем не менее, вот наши скромные результаты за 4 дня работы:
  • 1й день — 24 уникальных посетителя, 56 аватар создано.
  • 2й день — 246 пользователей, 542 аватары создано.
  • 3й день — 440 уникальных пользователей, 1408 аватар создано
  • 4й день — 890 пользователей — 2486 аватар создано.
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 76

    +6
    Очередная реализация комбо. Теперь для контакта. Мне нравится.
      0
      Для Вконтакте стали делать фичи, ура!
        0
        Уже давно. Тысячи их!
          +1
          Вы что?
          Какие тысячи?

          Пару десятков с однообразным функционалом, разве что.
            +3
            Ну, совсем немного преувеличил.
        • UFO just landed and posted this here
        –6
        А где ссылка на сам сайт?
        0
          0
          Вот только тяжело двигать рамку при редактировании.
            0
            offtopic
            Где-то я эту картинку уже видел…
            Часом не Magma Chamber? :)
              0
              Она самая
              0
              Сайт уже почти слёг
                0
                Тихооонько ползет :)
                  +4
                  Облачный сервер от Rackspace… Рекомендую) уже долбаем техподдержку за невыполнение заявленных характеристик по нагрузке
                    +1
                    Отбой тревоги. Техподдержка оперативно все решила
                      0
                      Очень интересно, а что именно не так пошло у Rackspace? У вас Cloud Servers или Cloud Sites?
                        0
                        Cloud Servers конечно же. Без понятия что у них не пошло. Конфиг апача у нас ровный. Оперативки свободной полно. Процессора полно. Отзвонили в поддержку — через полчаса все заработало.
                          0
                          !(ровный) == бугристый?

                          очень верная характеристика для конфига ;)
                    –2
                    Похоже, пока ваш сервис готов выдержать пользователей с рекламы, но хабраэффект выдержать не может :)
                      0
                      Неважно, что «сервис никому не нужен». Важен опыт, полученный при реализации.

                      Кстати, это можно монетизировать контекстной рекламой. А еще можно сделать Iframe-приложение, а там какие-нибудь плюшки за голоса. Ну а голоса можно и на хлеб намазать. Удачи.
                        +2
                        Следующим очевидным шагом должно быть прикручивание API социальных сетей к вашему проекту, чтобы у пользователей не было необходимости скачивать и загружать фотографии.

                        Я, кстати, когда-то тоже писал похожее приложение для ВК — только оно создавало аналогичный эффект в отдельно взятом фотоальбоме, а не на странице профиля.
                          0
                          «Время ожидания ответа от сервера vkomg.com истекло.»
                            0
                            ой, уже выше написали, что «хабраэффект выдержать не может»
                            0
                            Дайте ссылку на эту штуку в фэйсбуке?
                              +1
                                0
                                И этот положили :(
                                  0
                                  Тот же сервер. Жду ответа техподдержки
                                    0
                                    Советую сменить хостинг. Облака конечно хорошо, но…
                                      0
                                      Уже все работает
                                    +1
                                    Неудивительно, они на одном сервере :)
                                +1
                                Можно человеку не знакомому с фейсбуком объяснить что вы сделали ??
                                  0
                                  Да. Посмотрите скриншоты в статье
                                  +7
                                  Веселый сервис. скоро вся школа Фконтакта о нём узнает и поднимет вам посещаемость :)
                                    +3
                                    Ну чтож, это прекрасный способ для понта у большей части айдитории Вк.
                                      +6
                                      А мне понравилось.
                                      0
                                      не выдерживает:

                                      Warning: Division by zero in /var/www/vkomg.com/htdocs/libs/images.php on line 27

                                      Warning: Cannot modify header information — headers already sent by (output started at /var/www/vkomg.com/htdocs/upload.php:24) in /var/www/vkomg.com/htdocs/upload.php on line 46
                                        +3
                                        Не выдерживает и делит на ноль?
                                        0
                                        А почему jpg а не png? Как обрабатывается прозрачность у gif и png?
                                          0
                                          Половина пользователей этого проекта не знают что такое PNG. JPG куда привычнее простой домохозяйке.
                                          Полупрозрачность используется только при добавлении водяного знака. Делается одной командой ImageMagick. Про это детально описано
                                            0
                                            Не всё равно ли пользователям, jpg или png? Главное, что открывается.
                                              0
                                              Я про то, что исходное изображение может содержать прозрачные участки. GD как я знаю такие участки заливает чёрным. Вот я и спрашиваю — как это получается у ImageMagick — сохраняется альфа-канал у отрезанного изображения?
                                                –1
                                                Да. Альфа-канал сахраняется.
                                            +1
                                            Прекрасно!
                                              0
                                              Как уже написали выше, скоро весь «контакт» узнает о вашем сервисе, и тогда уж никакие хабраэффекты не пойдут в сравнение :)
                                              Если раньше «аватар by avatar.ru» был в моде, то будьте готовы к тому, что скоро ваш замечательный сервис войдет в обиход пользователей социальной сети «Вконтакте»
                                              Начало пути к славе :)
                                              Хотя я думаю, что вы равнодушны к славе.
                                              Удачи, ребята. Хороший проект, пользовался вашим сервисом для facebook, там про него уже весь мир знает ;)
                                                +1
                                                Вообще, супер. Молодцы!

                                                Надо же. А я-то, темнота, просто придумал свой велосипед, и сделал его. Раскромсал фотку, рассовал на фейсбуке, снял скриншот и радостно его опубликовал в ЖЖ, извините. Велосипед мой, т.е. мопед мой.

                                                Использованные программы: MS Paint, calc.
                                                Дата задумки и реализации: 13 декабря 2010.
                                                Как правильно подтвердить дату, не знаю. Так что, извините за ссылки:
                                                Пикаса — picasaweb.google.com/Paata.Dzhikidze/Screenshots#5550073390068539650
                                                ЖЖ — dzhikidze.livejournal.com/1199.html
                                                Собственно, зарегистрированные на фейсбуке могут посмотреть профайл — facebook.com/jikidze

                                                Ребята, вы молодцы. Целый веб-сервис. Аплодирую.

                                                Пара слов про контент, а не про сервис: сопоставление моего варианта портретного дизайна с человеческим лицом с вашим портретным вариантом дизайна. Возможно, будет полезно для клиентов сервиса.
                                                • Самый крупный фрагмент (титульное фото) у меня взят чуть больше 55% от прямоугольника, в который можно вписать лицо. Квота 55% — как при восстановлении бумажных денег в банке. У вас — ухо. Не важно чье. Не всякое ухо подходит для быть титульной фоткой, и не по всякому уху можно человека идентифицировать.
                                                • Мой вариант позволяет посмотреть в лицо, точнее в изображение лица. У вас в сэмпле юноша как бы выглядывает из амбразуры или из паранджи.
                                                  0
                                                  Вдогонку: даешь контрольный пакет лица в каждую титульную фотку! Если, конечно, надо.
                                                    0
                                                    Ага, а я, значит, раньше придумал вручную порезать фотографию: 10-12-2010. Можете посмотреть в профиле: www.facebook.com/ury.smirnov, там даты фотографий указаны :)

                                                    Но на самом деле, любая хорошая идея приходит одновременно в разные головы. :)

                                                    А разработчикам сервиса — спасибо. Cам искал сервис, позволяющий быстро нарезать любую фотографию на нужное количество фрагментов.
                                                  0
                                                  Затестила. Сделала себе модную аватарку. \m/
                                                  Звуки на сайте пугают и печалят.
                                                    +1
                                                    Вы мой прямой конкурент :)

                                                    Запустил очень похожий проект, только в виде приложения буквально на следующий день после появления фичи с фотографиями:
                                                    vkontakte.ru/app2147544

                                                    С аватарами конечно круто, но высота на которой находится блок с фотками по моим наблюдениям меняется в очень широком диапазоне и какую-то универсальную схему я пока что не придумал.
                                                      0
                                                      верно, даже у автора топика проблемы с этим возникли:
                                                        –1
                                                        Прежде чем писать коментарий стоило бы разобраться. Если пользовательне является вашим другом, то в информации на одну строчку меньше. Отсюда и проблема. Добавьте в друзья и все будет ровно. Тут уж ничего с этим не поделать.
                                                          0
                                                          Вы уверенны, что именно так? По сути высота меняется из-за расположения ссылки «показать подробную информацию», я проверил у своих друзей, и у некоторых эта ссылка рядом с именем, а у некоторых над блоком с фотографиями, без какой-то явной зависимости.
                                                            0
                                                            Абсолютно уверен. А для тех, у кого просто не заполнена информация, в приложении есть настройка количества строк информации с поясняющей всплывающей подсказкой:

                                                              0
                                                              Если Вы не против, то давайте проведем эксперимент. Сейчас, когда я захожу к Вам на страницу у меня эффект, как на скриншоте RenegadeMS. Я только что отправил Вам запрос в дружбы (Константин Соколов), если Вам не трудно, добавьте меня и я напишу здесь результат.
                                                                0
                                                                Получилось. После добавления в друзья, ссылка «показать подробную информацию» переехала из правого верхнего угла (как на скриношоте RenegadeMS) к блоку с фотографиями (как на Вашем скриншоте). Правда я всё равно не понимаю закономерности, у некоторых моих друзей ссылка «показать подробную информацию» находится в правом верхнем углу, не смотря на то что мы оба друг у друга в друзьях.
                                                                  0
                                                                  Это зависит от галки «Показывать полную информацию» в настройках. Если ее поставить, а затем скрыть полную информацию о пользователе, то ссылка будет отображаться в верхнем правом углу
                                                      0
                                                      Классно придумано!

                                                      Маленькое замечание: при наведении мышью на шаблон — появляется курсор, предполагающий что шаблон можно утащить. Но, так как он на всю картинку, утащить его нельзя. Сделайте его немного меньше картинки и будет понятно.
                                                        0
                                                        Мне уже хочется ЧАСЫ. вот вместо этих фоток)
                                                          0
                                                          Довольно таки, неплохо
                                                            0
                                                            Если ник в две строчки, то не подходит :(
                                                              0
                                                              Сегодня добавим поддержку
                                                                0
                                                                z700 на картинке контакта :D
                                                                  0
                                                                  Блин, предлагать скачивать архив это совсем не кошерно… Использовали бы API Описание API
                                                                    0
                                                                    Заливка фотографий через API доступна только desktop и iframe приложениям ВКонтакте, но не сторонним сайтам. Разработка такого приложения уже почти завершена
                                                                    0
                                                                    И, кстати, есть же расширение ru.php.net/manual/en/class.imagick.php нафига exec() делать?
                                                                      +1
                                                                      Что вы имеете против system() если ее вызов заранее безопасен и в нее не передаются пользовательские параметры? Или боитесь коммандной строки?

                                                                      Разумеется, я не спорю и считаю это делом вкуса, но лично для меня 1 вызов консольной команды гораздо проще и нагляднее многострочной пляски с этим уродским классом для работы с IM.

                                                                      Оба подхода имеют права на жизнь
                                                                        0
                                                                        Ну, есть некоторый оверхед на запуск процесса convert etc, опять же если нужно несколько операций проделать в ывременные файлы используете если я правильно понял.

                                                                        Опять же, некоторые предпочитают exec* функции запрещать вообще для защиты от веб-шеллов на случай взлома.
                                                                        0
                                                                        У нас например для одной штуки написана обертка, которая формирует запрос к шеллу для imagick, такой язык запросов своеобразный, вполне себе годная и удобная вещь.
                                                                        0
                                                                        Понравилось, но я бы всё таки убрал в конечном аватаре ссылку на ваш сайт. Знаю, что вы ответите, но я лишь высказываю своё мнение, как бы я сделал.
                                                                          0
                                                                          а копеечка-то откуда пойдёт? вся фееричность со временем пропадёт. или скажем её почти не будет. но монетки-то где?
                                                                            0
                                                                            Нигде) Данный проект был создан чисто из интереса. Максимум, что будет — контекстная реклама. Деньги будут с других проектов
                                                                          –1
                                                                          Сделайте то же самое для групп. Пример: vkontakte.ru/club17189573
                                                                          ЗЫ: Это не реклама группы, просто то, что мне друг показал, как пример. За что купил, за то продал.
                                                                            0
                                                                            Спасибо за оба проекта! Достойные +100 у поста теперь

                                                                            Only users with full accounts can post comments. Log in, please.