facebookarchive / react-360

Create amazing 360 and VR content using React
https://facebook.github.io/react-360
Other
8.73k stars 1.23k forks source link

[Question] Rendering Icon fonts #288

Open hggeorgiev opened 7 years ago

hggeorgiev commented 7 years ago

How would you approach adding font icon support (such as Font Awesome, Material Icons etc) for React VR? I'm not considering .png, because we all know .png isn't scalable in all the meanings of the word.

I noticed that you're using GlyphTextures to render the video player icons. It uses a registerGlyph method to create a canvas, draw a set of primitive lines, and then send them over to the TextureManager which I suppose runs in the web worker and makes it available in the view.

Option 1: I was thinking of using an icon font set (Font Awesome for instance) and putting it through a similar process - rendering an icon on a canvas and then sending it to the TextureManager.

Option 2: I was also wondering if it's a better idea to use the approach you used with the text fonts, but I'm not sure how you convert .ttf, .woff, etc to .fnt and generate the pngs. Maybe you're using Fontue? It also seems a bit vague to me how I'd use two fonts at once in the same application.

Option 3: Lastly, I thought of using a custom module, a custom View to render the icon in Three.js directly. However, this comes with its own set of questions and challenges and it may require a lot of boilerplate code just to render icons. Plus, you preferred using canvas to render things like icons and perhaps you had some good reasons to do it.

What's your opinion on this?

hggeorgiev commented 7 years ago

Any ideas on this? I would love to hear the opinion of somebody who's worked on building this part of React VR

RadValentin commented 6 years ago

If all you're interested in is getting Font Awesome inside a React VR app, you can generate a SDF version of it using the Fontue tool and then load it inside your vr/client.js.

import {VRInstance} from 'react-vr-web';
import * as OVRUI from 'ovrui';

function init(bundle, parent, options) {
  Promise.all([
    OVRUI.loadFont(),
    OVRUI.loadFont(
      '../static_assets/FontAwesome.fnt',
      '../static_assets/FontAwesome_sdf.png'
    )
  ]).then(([defaultFont, fontAwesome]) => {
    OVRUI.addFontFallback(defaultFont, fontAwesome);

    const vr = new VRInstance(bundle, 'CustomFont', parent, {
      font: defaultFont,
      ...options
    });
    vr.render = function() {};
    vr.start();
  });
}

window.ReactVR = {init};

One key thing to note here is that React VR doesn't support multiple font families, at least not in the sense that you can have an element that uses "Open Sans" and another that uses "Roboto" for example. Instead what you have is a fallback mechanism, in the example above I'm calling OVRUI.loadFont() to load in the default font so when we render a glyph not present in FA (ASCII chars) then that default font will be used.

You can find some examples of this here and here. I've also created a repo with already converted fonts and some converstion steps here.