Статьи

Анимация вашего мобильного интерфейса с Famo.us и Telerik AppBuilder

Автор Джен Лупер для Telerik Mobile Blog.

famous_header

Шум, возникший в связи с библиотекой JavaScript Famo.us, вызванный потрясающей демонстрацией, появившейся в 2012 году с 3D-рендерингом периодической таблицы , оказался практически беспрецедентным. Разработчики выстроились в очередь, чтобы попасть в закрытую бета-версию, поцарапанные, когтистые, боролись за места, и последовал хаос.

беспредел на запуске Famo.us

беспредел на запуске Famo.us

Это небольшое преувеличение, но не сильно. Совсем недавно мы увидели развертывание университета Famo.us , некоторые демонстрации и разработку проекта Famo.us/Angular , который помогает структурировать кодовую базу с использованием стратегий углового и декларативного макетов.

Так что же такое Famo.us и как мы можем использовать его для коммерческих приложений?

По данным сайта Famo.us:

Famo.us — это единственный JavaScript-фреймворк, который включает в себя движок трехмерного макета с открытым исходным кодом, полностью интегрированный с движком трехмерной физической анимации, который может рендериться в DOM, Canvas или WebGL.

Что это значит на самом деле?

Фреймворк Famo.us использует другой подход к отображению элементов на экране. Поскольку манипулирование DOM считается дорогостоящим и снижает производительность приложения, написание приложения на Famo.us почти полностью построено на JavaScript. Вместо того, чтобы манипулировать DOM путем написания вложенного HTML, «Famo.us абстрагирует управление DOM, поддерживая его представление в JavaScript, называемое деревом рендеринга».

В двух словах:

  • Написание приложения на HTML и манипулирование его внешним видом и поведением с использованием JavaScript замедляет «время, необходимое пользователю». Famo.us подчеркивает анимационные эффекты, обещая рендеринг со скоростью 60 кадров в секунду, поэтому ему нужен более быстрый способ доставки контента.
  • Фреймворк Famo.us использует дерево рендеринга, чтобы избежать дорогостоящих манипуляций с вложенными элементами DOM — это дерево является представлением DOM, но написано на JavaScript.
  • Узнайте больше о Дереве рендеринга и о том, как использовать его здесь .

Зачем мне это использовать?

Плавные, быстрые анимации могут быть важны для обеспечения хорошего пользовательского опыта. Все больше и больше мы видим веб-сайты, которые используют движение, чтобы заставить пользователя выполнять определенные задачи, будь то с помощью библиотеки, такой как GreenSock , Paper.js , или CSS-преобразования , написанные вручную. Если ваше приложение имеет сложный пользовательский интерфейс и / или требует анимации, которая необходима для плавной работы на разных устройствах, то Famo.us может быть полезным вариантом для изучения. Кроме того, Famo.us работает для настольных приложений, поэтому вы можете использовать код, разработанный для мобильного приложения, на адаптивном веб-сайте.

Давайте что-нибудь построим!

Мы собираемся создать приложение-карточку для викторины с интерфейсом Famo.us, который подключен к API Quizlet и развернут на платформе Telerik. Это будет выглядеть так:

Это приложение имеет три требования:

  • Включите форму, в которую пользователь может ввести идентификатор теста (найдите идентификатор теста в URL-адресе любого набора тестов Quizlet. Чтобы найти идентификатор, перейдите на Quizlet.com, найдите набор тестов и получите его идентификатор из URL-адреса. Например, идентификатор из URL http://quizlet.com/2154706/200-first-french-verbs-flash-cards/ будет 2154706)
  • Приложение будет иметь интерфейс интерфейса карты. Прикоснитесь к значку «счастливое лицо», чтобы подтвердить понимание, и сдвиньте карту в левом нижнем углу. Нажмите значок «звездочка», чтобы заархивировать карту для последующего просмотра.
  • Каждая карта перевернется, чтобы включить вопросы и ответы, предоставленные Quizlet.

Перенести код в AppBuilder

Завершенный код можно найти здесь .

Я решил использовать проект Famo.us/Angular для структурирования кода для этого приложения, так как я ценю простоту двухсторонней привязки для доставки контента на карты и способ, которым этот проект предлагает основанный на тегах декларативный формат для вид.

Клонируйте его на рабочий стол, а затем создайте пустой проект в Telerik Platform, выполнив следующие действия.

У вас нет лицензии на платформу? Не волнуйтесь, вы можете попробовать его бесплатно в течение 30 дней.

  1. Создайте в Платформе рабочую область под названием Sweet Quizzes:
    Создание рабочего пространства
  2. Создайте пустой гибридный проект AppBuilder в этом рабочем пространстве, клонируя репозиторий SweetQuizzes Github (https://github.com/jlooper/SweetQuizzes):

    10

  3. Зарегистрируйте учетную запись Quizlet, а затем зарегистрируйтесь для получения ключа API. На панели инструментов Quizlet вы увидите свой идентификатор клиента. Откройте файл scripts> config.js и добавьте свой client_id:
var CLIENT_ID = "your-client-id"

Теперь вы можете запустить свое приложение, нажав кнопку «Выполнить» в верхней части экрана и выбрав симулятор по вашему выбору для просмотра приложения:

бег

В текстовом поле введите 2154706 в качестве примера идентификатора теста и нажмите кнопку «Получить тест». Вы должны увидеть карты; щелкните их, чтобы перевернуть вопросы и ответы на викторину, и щелкните значки «смайлик» или «звездочка», чтобы сдвинуть их влево или вправо. Если вы нажмете «смайлик», пара вопросов / ответов будет удалена из коллекции, на которой построен тест; если вы нажмете «звездочку», вы добавите ее в коллекцию «обзор», чтобы вернуться к ней позже:

sim2

Изучение Famo.us

Теперь, когда приложение настроено и запущено в AppBuilder, давайте посмотрим на код. Структура кода основана на проекте семени Famo.us/Angular, который вы можете скачать здесь .

После загрузки начального проекта и его расширения из командной строки перейдите в папку, которую вы только что загрузили, и перейдите к стартеру / приложению. Предполагая, что у вас установлен npm с модулем локального сервера, таким как serve , вы можете просто напечатать, serveи проект будет запущен по адресу http: // localhost: 3000. Стартовый проект — это просто демонстрация логотипа Famo.us, вращающегося вокруг — не очень интересно, хотя вы можете использовать ползунок для управления скоростью вращения.

Однако, если вы перейдете в / examples / app, вы можете еще немного покопаться. В текущем окне терминала нажмите Ctrl + C, чтобы прекратить обслуживать localhost: 3000. Перейдите в папку / examples / app и введите «serve» в окне терминала, чтобы перезапустить localhost: 3000. Теперь вы должны увидеть изображение iphone с бабуином (я не знаю, почему есть бабуин, но вы здесь).

обезьяна

Откройте папку / examples в Sublime text или по вашему выбору. Вы можете просмотреть несколько различных эффектов анимации и макета, перейдя к конечным точкам, указанным в /scripts/controllers/app.js. Попробуйте изменить свой локальный URL-адрес на http: // localhost: 3000 / # / Физика-частицы и наведите курсор мыши на изображение, чтобы увидеть интересную демонстрацию, ориентированную на физику. Навигация по этим демонстрационным программным кодам дает вам хорошее представление о возможностях создания интересного пользовательского интерфейса.

Структура кода

Для наших целей мы будем использовать Famo.us для его анимации и Famo.us/Angular для его макета и декларативного синтаксиса. Обратите внимание, что проект, который вы импортировали в AppBuilder, имитирует структуру папок начального приложения:

app
— bower_components
— css
— img
— partials
— скрипты
index.html

В папке bower_components у нас есть несколько зависимостей, которые Famo.us/Angular использует для создания и управления экранами. Эти зависимости включены в index.html вместе с несколькими файлами .css.

<script src="bower_components/famous/famous-global.min.js"></script><script src="bower_components/famous-angular/dist/famous-angular.js"></script>

CSS содержит несколько специальных стилей, чтобы приложение отображало красивые цвета, которые я выбрал на ColourLovers.com . Папка img содержит счастливое лицо и звездную графику SVG, которые действуют как кнопки.

раскладка

Однако основная часть приложения находится в папках partials и scripts.

Частично мы используем метод разметки Famo.us/Angular для создания макета приложения. Весь код для пользовательского интерфейса ниже:

<fa-app class="full-screen" id="app">


 <fa-header-footer-layout fa-options="{headerSize: 75, footerSize: 75}">


     <fa-surface fa-background-color="'#FBC5C5'"><p class="title">Sweet Quizzes</p></fa-surface>


      <fa-surface fa-background-color="'#9ECEBE'">
          <div class="getnew">

              <form>
                 <input type="text" name="quizId" placeholder="Quiz Id" ng-model="quiz.quizId">
                <button class="blue" ng-click="getNewQuiz(quiz)">Get Quiz</button>
                <button class="pink" ng-click="getReviewQuiz()"><img src="img/star.svg" class="star-icon"/>Review</button>              
              </form>

           </div>

               <div align="center">
                  {{quizTitle}}
              </div>

            <img style="float:left" src="img/happy.svg" ng-click="nextQuestion()"/>
            <img style="float:right" src="img/star.svg" ng-click="storeQuestion()"/> 

      </fa-surface>

  </fa-header-footer-layout>

</fa-app>

Обратите внимание на использование fa-header-footer-layout. Эта разметка сообщает famo.us/Angular, что мы создаем макет определенного типа, и я включил две «fa-поверхности», которые по сути являются div, чтобы содержать верхний заголовок и область, содержащую кнопки управления и форму, в которой карты упадут. Если вам нужны заголовок, внутренний div и нижний колонтитул, вы должны включить три fa-поверхности, но я обнаружил, что абсолютно позиционированный нижний колонтитул создает проблемы с моими картами на устройстве из-за некоторых конфликтов разметки CSS, поэтому я выбрал более простой раскладка.

Простая форма позволяет пользователю ввести идентификатор теста из Quizlet, который загружает контент для отображения на карточках, которые падают сверху. Но где карты? Они не появляются в этом файле макета; они полностью создаются и контролируются в JavaScript-файлах Famo.us в папке / scripts. Давайте посмотрим на них.

Код Famo.us

Теперь мы подошли к самому важному: коду, который управляет картами. Это файл /scripts/main/main-ctrl.js. Этот файл дает нам хорошее представление о том, как структурировать приложение Famo.us.

Во-первых, включайте только те элементы Famo.us, которые вам нужны для вашего приложения. Интерфейс карты, который я построил, включает в себя анимированный «флиппер», карту, состоящую из передней и задней поверхностей, которая содержит контент, введенный через фабрику Quizlet, на которую ссылается контроллер. Для этого мы собираемся включить несколько частей библиотеки Famo.us:

  • Для начала нам понадобится Engine и модификатор, которые являются наиболее распространенными элементами приложения Famo.us и действуют как базовая структура вышеупомянутого дерева рендеринга.
  • Мы включаем поверхность, которая является потомком модификатора
  • Наконец, мы включаем библиотеку Transform, которая позволяет нам перемещать модификатор по экрану:
var Engine = $famous['famous/core/Engine'];
var Modifier = $famous['famous/core/Modifier'];
var Surface = $famous['famous/core/Surface'];
var Transform = $famous['famous/core/Transform'];

Добавьте Flipper, который является типом представления, управляющим интерфейсом наших карт:

var Flipper = $famous['famous/views/Flipper'];

Добавьте утилиту Timer, которая позволяет нам контролировать длину наших анимаций:

var Timer = $famous['famous/utilities/Timer'];

И, наконец, обозначим типы переходов, которые нам нужны:

var Easing = $famous['famous/transitions/Easing'];
var Transitionable = $famous['famous/transitions/Transitionable'];
var SpringTransition = $famous['famous/transitions/SpringTransition'];
Transitionable.registerMethod('spring', SpringTransition);

Далее мы создадим некоторые переменные, $scopeкоторые мы будем использовать позже:

$scope.index = 0;
//sample quiz
$scope.quizId = 2273151;
$scope.reviewQuizData=[];

Давайте создадим основной контекст нашего приложения Famo.us:

var mainContext = Engine.createContext();

Получите данные теста из Quizlet после того, как пользователь введет действительный идентификатор теста:

$scope.getNewQuiz = function (quiz) {
  if(angular.isDefined(quiz)){
    $scope.quizId = quiz.quizId;
    if($scope.quizData){
      $scope.clear();
    }
      $scope.loadQuiz()
    }
  else{
    alert("Please enter a quiz id from Quizlet. Try 2154706")
  }
};

Мы также создаем функцию, в которой сохраненные вопросы пользователя могут быть вызваны и просмотрены:

$scope.getReviewQuiz = function (quiz) {
  $scope.clear();
  $scope.quizData = $scope.reviewQuizData;
  $scope.buildInterface();
};

Получив данные из Quizlet, мы получаем заголовок и связанные с ним данные, необходимые для интерфейса:

$scope.loadQuiz = function () {            
  var promise = quizlet.getQuiz($scope.quizId);
  promise.success(function (data) {
    $scope.quizTitle = data.title;
    $scope.quizData = data.terms;
    $scope.buildInterface();
  });
  promise.error(function () {
    console.log("API ERROR!", arguments);
  })
};

На данный момент мы готовы построить интерфейс карт. Здесь мы создаем новый Flipper с модификатором центра, расположенным немного ниже центра экрана (чтобы освободить место для верхних элементов) и указываем размеры передней и задней поверхностей. Мы добавляем данные опроса на переднюю и заднюю поверхности флиппера и сообщаем ему, как мы хотим, чтобы он вел себя при нажатии. Наконец, мы добавляем кусочки все вместе в здании Famo.us стиле из дерева отображения, добавляя flipperк modifierк maincontext.

$scope.buildInterface = function() {
    if(!angular.isDefined($scope.quizData)){
        alert("Sorry, that quiz id seems to be invalid")
     } 
     else {
      if($scope.quizData.length>0){
        $scope.flipper = new Flipper();
        $scope.centerModifier = new Modifier({
           origin: [0.5, 0.25],
           align: [0.5, 0.25]
        });

        var frontSurface = new Surface({
             size: [200, 200],
             content: $scope.quizData[$scope.index].term,
             properties: {
                  background: '#F09BA2',
                  textAlign: 'center',
                   border: '5px solid #FBC5C5',
                   borderRadius: '10px',
                   padding:'10px'
              }
        });

        var backSurface = new Surface({
             size: [200, 200],
             content: $scope.quizData[$scope.index].definition,
             properties: {
                 background: '#FBC5C5',
                 color: 'black',
                 textAlign: 'center',
                 border: '5px solid #FBC5C5',
                 borderRadius: '10px',
                 padding:'10px'
             }
       });

       $scope.flipper.setFront(frontSurface);
       $scope.flipper.setBack(backSurface);

       var toggle = false;
        frontSurface.on('click', function () {
            var angle = toggle ? 0 : Math.PI;
              $scope.flipper.setAngle(angle, {
                 curve: 'easeOutBounce',
                 duration: 800
              });
            toggle = !toggle;
         });
         backSurface.on('click', function () {
            var angle = toggle ? 0 : Math.PI;
               $scope.flipper.setAngle(angle, {
                  curve: 'easeOutBounce',
                  duration: 800
               });
             toggle = !toggle;
         });

         var spring = {
            method: 'spring',
            period: 1000,
            dampingRatio: 0.3
         };

         $scope.centerModifier.setTransform(
             Transform.translate(0,200,0),spring
         );
                                     mainContext.add($scope.centerModifier).add($scope.flipper);

     }
     else{
      alert("all done!")
     }
   }
};

В конце этого файла у нас есть три дополнительные функции. Первая — это функция очистки, которая удаляет все старые данные викторины и начинает заново:

$scope.clear = function(){
    $scope.quizData=[];
    $scope.centerModifier.setTransform(
       Transform.translate(-300,800,0),
          { duration : 200, curve: 'easeInOut' }
       );
};

У нас также есть возможность получить следующий вопрос, если пользователь щелкнет значок улыбки (демонстрируя, что он / она изучил вопрос и ему не нужно возвращаться для его просмотра), нажав на карточку слева от экрана и собрав новая карта:

$scope.nextQuestion = function() {
    //remove learned question
    $scope.quizData.splice($scope.index, 1);
    $scope.centerModifier.setTransform(
       Transform.translate(-300,800,0),
         { duration : 200, curve: 'easeInOut' }
    );

    Timer.setTimeout(function() {
        $scope.buildInterface()
     }, 1000);
};

Точно так же мы включаем storeQuestionфункцию, чтобы пользователь мог вернуться к просмотру вопросов:

$scope.storeQuestion = function() {
    //capture the data for future review
    $scope.quizData.splice($scope.index, 1);            
    $scope.reviewData = $scope.quizData[$scope.index]
    $scope.reviewQuizData.push($scope.reviewData);
    $scope.centerModifier.setTransform(
       Transform.translate(300,800,0),
          { duration : 200, curve: 'easeInOut' }
    );
       Timer.setTimeout(function() {
           $scope.buildInterface()
        }, 1000);         
};

Заканчивать

Хотя интерфейс этого приложения очень прост, я думаю, что анимации Famo.us помогают сделать его красивым и привлекательным. Я могу представить создание интерфейса сортировки карт в стиле Tinder или Jelly с управляемой пользователем анимацией — они могли бы контролировать замедление и отскок с помощью каких-то настроек для индивидуальной настройки своего интерфейса. Famo.us предлагает много привлекательной огневой мощи, чтобы дать разработчику почти неограниченное движение вокруг экранов всех типов. Кроме того, использование модели Famo.us/Angular упрощает создание макета для размещения анимации. Плавная, плавная анимация, на мой взгляд, является одной из важных тенденций в ближайшем будущем для мобильных и настольных приложений, поэтому изучение Famo.us теперь кажется хорошим вложением времени. Мне не терпится увидеть новые приложения, созданные с помощью Famo.us! Если у вас есть, не стесняйтесь размещать ссылку ниже.