Статьи

Создайте мобильное приложение, используя Famo.us и Angular

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

Famo.us делает это, используя примитив CSS3 -webkit-transform: matrix3d , который позволяет платформе вычислять составную матрицу и пропустить средство визуализации браузера. Нет плагина, нет загрузки, нет взлома. Добавив это к каждому DIV, разработчики могут визуализировать составную матрицу и перейти прямо к графическому процессору.

Я углубляюсь в обсуждение всех подробностей Famo.us в этом посте . Спасибо Заку Брауну за его помощь в этом! Давайте начнем.

К концу этого проекта вы сможете:

  • понять, как работает Angular в контексте приложения Famo.us
  • использовать истинную силу JavaScript и хорошие части HTML5
  • создавать плавные анимации

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

  • Мобильное приложение работает на iOS и Android через Cordova.
  • Универсальное приложение Windows 10 изначально работает на Windows 10.
  • Этот проект также может быть запущен как размещенный веб-сайт, хотя у меня есть его масштаб, который лучше всего подходит для мобильных устройств.
  • ПК или Mac
  • веб сервер
  • Кросс-платформенная тестовая матрица (например, BrowserStack, IDE или бесплатные виртуальные машины для EdgeHTML, механизм рендеринга для Microsoft Edge и размещенный контент веб-приложений в Windows 10)
  1. Загрузите источник с GitHub .
  2. Загрузите и установите веб-сервер (я использую MAMP на OS X или встроенный сервер IIS с Visual Studio на Windows).
  1. Запустите свой веб-сервер.
  2. Перейдите к известному-angular-Pokemon / app / .

Проект предназначен для работы на мобильных устройствах, поэтому используйте мобильный эмулятор в своем браузере, чтобы получить правильный вид. Вот как это будет выглядеть на iPhone 6 внутри эмулятора с помощью браузера Chrome для настольных ПК (375×667):

Создавалось мобильное приложение, отображаемое на эмуляторе iPhone 6

Я извлекаю всю информацию из PokeAPI , который имеет хорошо документированный API, но в нем отсутствуют изображения для каждого покемона. Для изображений я просто вытягиваю имя выбранного в данный момент покемона и добавляю его в конец этого URL: http://img.pokemondb.net/artwork/ . Например: http://img.pokemondb.net/artwork/venusaur.jpg приведет вас к изображению Vanosaur. Отличный, верно? К сожалению, у них нет API.

Каждый раз, когда пользователь нажимает кнопку Next , генерируется случайное число между значением min / max, которое я определил (скажем, от 1 до 20), и он извлекает покемона из базы данных, которая соответствует этому числу. Вот как это выглядит:

http://pokeapi.co/api/v1/pokemon/1/ возвращает объект JSON для Bulbasaur. Вы можете играть с их API .

Затем я перебираю этот объект JSON и устанавливаю свойства, которые нахожу, переменными в Angular, используя объект $Scope .

Вот пример:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*
  * Grab Pokemon from the DB
  */
 $scope.getPokemon = function () {
 
   // Generate a random num and use it for the next pokemon
   getRandomInt($scope.minVal, $scope.maxVal);
 
   // Retrieve data from DB and draw it to screen
   $http.get($scope.dbURL + $scope.pokemonNum + «/»)
     .success(function(data) {
       $scope.name = data.name;
       $scope.imageUrl = $scope.imgDbURL + $scope.name.toLowerCase() + ‘.jpg’;
 
       /* 1) Empty out the current array to store the new items in there
        * 2) Capitalize the first character for each ability from the database
        * 3) Store that ability in a new abilityObj & add it into the abilities array
        */
       $scope.abilities.length = 0;
       for (var i = 0; i < data.abilities.length; i++){
        var capitalizedString = capitalizeFirstLetter(data.abilities[i].name);
        var abilityObj = {name: capitalizedString };
         $scope.abilities.push(abilityObj);
       }
 
       $scope.hitPoints = data.
       var firstType = data.types[0].name;
       $scope.types.name = capitalizeFirstLetter(firstType);
       determineNewBgColor();
     })
     .error(function(status){
       console.log(status);
       $scope.name = «Couldn’t get Pokemon from the DB»;
     });
 };

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

Я также перебираю способности и помещаю их в объект способности, который выглядит следующим образом:

1
2
3
4
$scope.abilities = [
   { name: «Sleep»},
   { name: «Eat» }
 ];

База данных также возвращает несколько типов для определенных покемонов, таких как Чаризард, который летит так же, как и огонь. Для простоты я хотел вернуть только один из базы данных.

1
2
3
$scope.types = { name: «Grass» };
 
 var firstType = data.types[0].name;

Famo.us имеет две волны рисования контента на экране, создавая поверхности , которые являются элементами, которые содержат ваш текст, изображения и т. Д .:

  • JavaScript
  • Директивы FA (HTML)

Я не использовал JavaScript для рисования поверхностей в этом приложении. Вместо этого я решил использовать только директивы FA (Famous-Angular), такие как:

01
02
03
04
05
06
07
08
09
10
11
<!— Name—>
<fa-modifier
    fa-origin =»origin.center»
    fa-align =»align.frontName»
    fa-size =»size.frontName»
    fa-translate =»trans.topLayer»>
    <fa-surface
        class =»front-name-text»>
        {{name}}
    </fa-surface>
</fa-modifier>

Это имя над покемоном на переднем экране.

Вы заметите, что поверхность обернута fa-modifier . Вы можете прочитать о них в документации Famo.us , но они по существу регулируют свойства поверхности, такие как выравнивание, размер и происхождение. Мне потребовалось некоторое время, чтобы обернуть голову в разницу между выравниванием и происхождением, так что вот как я это понял.

Это точка отсчета на любой поверхности. Если я хочу нарисовать прямоугольник и переместить его по экрану, мне нужно решить, какая точка на этом прямоугольнике будет моей отправной точкой. Документы Famo.us хорошо это объясняют. Значения выложены следующим образом:

1
2
3
4
5
6
7
$scope.origin = {
                        // XY topLeft: [0, 0 ],
  topRight: [1, 0 ],
  center: [0.5, 0.5],
  bottomLeft: [0, 1 ],
  bottomRight: [1, 1 ]
 };

Это местоположение поверхности на экране. Когда вы вносите изменения в выравнивание, оно использует исходную точку в качестве исходной точки для начала.

1
2
3
4
5
6
$scope.align = {
                         // XY frontName: [0.50, 0.10],
   frontImg: [0.50, 0.40],
   backImg: [0.5, 0.38],
   center: [0.50, 0.50]
 };

Теперь вы можете использовать все свои навыки Angular и привязку данных для работы с реализацией Angular. Если вы уже знакомы с Angular, то здесь он не сильно отличается.

01
02
03
04
05
06
07
08
09
10
11
12
13
<!— Next button —>
<fa-modifier
    fa-origin =»origin.center»
    fa-align =»align.nextBtn»
    fa-size =»size.btn»
    fa-scale =»scale.nextBtn.get()»
    fa-translate =»trans.topLayer»>
    <fa-surface
        class =»one-edge-shadow center-align next-btn»
        ng-click =»getPokemon(); nextBtnPressAnim(); frontImgAnim()»>
        {{nextBtn}}
    </fa-surface>
</fa-modifier>

Эта кнопка появляется на первом экране и просто вытаскивает другого покемона из базы данных. Все знакомые вам директивы ng (Angular), такие как ng-click . У меня есть несколько функций здесь. Обратите внимание, что они не разделены запятыми.

Я также связываю значение $scope.nextBtn с {{nextBTn}} в HTML.

Чтобы позволить Famo.us и Angular работать вместе, нам нужно включить $Famo.us в начало нашего файла JavaScript. Вот как вы это делаете:

01
02
03
04
05
06
07
08
09
10
angular.module(‘famousAngularStarter’)
 .controller(‘PokemonCtrl’, [‘$scope’, ‘$http’, ‘$famous’, function ($scope, $http, $famous) {
 
   /* Inject famo.us to DOM */
   var View = $famous[‘famous/core/View’ ];
   var Modifier = $famous[‘famous/core/Modifier’ ];
   var Surface = $famous[‘famous/core/Surface’ ];
   var Transform = $famous[‘famous/core/Transform’ ];
   var Transitionable = $famous[‘famous/transitions/Transitionable’];
   var Timer = $famous[‘famous/utilities/Timer’ ];

Каким было бы высокопроизводительное приложение без анимации? Famo.us упакован с ними, что позволяет легко начать работу. Вот один для анимации изображения на передней панели.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
/*
  * @OnClick: Sets the opacity and scale for the front image when user clicks «Next» btn
  * 1) Turns opacity invisible quickly before returning to original opacity, revealing new Pokemon
  * 2) Turns scale down before quickly turning it back up to original size
  */
 $scope.frontImgAnim = function() {
   var hideDuration = 200;
   var returnDuration = 1300;
 
   $scope.opac.imgFront.
     function returnToOrigOpacity() {
       $scope.opac.imgFront.set(1, {duration: returnDuration, curve: «easeIn»})
     }
   );
   $scope.scale.imgFront .set([0.5, 0.5], {duration: hideDuration, curve: «easeIn»},
     function returnToOrigSize() {
       $scope.scale.imgFront.set([0.8, 0.8], {duration: returnDuration, curve: «easeIn»})
     }
   )
 };

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

Я столкнулся с несколькими проблемами по пути.

1
fa-origin =»origin.center»

Если у вас есть орфографическая ошибка, приложение будет просто использовать значения по умолчанию для этого свойства. Это меня зацепило несколько раз, поэтому вы видите, что я установил все свои свойства как объект, такой как align.frontName , чтобы его было легче читать.

В директивах FA вы добавляете несколько классов в виде строк, и они не разделяются запятыми.

1
2
3
4
5
<fa-surface
    class =»one-edge-shadow center-align next-btn»
    ng-click =»infoBtnPressAnim(); flip()»>
    {{infoBtnText}}
</fa-surface>

Если вы пытаетесь добавить классы, создавая поверхности в JavaScript, вы передаете массив строк.

1
2
3
4
5
6
var logo = new Surface({
    properties: {
         …
    },
    classes: [‘backfaceVisibility, class-two’]
});

Мне потребовалось некоторое время, чтобы понять это, поскольку я нашел решение только в этом .

В середине этого проекта я увидел, что Famo.us работает над улучшенной версией фреймворка, который включает в себя смешанный режим. Famo.us + Angular по крайней мере не использует эти дополнения (пока). Это не значит, что FA никуда не денется, так как работает отлично, просто вы не получите новейшие функции.

Эта статья является частью серии веб-разработок от технических евангелистов Microsoft, посвященной практическому изучению JavaScript, проектам с открытым исходным кодом и рекомендациям по взаимодействию, включая браузер Microsoft Edge и новый механизм рендеринга EdgeHTML .

Мы рекомендуем вам протестировать браузеры и устройства, включая Microsoft Edge — браузер по умолчанию для Windows 10 — с бесплатными инструментами на dev.modern.IE :

Глубокие технические знания по Microsoft Edge и веб-платформе от наших инженеров и евангелистов:

Больше бесплатных кроссплатформенных инструментов и ресурсов для веб-платформы: