And again, good day, habrazhiteli. My name is Vladimir Milenko, and as you possibly know, I am a front-end developer at Innosoft. You may also notice that in my free time I study the situation on the market for developing mobile applications. A few days ago I wrote an article in which I described what NativeScript is. It's time to introduce you to another unique tool, which has no analogues.
It will be about FuseTools - a framework for writing native mobile applications with amazing features.

What is FuseTools?
FuseTools is a framework that provides access to OpenGL without the need to write code for it.
')
What is the fundamental difference from NativeScript, React.Native:
Fuse works at the OpenGL level, providing extended access to the generation of the layout. Fuse also allows you to use native components, but provides far more convenient access to various OpenGL functions.
What does this give? This makes it possible to create such animations that you never dreamed of, and if you did, they were very difficult to bring to life. But not only animations, in the future, you will be able to create components, and use them in your projects, but first things first.
Fuse is a tool not only for prototyping, but also for development. You can write JS code that is responsible for the logic of your application, but the UI itself is described in a declarative style in .ux files.
Immediately block some questions that may arise:
Is it possible to call native methods from fuse?- Yes, you can. For this, the Uno language is used, which allows you to write code in ObjC / Java, and then compiles it yourself into the same native code.
Can I use NPM packages?- Yes, you can. For this, a third-party utility is used, which forces the Fuse compiler to take the NPM package into the bundle.
Is HotReload supported?- Supported, works very quickly.
Let's start installing Fuse
Go to
fusetools.com and download the installer for your OS: Mac / Windows. I think about how to press the button “I agree”, ”Next” is not necessary. We are almost ready to create a project, we will continue:
In the terminal:
fuse create app habr cd habr
For review, we will need Sublime Text / Atom / VS Code, for these editors there are already plugins.
To install sublime plugin:
fuse install sublime-plugin
First run the preview of our project, for this you need to call the context menu on the .ux file and run Preview → Local. Open our habr folder in the subtime and go to MainView.ux. In this file we will see the whole application consisting of the <App> tag. Since I’m talking about animation, let's set this goal:

Interface design
In this case, we don’t need JS, so we’ll completely do without it, but we’ll touch on this topic closer to the end of our review.
We describe the base layout:
<App> <ClientPanel> </ClientPanel> </App>
Now, consider the set of primitives available:
Rectangle, Circle, Text, Image, Video . Choose the ones we need -
Rectangle and
Circle .
Let's move on to a little complicated, creating your own component templates. Fuse has various designs that allow you to describe your layout, use the Class construct.
<Rectangle ux:Class="SnapButton" CornerRadius="30" Margin="10" Color=”#5E2E91”> </Rectangle>
I think everything is clear here, this is a rectangle pattern, indented from all sides by 10 pt, and a rounding of corners of 30 pt.
Place the instance of our template in ClientPanel. As a result, our code will look something like this:
<App> <ClientPanel> <SnapButton ux:Name=”loginButton” Width=”300” Height=”60” /> </ClientPanel> </App>
Add a circle to our SnapButton instance:
<Circle ux:Name="loadingCircle" Width="50%" Height="50%" Opacity="0" StartAngleDegrees="0" LengthAngleDegrees="90"> <Stroke Width="2" Brush="#fff" /> </Circle>
From the above code, it can be seen that our circle is transparent and is not displayed by default, you can also notice that this is not a full circle, but only a quarter of a circle. Inside, we describe the Stroke parameter - stroke, width -2, white color.
Fine! We are ready to start creating animation!
We will write in steps:
- Turn button into circle
- Show our circle
- Start rotation animation
Fuse allows us to describe the triggers, now we will describe the trigger that will trigger the animation of the change in the width of our button:
<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>
From the markup above, you can see that there are two triggers, one with the name loading, which controls the activation of the trigger changeWidth.
The ChangeWidth trigger in turn triggers a change in the Width parameter of an object named loginButton, which is 0.5 seconds long in both directions.
Let's not even ahead and about, we describe the trigger animation of our circle:
<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>
Here we meet
Spin and
Cycle , the first rotates the object with a given frequency, the second performs a cyclic change of the parameter with a frequency, in our case we change the length of our circle from 10 to 300 in 0.7 seconds.
And finally, we will add our new trigger to the loading trigger, after which we will trigger the change of the trigger value by the event of pressing our button.
That's all, we made a pretty beautiful interactive button that can display the status of the application.
The final code will look like this:
<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>
It is worth noting that Fuse supports a huge number of different parameters for creating animations, imposing effects, but let's move on.
The animation is, of course, good. Yes, that's just the application can not write without logic
There are several options, they are all quite raw, which is explained by the state of Fuse - beta, the community is not so big, although they are preparing for open-source.
You can write to EcmaScript5, either in JS files, or within markup. You can enable JS by adding the
<JavaScript File=”file.js” />
. In fact, they give us MVVM and say, well, something like that. Having a little pop, you can achieve integration with ES2015 → Babel → ES5. Exactly the same number of dances will be required for TS integration,
which I described in detail on the fuse forum .
Fuse operates on data using Observabl's, an example of use can be found at the link above. By default, you also have Two-Way Binding.
Let's return to execution of the native code:
Fuse uses the Uno language, more like C #, but providing the ability to decorate methods and parameters with executable languages.
It looks like this:
[Foreign(Language.ObjC)] static float GetValue(ObjC.Object handle) @{ ::UISlider* slider = (::UISlider*)handle; return [slider value]; @}
What do we have in the end?
Developing something serious on Fuse is unlikely to succeed so far, although nothing really hinders. But to create a prototype that you can touch - in my opinion the most it. According to promises, Fuse will be able to export components for use in projects (which, in my opinion, is fine).
References:
→
Official website→
Installing npm packages for the application