Если вы активно пользуетесь порталом Битрикс24, наверняка вы видели на экране анимированного мультяшного персонажа Клаудмена. Он используется в аватаре чата технической поддержки, во встроенной справке, а так же появляется на экране, чтобы указать вам на новую кнопочку или рассказать о каком-нибудь мероприятии.

анимированный клаудмен

Клаудмен из Битрикс24

Ситуация, когда необходимо указать пользователю на новый элемент интерфейса или привлечь его внимание к акции, может возникнуть и в вашем приложении для Битрикс24. Например, мы захотели узнать у пользователей нашего приложения "Стикеры" какие новые функции они хотели бы увидеть в следующих релизах. Для этого мы добавили в приложение ссылку, ведущую на форму опроса, и Клаудмена, который появляется на несколько секунд и указывает на эту ссылку. Почему бы и вам не воспользоваться методом разработчиков и не призвать на помощь Клаудмена?


Можно дать задачу художнику-аниматору, чтобы он нарисовал раскадровку сцены и упаковал ее в .GIF-файл. Но, что если у нас нет художника? Или хочется все сделать быстро своими силами?


В этой статье я расскажу, как быстро создавать простейшие анимации Клаудмена при разработке приложений для Битрикс24 с помощью JavaScript-библиотеки Span.SVG.


Для работы нам потребуются инструменты:

  • Сервис vectorizer.io или приложение Vector Magic для векторизации растрового изображения
  • Corel Draw или другой редактор, умеющий редактировать SVG вектор
  • Ваша любимая IDE, в которой вы пишете приложение


Для начала скачаем из брендбука для партнеров изображение Клаудмена. В архиве находятся изображения в формате .PNG, нам же нужны векторные изображения в формате .SVG.


Для преобразования растра в вектор я использую приложение Vector Magic – оно очень простое и интуитивное. Достаточно перетащить файл в растровом формате в область приложения и нажать кнопку автоматической векторизации. На выходе вы получите изображение в векторном формате.


векторизация

Приложение Vector Magic

Теперь нам нужно немного отредактировать полученного Клаудмена. Я хочу, чтобы он приветственно махал рукой моим пользователям. Открываем наш векторный файл, полученный на предыдущем шаге, в CorelDraw и редактируем его. Удаляем табличку из руки, дорисовываем недостающие точки. В итоге мы должны получить картинку, отображающую исходное состояние нашей будущей анимации.


корел

Первая позиция Клаудмена в Corel Draw

Теперь нам нужно сохранить получившегося Клаудмена в формате SVG. В Corel Draw это делается командой "Файл -> Экспорт".


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


корел

Вторая позиция Клаудмена в Corel Draw

Так же сохраняем полученное изображение в .SVG. В итоге у нас получится два SVG-файла - по одному на каждое состояние персонажа. Теперь давайте встроим Клаудмена в наше приложение.


Менять состояние нашего Клаудмена мы будем с помощью библиотеки Snap.svg – скачать ее можно тут: http://snapsvg.io. Библиотека позволяет манипулировать путями, заданными в формате SVG, с помощью простого и понятного интерфейса.


Подключаем библиотеку на нашу страницу:


<script type="text/javascript" src="js/snap.svg-min.js"></script>

Добавляем элемент <svg> в место, где хотим отобразить Клаудмена:


<svg id="cloudman" class="cloudman-svg" viewBox="0 0 156 201" width="156px" height="201px"></svg>

Открываем наши SVG-файлы в текстовом редакторе. В каждом из файлов находим строки:


<path class="fil0" d="M74 7c15,-10 36,-9 51,1 10,7 17,19 19,32 2,8 -1,17 -1,25 -1,16 -1,33 1,49 0,3 2,5 4,7 3,5 5,9 7,14 2,8 1,16 0,23 -1,3 -1,7 -4,7 -3,2 -7,-2 -7,-5 2,-9 4,-18 0,-27 -3,13 -11,24 -23,30 2,5 4,11 4,16 0,4 -1,8 -2,12 3,0 7,-1 9,2 2,2 1,7 -3,7 -4,1 -7,1 -11,0 -3,0 -6,-4 -6,-7 1,-5 3,-9 3,-14 0,-4 -1,-8 -3,-12 -9,3 -20,2 -29,0 -2,4 -3,8 -4,12 1,5 3,9 3,14 1,3 -2,7 -6,7 -3,1 -7,1 -11,0 -3,0 -4,-5 -2,-7 2,-3 6,-2 9,-2 -1,-4 -3,-8 -3,-12 1,-6 3,-11 5,-17 -12,-8 -20,-21 -21,-35 -8,6 -16,12 -26,13 -6,1 -9,0 -13,-5 -2,-2 -7,-8 -9,-13 -3,-6 -5,-14 -5,-15 0,-4 1,-5 3,-5 2,-1 4,-1 6,2 3,4 9,29 18,26 10,-2 17,-9 24,-15 -2,-25 -1,-50 2,-74 1,-14 9,-26 21,-34z"/>
<path class="fil1" d="M71 68c-1,-4 1,-9 5,-9 5,-1 9,4 8,8 -4,-1 -9,0 -13,1z"/>
<path class="fil1" d="M109 68c-1,-5 2,-9 7,-9 4,0 7,4 6,9 -4,-2 -8,-2 -13,0z"/>
<path class="fil2" d="M81 81c7,-2 15,-1 22,-1 3,-1 8,1 6,5 -6,10 -23,10 -29,0 -2,-1 -1,-3 1,-4z"/>

Эти строки описывают наши контуры. Всего их четыре – линия туловища, линия рта, и по контуру для каждого глаза. Теперь напишем скрипт, который хранит контуры и с помощью библиотеки span.svg манипулирует ими:


<script type="text/javascript">

    // Укажем библиотеке snap.svg место, в котором мы будем рисовать наше изображение;
    var s = Snap("#cloudman");

    // Контур туловища, в который входят и руки
    var cloudmanStartPath = "M74 7c15,-10 36,-9 51,1 10,7 17,19 19,32 2,8 -1,17 -1,25 -1,16 -1,33 1,49 0,3 2,5 4,7 3,5 5,9 7,14 2,8 1,16 0,23 -1,3 -1,7 -4,7 -3,2 -7,-2 -7,-5 2,-9 4,-18 0,-27 -3,13 -11,24 -23,30 2,5 4,11 4,16 0,4 -1,8 -2,12 3,0 7,-1 9,2 2,2 1,7 -3,7 -4,1 -7,1 -11,0 -3,0 -6,-4 -6,-7 1,-5 3,-9 3,-14 0,-4 -1,-8 -3,-12 -9,3 -20,2 -29,0 -2,4 -3,8 -4,12 1,5 3,9 3,14 1,3 -2,7 -6,7 -3,1 -7,1 -11,0 -3,0 -4,-5 -2,-7 2,-3 6,-2 9,-2 -1,-4 -3,-8 -3,-12 1,-6 3,-11 5,-17 -12,-8 -20,-21 -21,-35 -8,6 -16,12 -26,13 -6,1 -9,0 -13,-5 -2,-2 -7,-8 -9,-13 -3,-6 -5,-14 -5,-15 0,-4 1,-5 3,-5 2,-1 4,-1 6,2 3,4 9,29 18,26 10,-2 17,-9 24,-15 -2,-25 -1,-50 2,-74 1,-14 9,-26 21,-34z";

    // Отрисуем первое состояние, используя начальный контур cloudmanStartPath
    var cloudman = s.path(cloudmanStartPath).attr({
        fill: "#2EC6F7" //цвет заполнения контура
    });

    // Нарисуем рот Клаудмена
    var mouth = s.path("M81 81c7,-2 15,-1 22,-1 3,-1 8,1 6,5 -6,10 -23,10 -29,0 -2,-1 -1,-3 1,-4z").attr({
        fill: "#FFFFFF" //цвет заполнения контура
    });

    // Нарисуем глаза Клаудмена
    var eye1 = s.path("M71 68c-1,-4 1,-9 5,-9 5,-1 9,4 8,8 -4,-1 -9,0 -13,1z").attr({
        fill: "#0066A0" //цвет заполнения контура
    });
    var eye2 = s.path("M109 68c-1,-5 2,-9 7,-9 4,0 7,4 6,9 -4,-2 -8,-2 -13,0z").attr({
        fill: "#0066A0" //цвет заполнения контура
    });

</script>

В итоге у нас отрисовался такой Клаудмен:

Отлично, теперь научим его махать рукой. Для этого нам необходимо создать переменную cloudmanEndPath, которая будет хранить второе состояние контура Клаудмена, а так же добавить в код функцию анимации контуров. Дополненный код выглядит так:


<script type="text/javascript">

    // Укажем библиотеке snap.svg место, в котором мы будем рисовать наше изображение;
    var s = Snap("#cloudman");

    // Контур туловища, в который входят и руки, будет меняться.
    // Запишем оба положения в переменные
    var cloudmanStartPath = "M74 7c15,-10 36,-9 51,1 10,7 17,19 19,32 2,8 -1,17 -1,25 -1,16 -1,33 1,49 0,3 2,5 4,7 3,5 5,9 7,14 2,8 1,16 0,23 -1,3 -1,7 -4,7 -3,2 -7,-2 -7,-5 2,-9 4,-18 0,-27 -3,13 -11,24 -23,30 2,5 4,11 4,16 0,4 -1,8 -2,12 3,0 7,-1 9,2 2,2 1,7 -3,7 -4,1 -7,1 -11,0 -3,0 -6,-4 -6,-7 1,-5 3,-9 3,-14 0,-4 -1,-8 -3,-12 -9,3 -20,2 -29,0 -2,4 -3,8 -4,12 1,5 3,9 3,14 1,3 -2,7 -6,7 -3,1 -7,1 -11,0 -3,0 -4,-5 -2,-7 2,-3 6,-2 9,-2 -1,-4 -3,-8 -3,-12 1,-6 3,-11 5,-17 -12,-8 -20,-21 -21,-35 -8,6 -16,12 -26,13 -6,1 -9,0 -13,-5 -2,-2 -7,-8 -9,-13 -3,-6 -5,-14 -5,-15 0,-4 1,-5 3,-5 2,-1 4,-1 6,2 3,4 9,29 18,26 10,-2 17,-9 24,-15 -2,-25 -1,-50 2,-74 1,-14 9,-26 21,-34z";
    var cloudmanEndPath = "M74 7c15,-10 36,-9 51,1 10,7 17,19 19,32 2,8 -1,17 -1,25 -1,16 -1,33 1,49 0,3 2,5 4,7 3,5 5,9 7,14 2,8 1,16 0,23 -1,3 -1,7 -4,7 -3,2 -7,-2 -7,-5 2,-9 4,-18 0,-27 -3,13 -11,24 -23,30 2,5 4,11 4,16 0,4 -1,8 -2,12 3,0 7,-1 9,2 2,2 1,7 -3,7 -4,1 -7,1 -11,0 -3,0 -6,-4 -6,-7 1,-5 3,-9 3,-14 0,-4 -1,-8 -3,-12 -9,3 -20,2 -29,0 -2,4 -3,8 -4,12 1,5 3,9 3,14 1,3 -2,7 -6,7 -3,1 -7,1 -11,0 -3,0 -4,-5 -2,-7 2,-3 6,-2 9,-2 -1,-4 -3,-8 -3,-12 1,-6 3,-11 5,-17 -12,-8 -20,-21 -21,-35 -8,6 -17,11 -26,12 -7,1 -9,-1 -11,-4 -2,-2 -4,-10 -5,-17 0,-6 -1,-14 -1,-16 0,-4 1,-4 3,-5 2,-1 5,-1 7,2 3,4 -3,32 7,30 9,-2 17,-8 24,-14 -2,-25 -1,-50 2,-74 1,-14 9,-26 21,-34z";

    // Отрисуем первое состояние, используя начальный контур cloudmanStartPath
    var cloudman = s.path(cloudmanStartPath).attr({
        fill: "#2EC6F7" //цвет заполнения контура
    });

    // Нарисуем рот Клаудмена
    var mouth = s.path("M81 81c7,-2 15,-1 22,-1 3,-1 8,1 6,5 -6,10 -23,10 -29,0 -2,-1 -1,-3 1,-4z").attr({
        fill: "#FFFFFF" //цвет заполнения контура
    });

    // Нарисуем глаза Клаудмена
    var eyeLeft = s.path("M71 68c-1,-4 1,-9 5,-9 5,-1 9,4 8,8 -4,-1 -9,0 -13,1z").attr({
        fill: "#0066A0" //цвет заполнения контура
    });

    // У одного глаза сделаем два состояния, для "подмигивания"
    var eyeStartPath = "M109 68c-1,-5 2,-9 7,-9 4,0 7,4 6,9 -4,-2 -8,-2 -13,0z";
    var eyeEndPath = "M109 68c-1,-2 2,-5 7,-5 4,0 7,3 6,5 -4,-1 -8,-1 -13,0z";

    var eyeRight = s.path(eyeStartPath).attr({
        fill: "#0066A0" //цвет заполнения контура
    });

    // Изменение состояния контура туловища
    function animateCloudman(path, speed, callback) {
        return cloudman.stop().animate({'path': path}, speed, mina.easeout, function () {
            callback()
        });
    }

    // Изменение состояния контура глаза
    function animateEye(path, speed, callback) {
        return eyeRight.stop().animate({'path': path}, speed, mina.easeout, function () {
            callback()
        });
    }

    // Анимация маха рукой
    function startAnimation() {
        // Количество махов
        var count = 10;

        function a() {
            if (count <= 0) {
                return;
            }
            count--;
            animateCloudman(cloudmanStartPath, 300, b);
        }

        function b() {
            if (count <= 0) {
                return;
            }
            count--;
            animateCloudman(cloudmanEndPath, 300, a);
        }

        a();
    }

    // Стартуем анимацию
    startAnimation();
    window.setInterval(function () {
        startAnimation();
    }, 3500);

    // А еще раз в 2 секунды будем подмигивать
    window.setInterval(function () {
        animateEye(eyeEndPath, 200, function () {
            animateEye(eyeStartPath, 300, function () {
            })
        });
    }, 2000);

</script>

"Улыбаемся и машем!" Теперь наш Клаудмен будет махать пользователю, привлекая его внимание. Используя показанный метод, мы можем анимировать любую часть персонажа, чтобы сделать его движения более плавными и живыми.

Архив с векторными изображениями Клаудмена можно скачать ТУТ.