How can I make a responsive canvas?

Hello, I’m a brand new Armory3D user and was wondering how to make a responsive UI with canvases for Android devices?

I noticed that if the resolution of the device changes, everything is moved or worse, the UI goes out of sight.
I’ve try this: How to make the HTML5 responsive?
But it doesn’t seem to work for canvas.

How can I proceed?

Hi and welcome :slight_smile:

By default, all positions of UI elements are relative to the top left corner. If you want to change this, you can choose a different anchor in the UI editor:

Screenshot

The positions will then be relative to whatever corner you selected. Note that the UI editor has some bugs in that regard, if you zoom out, the anchor positions are incorrectly displayed.

You can also use the following logic nodes:

With Set Canvas Scale, you can set the dimensions (width and height) of a single element.
With Set Global Canvas Scale, you can scale the entire canvas.
With Set Global Canvas Font Size you can set the font size.

Apart from that, Armory’s canvas unfortunately does not have many features for responsive layouts. Either you need to use different UI libraries (HaxeUI, Koui, …) for which you need to use Haxe, or you need to set the positions and sizes dynamically via logic nodes, for example responding to the window size (Get Window Resolution node).

2 Likes

Thanks for telling us that this could work. However, the only example i found is by ziglag from 2019 and i could not get that to work. Could someone post a recent and working HaxeUI example, please. HaxeUi is from Ian Harrigan and i also tried the websockets from him to no avail.

The problem i have with external libraries in general is the following. The headers have to be adapted in a certain way which i could nowhere find explained. Else you get errors like a flood of “type not found” and a “*.hx should be package” error. But i don´t know how to get rid of them. What are the underlying rules?

package arm;

import haxe.ui.Toolkit;
import haxe.ui.components.*;
import haxe.ui.core.Component;
import haxe.ui.core.Screen;
import haxe.ui.macros.ComponentMacros;
import haxe.ui.core.UIEvent;

There seems to be a directory structure hidden in these import expressions. Why is it not separate? This is a pain to edit block wise, especially for a trial and error approach.

I just tried an old example of mine from early 2020 (with updated HaxeUI, the old versions no longer compile), and unfortunately I couldn’t make it work on Krom where it fails with error messages because it tries to access browser stuff (Krom is JS) that doesn’t exist in Krom. However, on Html5 and probably also Hashlink it works (after adding a workaround for a Haxe bug I found).

In general, the Kha backend of HaxeUI seems to have some problems, limited support for the CSS attributes that are supported by other backends, and HaxeUI seems to be a bit over-engineered sometimes (although you can do a lot with it, it’s a powerful library). But I haven’t used much of it, so I can’t tell you much about it. However, that was the reason why I wrote my own UI library a while ago. Zui was too limiting and HaxeUI too complex and error-prone.

As for websockets: if you’re on the Discord server, take a look at the #armory-dev channel, someone is currently implementing networking nodes with hxwebsockets. I’m not sure whether it works in Krom though.

Usually you don’t need to change any package headers. As long as a library is included in the build, you can import it as stated in its API. So import haxe.ui.Toolkit for example should work without any problems as long as you correctly “installed” HaxeUI. If you have any specific errors then maybe create a new forum thread for them or ask on Discord.

Yes, the imports follow the directory structure, although I think it’s mostly by convention. If I’m not mistaken then you can choose the package of each module freely as long as it is also reflected in the corresponding import statements. I’m not sure what exactly you mean with “separate”, you mean that you want to do import Toolkit instead of import haxe.ui.Toolkit? How would you solve situations where two libraries have a Toolkit module or class?

1 Like