- PVSM.RU - https://www.pvsm.ru -
И снова доброго времени суток, читатели. Меня зовут Владимир Миленко, и как вы возможно знаете, я фронтенд-разработчик в компании Иннософт. Возможно вы так-же заметите, что в свободное время я изучаю ситуацию на рынке разработки мобильных приложений. Несколько дней назад я написал статью, в которой описал, что такое NativeScript. Пришло время познакомить вас с другим уникальным инструментом, аналогов которому нет.
Речь пойдет о FuseTools — фреймворк для написания нативных мобильных приложений с потрясающими возможностями.
FuseTools — фреймворк, который предоставляет доступ к OpenGL без необходимости написания кода для него.
В чем кардинальное отличие от NativeScript, React.Native:
Fuse работает на уровне OpenGL, предоставляя расширенный доступ к генерации лэйаута. Fuse так же позволяет использовать нативные компоненты, но предоставляет куда более удобный доступ к различным функциям OpenGL.
Что это дает? Это дает возможность создавать такие анимации, которые вам и не снились, а если и снились — их было очень тяжело привнести в жизнь. Но и не только анимации, в будущем, вы сможете создавать компоненты, и использовать их в своих проектах, но обо всем по порядку.
Fuse — инструмент не только для прототипирования, но и для разработки. Вы можете писать JS код, который отвечает за логику вашего приложения, но сам UI описывается в декларативном стиле в .ux файлах.
Можно ли вызывать нативные методы из Fuse?
— Да, можно. Для этого используется язык Uno, который позволяет писать код на ObjC/Java, а потом сам компилирует его в тот же нативный код.
Можно ли использовать NPM-пакеты?
— Да, можно. Для этого используется сторонняя утилита, которая заставляет компилятор Fuse забирать NPM пакет в бандл.
Поддерживается ли HotReload?
— Поддерживается, работает очень быстро.
Переходим на fusetools.com [1] и скачиваем установщик для вашей ОС: Mac/Windows.
Думаю, про то, как нажимать кнопочку “Я согласен”,”Далее” — не нужно.
Мы уже почти готовы к созданию проекта, продолжим:
В терминале
fuse create app habr
cd habr
Для ознакомления нам понадобится Sublime Text/Atom/VS Code, для этих редакторов уже есть плагины.
Для того, чтобы установить sublime плагин:
fuse install sublime-plugin
Предварительно запустим превью нашего проекта, для этого нужно вызвать контекстное меню на .ux файле и запустить Preview->Local.
Открываем нашу папку habr в саблайме и переходим в MainView.ux.
В этом файле мы увидим целое приложение, состоящее из тега .
Раз уж я говорил об анимации, давайте поставим такую цель:
В данном случае нам не нужен JS, поэтому мы вполне обойдемся без него, но эту тему затронем ближе к концу нашего ознакомления.
Опишем базовый лэйаут:
<App>
<ClientPanel>
</ClientPanel>
</App>
Теперь, рассмотрим набор имеющихся примитивов: Rectangle, Circle, Text, Image, Video.
Выберем необходимые нам — Rectangle и Circle.
Перейдем к чуть сложному, созданию собственных шаблонов компонентов.
Fuse имеет различные конструкции, которые позволяют описывать ваш лэйаут, воспользуемся конструкцией Class.
<Rectangle ux:Class="SnapButton" CornerRadius="30" Margin="10" Color=”#5E2E91”>
</Rectangle>
Я думаю, здесь все понятно, это шаблон прямоугольника, с отступами со всех сторон по 10 pt, и скруглением углов в 30 pt.
Разместим инстанс нашего шаблона в ClientPanel.
В итоге, наш код будет выглядеть примерно так:
<App>
<ClientPanel>
<SnapButton ux:Name=”loginButton” Width=”300” Height=”60” />
</ClientPanel>
</App>
Добавим внутрь нашего инстанса SnapButton круг:
<Circle ux:Name="loadingCircle" Width="50%" Height="50%" Opacity="0" StartAngleDegrees="0" LengthAngleDegrees="90">
<Stroke Width="2" Brush="#fff" />
</Circle>
Из выше описанного кода видно, что наш круг прозрачен и не отображается по умолчанию, также можно заметить, что это не полный круг, а всего-лишь четверть круга. Внутри мы описываем параметр Stroke — обводка, ширина -2, цвет-белый.
Распишем по шагам:
Fuse дает нам возможность описывать триггеры, теперь опишем триггер, который будет вызывать анимацию изменения ширины нашей кнопки:
<WhileTrue ux:Name=”loading”>
<Change changeWidth.Value=”true” DelayBack=”0” />
</WhileTrue>
<WhileTrue ux:Name=”changeWidth”>
<Change loginButton.Width="60" Duration=".5" DurationBack=".5" Easing="CircularInOut"/>
</WhileTrue>
Из разметки выше видно, что есть два триггера, один с названием loading, управляющий включением триггера changeWidth.
Триггер ChangeWidth в свою очередь запускает изменение параметра Width у объекта с именем loginButton, длительностью 0.5 секунды в обе стороны.
Не будем хоть вперед да около, опишем триггер анимации нашего круга:
<WhileTrue ux:Name="loadCircle">
<Change loadingCircle.Opacity="1" Duration="0.3" Delay="0.2" DelayBack="0" DurationBack="0"/>
<Spin Target="loadingCircle" Frequency="2"/>
<Cycle Target="loadingCircle.LengthAngleDegrees" Low="10" High="300" Frequency="0.7" />
</WhileTrue>
Здесь мы встречаем Spin и Cycle, первый вращает объект, с заданной частотой, второй же выполняет цикличное изменение параметра с частотой, в нашем случае мы изменяем длину нашей окружности от 10 до 300 в течении 0.7 секунды.
И последнее — добавим наш новый триггер в триггер loading, после чего вызовем смену значения триггера по событию нажатия на нашу кнопку.
Вот и все, мы сделали довольно красивую интерактивную кнопку, которая может отображать состояние приложения.
Финальный код будет выглядеть так:
<App>
<ClientPanel>
<SnapButton ux:Name="loginButton" Width="300" Height="60">
<Clicked>
<Toggle Target="loading"/>
</Clicked>
<Circle ux:Name="loadingCircle" Width="50%" Height="50%" Opacity="0" StartAngleDegrees="0" LengthAngleDegrees="90">
<Stroke Width="2" Brush="#fff" />
</Circle>
</SnapButton>
</ClientPanel>
<Rectangle ux:Class="SnapButton" CornerRadius="30" Margin="10" Color="#5E2E91">
</Rectangle>
<WhileTrue ux:Name="loading">
<Change changeWidth.Value="true" DelayBack="0"/>
<Change loadCircle.Value="true" DelayBack="0"/>
</WhileTrue>
<WhileTrue ux:Name="changeWidth">
<Change loginButton.Width="60" Duration=".5" DurationBack=".5" Easing="CircularInOut"/>
</WhileTrue>
<WhileTrue ux:Name="loadCircle">
<Change loadingCircle.Opacity="1" Duration="0.3" Delay="0.2" DelayBack="0" DurationBack="0"/>
<Spin Target="loadingCircle" Frequency="2"/>
<Cycle Target="loadingCircle.LengthAngleDegrees" Low="10" High="300" Frequency="0.7" />
</WhileTrue>
</App>
Стоит заметить, что Fuse поддерживает огромное количество различных параметров для создания анимаций, наложения эффектов, но перейдем дальше.
Здесь есть несколько вариантов, все они достаточно сырые, что объясняется состоянием Fuse — бета, коммьюнити не такое большое, хотя и готовятся к open-source.
Можно писать на EcmaScript5, либо в JS файлах, либо внутри разметки.
Подключить JS можно добавив тег
<JavaScript File=”file.js” />
Фактически, нам дают MVVM и говорят, ну вот как-то так.
Немного поплясав, можно добиться интеграции с ES2015-> Babel -> ES5. Точно столько же танцев потребуется на интеграцию TS, о чем я подробно описал на форуме fuse [2].
Fuse оперирует данными с помощью Observabl’ов, пример использования можно найти по ссылке выше. По умолчанию вам так же доступен Two-Way Binding.
Вернемся к выполнению нативного кода:
Fuse использует язык Uno, больше похожий на C#, однако предоставляющий возможность декорировать методы и параметры исполняемыми языками.
Выглядит это примерно так:
[Foreign(Language.ObjC)]
static float GetValue(ObjC.Object handle)
@{
::UISlider* slider = (::UISlider*)handle;
return [slider value];
@}
Разрабатывать на Fuse что-то серьезное пока-что вряд ли получится, хотя ничего особо не мешает. А вот для создания прототипа, который можно пощупать — на мой взгляд самое то.
По обещаниям, Fuse будет представлять возможность экспортировать компоненты для использования в проектах(что, на мой взгляд, прекрасно).
Ссылки:
Официальный сайт: fusetools.com [1]
Установка npm пакетов для приложения: github.com/Sunjammer/nfuse [3]
Автор: AsTex
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ux/230549
Ссылки в тексте:
[1] fusetools.com: http://fusetools.com/
[2] о чем я подробно описал на форуме fuse: https://www.fusetools.com/community/forums/show_and_tell/combining_fuse_with_typescript
[3] github.com/Sunjammer/nfuse: https://github.com/Sunjammer/nfuse
[4] Источник: https://habrahabr.ru/post/319056/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.