Nativescript: [Feature request] Use Font Awesome Duotone Style

Created on 3 Dec 2019  ·  12Comments  ·  Source: NativeScript/NativeScript

Is your feature request related to a problem? Please describe.
Font Awesome recently introduced a new style of their awesome icons, the Duotone one where they use 2 separate glyphs stacked on top of each other to allow you to create some really awesome icons in two tones.

Currently, I can't see a way how you can use it with Nativescript.

Describe the solution you'd like
Would be great to be able to use them and to be able to control the opacity/colour of each layer exactly how you can easily do it on the web.
https://fontawesome.com/how-to-use/on-the-web/styling/duotone-icons

Additional context
https://blog.fontawesome.com/introducing-duotone/

feature help wanted

Most helpful comment

@NathanaelA

Here is the directive that uses your fix in an organised way, according to Angular structure.

You can see an example in use on this playground https://play.nativescript.org/?template=play-ng&id=T3S2hi

import { Directive, ElementRef, OnInit } from "@angular/core";
import { Label } from "ui/label";

@Directive({
    selector: "[labelDuoTone]"
})
export class DuoToneDirective implements OnInit {

    constructor(private el: ElementRef) {
    }

    get nativeView(): Label {
        return this.el.nativeElement;
    }

    ngOnInit() {
        const nativeView = this.nativeView;

        if (nativeView instanceof Label) {
            nativeView.on(Label.loadedEvent, () => {
                let val = nativeView.text.codePointAt(0);
                // Check to see if this is already a valid unicode string above 0xffff.
                // If they fix the underlying issue in the future; we don't need to run the rest of the code...
                if (val > 65535) {
                    return;
                }

                // We found a character we need to change...
                val = val | 0x100000;
                nativeView.text = String.fromCodePoint(val);

            });
        }
    }
}

All 12 comments

Nothing yet ?! I need to use FontAwesome 5 DuoTone class for my fonts but the secondary color and opacity doesn't take effect.

@Pandishpan @meikii - NativeScript supports this perfectly fine:
image

However, the issue on mobiles is exactly the same as the font awesome present in their article: https://fontawesome.com/how-to-use/on-the-desktop/referencing-icons/duotone-icons

However, on NativeScript it is trivial to do the alignment as the GridLayout will line things up perfectly...
The code to do this is trivial:

.fad {
  font-family: fa-duotone-900, Font Awesome 5 Duotone;
  font-weight: 900; 
}

// Set to whatever opacity you want the second layer
.fad-op {
    opacity: .4;
}

XML:

 <GridLayout rows="auto" columns="auto,auto,auto">
                <Label text="Font Awesome Duotone Icons" class="normal"/>

                <!-- Acorn -->
                <Label col="1" text="&#xf6ae;" class="larger fad" />
                <Label col="1" text="&#x10f6ae;" class="larger fad green fad-op" />

                <!-- Bird -->
                <Label col="2" text="&#xf520;" class="larger fad blue" />
                <Label col="2" text="&#x10f520;" class="larger fad red fad-op" />
</GridLayout>

Hi @NathanaelA,

Can you please confirm what version of NativeScript did you use to create that example and in what platform are you running it?

I just tested on Android with Nativescript "version": "6.1.2", and I'm not getting the same behaviour ...

image

Although I'm using the right Unicode for the second glyph I'm always getting the first one. (this is a side-by-side column with glyph1 and glyph2)

image

@Pandishpan

  • Using NS 6.4 -- I always use the latest; but I can't think of any changes that could cause issues in 6.1 and fonts, but that is a small possibility... (Update: Tested NS 6.1 and it also worked)

  • Here is the screen shot from the android emulator:
    image

  • Here is the screen shot on the ios Emulator:
    image

I downloaded the latest Font-Awesome web download (also tried the desktop version and it also worked); and copied the fa-duotone-900.ttf into the fonts folder.

Dear Sir,

Thank you for the great sample you provided for me...It would be great if
you put this somewhere so other people just like me can see it...

Nativescript is really awesome but it needs an integrated great
Documentation...It's documentation is not one place...

Thank you again
Mehdi Nourollah

On Sat, Feb 29, 2020 at 11:33 PM Nathanael Anderson <
[email protected]> wrote:

@Pandishpan https://github.com/Pandishpan @Meikii
https://github.com/Meikii - NativeScript supports this perfectly fine:
[image: image]
https://user-images.githubusercontent.com/850871/75614158-74238f00-5afb-11ea-80ab-b4741468ca51.png

However, the issue on mobiles is exactly the same as the font awesome
present in their article:
https://fontawesome.com/how-to-use/on-the-desktop/referencing-icons/duotone-icons

However, on NativeScript it is trivial to do the alignment as the
GridLayout will line things up perfectly...
The code to do this is trivial:

.fad {
font-family: fa-duotone-900, Font Awesome 5 Duotone;
font-weight: 900;
}

// Set to whatever opacity you want the second layer
.fad-op {
opacity: .4;
}

XML:


            <!-- Acorn -->
            <Label col="1" text="&#xf6ae;" class="larger fad" />
            <Label col="1" text="&#x10f6ae;" class="larger fad green fad-op" />

            <!-- Bird -->
            <Label col="2" text="&#xf520;" class="larger fad blue" />
            <Label col="2" text="&#x10f520;" class="larger fad red fad-op" />


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/NativeScript/NativeScript/issues/8162?email_source=notifications&email_token=ABG4MYGU7WBZT3OAJCOJS6TRFFUYTA5CNFSM4JUYCR32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENMETWY#issuecomment-592988635,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABG4MYEREHQF22GNEUU7E4LRFFUYTANCNFSM4JUYCR3Q
.

I created an entire blog article (http://fluentreports.com/blog/?p=1143) and you can download the demo from https://github.com/NathanaelA/fonter

Thank you @NathanaelA for your support to the NS community.
_Most of the people who are using NS + Angular and use the nested routing are sticking to 6.1.2 due to a serious BUG which is already reported https://github.com/NativeScript/nativescript-angular/issues/2075_

Precisely as you said, it should work fine the example with the fonts. However, the issue that I report it is due to using Angular on top of NS.

Take a look on this playground https://play.nativescript.org/?template=play-ng&id=Ye9ZYD
which is based on Angular, you can experience the same problem.
Here is the version based on TypeScript https://play.nativescript.org/?template=play-tsc&id=GwVNSp this one is working perfectly fine.

Do you have any recommendations?

@Pandishpan,

Yep, drop angular (I'm joking! :grinning:). In all seriousness you gave me enough information to understand why you are seeing the issue. Thank you for creating the broken demo...

Angular has its own screen parsing/building code; it does NOT run through the normal NS-Core builder. So that is the difference between the two of them, and the source of the issue.

I honestly have NOT explored the NS-Angular plugin enough to tell you if this broken code is part of the NS-Angular binding/plugin, or actually part of the actual Angular core stuff that NativeScript has no control over. Either way; I do have a work around. :grinning:

This is from Angular, with minor/simple changes to the demo app:
image

So basically when you pass in "&#x10f520;" it is being parsed to only the final 16 bits; and so the "0x100000" is basically being stripped off; leaving it to be "0xf520" which of course is the same symbol as the first character. So my "hack" is to simply read the character and then re-add the 0x100000 back to the character and reset the text value to the new computed value.

So in your HTML you do this:

<!-- Acorn -->
    <Label col="1" text="&#xf6ae;" class="larger fad c-forest"></Label>
    <Label col="1" text="&#x10f6ae;" class="larger fad c-blue fad-op" (loaded)="fixAngularParsingIssue($event)"></Label>

As you noticed, only on the SECOND label (any label that you are using the 10 prefix on); do I add the fixAngularParsingIssue as the loaded event, this will cause this event to fire only once in the lifestyle of the label.

This function is really simple:

fixAngularParsingIssue(args: any): void {
   let field = args.object;
   let val = field.text.codePointAt(0);

   // Check to see if this is already a valid unicode string above 0xffff.
   // If they fix the underlying issue in the future; we don't need to run the rest of the code...
   if (val > 65535) { return; }

   // We found a character we need to change...
  val = val | 0x100000;
  field.text = String.fromCodePoint(val);
}

I expected that you'll say to drop Angular😅 I like your humour @NathanaelA
The workaround looks quite great, futureproof 👍
Thanks again for the explanation lesson, _don't forget to update your blog post I'm pretty sure that there are a lot of Angular Devs using NS._

@Pandishpan - I have already updated the blog post; it was the next thing I did after sending you the solution.

A better design for Angular; would be actually to create a new Directive that does this automatically so then you do <Label /> then <DuoLabel /> and the DuoLabel handles that internally. But I was just trying to give a work around... If someone wants to create a Directive; I will link to it. :grinning:

And I am glad you are off to the races; and able to proceed.

@NathanaelA

Here is the directive that uses your fix in an organised way, according to Angular structure.

You can see an example in use on this playground https://play.nativescript.org/?template=play-ng&id=T3S2hi

import { Directive, ElementRef, OnInit } from "@angular/core";
import { Label } from "ui/label";

@Directive({
    selector: "[labelDuoTone]"
})
export class DuoToneDirective implements OnInit {

    constructor(private el: ElementRef) {
    }

    get nativeView(): Label {
        return this.el.nativeElement;
    }

    ngOnInit() {
        const nativeView = this.nativeView;

        if (nativeView instanceof Label) {
            nativeView.on(Label.loadedEvent, () => {
                let val = nativeView.text.codePointAt(0);
                // Check to see if this is already a valid unicode string above 0xffff.
                // If they fix the underlying issue in the future; we don't need to run the rest of the code...
                if (val > 65535) {
                    return;
                }

                // We found a character we need to change...
                val = val | 0x100000;
                nativeView.text = String.fromCodePoint(val);

            });
        }
    }
}

@Pandishpan - I have updated the blog post to link directly to your code here. Thank you very much for taking the time to make this a lot simpler for everyone using Angular!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kn9ts picture kn9ts  ·  3Comments

fmmsilva picture fmmsilva  ·  3Comments

vtisnado picture vtisnado  ·  3Comments

Leo-lay picture Leo-lay  ·  3Comments

dhanalakshmitawwa picture dhanalakshmitawwa  ·  3Comments