Coder Social home page Coder Social logo

bryik / aframe-bmfont-text-component Goto Github PK

View Code? Open in Web Editor NEW
62.0 6.0 15.0 704 KB

A-Frame component for rendering bitmap fonts.

Home Page: https://bryik.github.io/aframe-bmfont-text-component/

License: MIT License

JavaScript 100.00%
aframe text sdf threejs

aframe-bmfont-text-component's Introduction

This is an old component! A-Frame 0.5.0 and up includes SDF text as a standard component. Use that instead!


aframe-bmfont-text-component

Works with A-Frame version 0.3.0.

This component is useful for rendering bitmap and signed distance field font text in A-Frame. Basically, it wraps Matt DesLauriers' three-bmfont-text and load-bmfont.

screenshot

Properties

Property Description Default Value
text the text you want to appear None
width width of the text box None
align 'left', 'center', 'right' left
letterSpacing the letter spacing in pixels 0
lineHeight the line height in pixels 38
fnt path to 'fnt' file https://...
fntImage path to font image file https://...
mode 'pre' and 'nowrap' 'normal'
color by RGB, hex, or name #000
opacity Extent of transparency. 1.0

More details on these properties here.

Explanation of 'mode' property here.

Usage

Write some text:

<a-entity bmfont-text="text: Hello World;"></a-entity>

To change the size of the text, use the scale component or position the text closer or further away.

Text can be wrapped by specifying width, but I'm not sure what units three-bmfont-text uses. You will have to play around a bit.

Custom Fonts

A guide for generating SDF fonts can be found here; here is an example comparing Arial Black and DejaVu. Bitmap fonts also work, but do not look nearly as good.

Different fonts can be specified with the 'fnt' and 'fntImage' properties.

<a-entity bmfont-text="text: Hello World; fnt:../fonts/DejaVu-sdf.fnt; fntImage:../fonts/DejaVu-sdf.png">
</a-entity>

Thanks to jsDelivr, these default to hosted "DejaVu-sdf.fnt" and "DejaVu-sdf.png" files.

Limitations

This component does not make use of all of the features of three-bmfont-text and its sister modules, if you require more advanced functionality such as tabSize and start and end indices, I recommend forking this component and modifying it. Pull requests are welcome, but please include a test example.

Bitmap font rendering limits you to the characters included in the font (Unicode this is not). SDF font (in particular) tends to smooth sharp edges though there are ways around this.

Additional Information

If you are interested in text rendering in WebGL/ThreeJS/A-Frame and want to learn more, I recommend reading the documentation for three-bmfont-text.

Here are some additional resources:

Installation

Browser

Install and use by directly including the browser files:

<head>
  <title>My A-Frame Scene</title>
  <script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script>
  <script src="https://cdn.jsdelivr.net/gh/bryik/aframe-bmfont-text-component@e041ead91a309c924408087a0f7aef0cb870e2f9/dist/aframe-bmfont-text-component.min.js"></script>
</head>

<body>
  <a-scene>
    <a-entity bmfont-text="text: Hello world"></a-entity>
  </a-scene>
</body>

NPM

Install via NPM:

npm install aframe-bmfont-text-component

Then register and use.

require('aframe');
require('aframe-bmfont-text-component');

aframe-bmfont-text-component's People

Contributors

bryik avatar ngokevin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

aframe-bmfont-text-component's Issues

Can't dynamically change the attribute's value

I'm registering a component in A-Frame where I want to be able to change the text dynamically
data.target.setAttribute('bmfont-text', 'text:'+weather.city)
The attribute bmfont-text gets created but there's no value being assigned to it.

Embedding in Wordpress

I am attempting to embed an aframe scene into my wordpress template, but so far I have had no luck. I keep getting an error "Cannot read property 'removeBehavior' of null". I saw an earlier issue that mentioned rocketscript breaking the javascript so I did a bit of research and added code to functions.php to disable rocketscript loading for the aframe.min.js script. This didn't fix anything sadly. I get the error 5 times when the page loads, it is reported from material.js file at line 79:

if (Object.keys(tickProperties).length === 0) {

  scene.removeBehavior(this);

}

Does anyone have any input on this? It looks to me that scene is not being set correctly.

The code I am embedding is just the hello world stuff straight from the a-frame site:

  <a-sphere position="0 1.25 -1" radius="1.25" color="#EF2D5E"></a-sphere>

  <a-box position="-1 0.5 1" rotation="0 45 0" width="1" height="1" depth="1"  color="#4CC3D9">
  <a-cylinder position="1 0.75 1" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>

  <a-plane rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>

  <a-sky color="#ECECEC"></a-sky>

  <a-entity position="0 0 3.8">

    <a-camera></a-camera>

  </a-entity>

Does this work with aframe react?

I am trying to implement this with AFrame React but not sure how to do it properly.

tried this:

<Scene antialias="true" >
    <Entity
                        bmfont-text={`text: Hello World;
                        fnt:${BASE_URL}assets/fonts/bmp/frutiger-light-45.fnt;
                        fntImage:${BASE_URL}assets/fonts/bmp/frutiger-light-45.png;
                        color:#ffffff;
                        width:50;
                        align:center;`}
                        position="50 50 50"
                        ></Entity>
</Scene>

and this with the primitive

<Scene antialias="true" >
    <a-entity
                        bmfont-text={`text: Hello World;
                        fnt:${BASE_URL}assets/fonts/bmp/frutiger-light-45.fnt;
                        fntImage:${BASE_URL}assets/fonts/bmp/frutiger-light-45.png;
                        color:#ffffff;
                        width:50;
                        align:center;`}
                        position="50 50 50"
                        ></a-entity>
</Scene>

Text primitive is terribly buggy

Thing I've noticed:

  • color failing to override default (text is black regardless of color attribute)
  • mixing text primitive and regular a-entity with bmfont-text component fails sometimes (primitive will not appear)
  • multiple text primitives in a single scene can cause some or all text to not appear

Using play() instead of update() does help with the first issue. However, it breaks setAttribute?

Position of text feels offset compared to normal entities position

If I create a basic cube and place it at position="0 0 -5" and then do the same thing with a bmfont-text element and adjust its position to the same position="0 0 -5" and add align:center the text is not perfectly in the center of the cube as would be assumed. I've tried other alignments as well and all shift the text to the right of the cube. Adding position = "-2 0 -5" compensates for the offset but if I change my text or make it longer I have to readjust that offset on position.x

I guess my question is, is there a defined offset that I can just input to compensate for this shift or what would be the best way to center text in front of a camera that is located at "0 0 0"

Thanks

Way to cache fntImage?

Is there a way to use an earlier asset without having to fetch a new fntImage every time a bmfont text is used? For example, would it be possible to have fntImage point to something in ?

MSDF Shader

Three-bmfont-text has a new shader that may produce sharper results! Will need to try this out.

Placement with variable length text.

It appears the component is being placed based on middle coordinate. This is an issue when the text can be of varying length. The more lines rendered the top line move higher in the scene. This isn't ideal when the text needs to be displayed with the top line at a specific position.

Would it be possible to add a height attribute?

Issue when deployed on remote server?

I am having an issue when I deploy it to a remote server through cloudflare using SSL.
So when I run the code on my local desktop then everything works as expected; I can run the pre-mode demo successfully.
However, if I deploy the same code on a remote ubuntu 14.04 server and open it using the same chrome browser on local desktop then just an empty screen with a VR button is displayed.
Curiously, if I view the same page on the remote server on my android device, everything works successfully.
I uploaded the code here https://apps.jpatrickpark.com/lsl/

These are the error messages I received on desktop chrome browser:

Uncaught (in promise) TypeError: Cannot read property 'addEventListener' of null
at s.init (https://aframe.io/releases/0.3.0/aframe.min.js:69:591)
at s.updateProperties (https://aframe.io/releases/0.3.0/aframe.min.js:143:2661)
at new s (https://aframe.io/releases/0.3.0/aframe.min.js:143:3586)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:3855)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:5048)
at e (https://aframe.io/releases/0.3.0/aframe.min.js:135:4639)
at Array.forEach (native)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:4855)
at t (https://aframe.io/releases/0.3.0/aframe.min.js:135:3097)
at eval (https://aframe.io/releases/0.3.0/aframe.min.js:139:1196)
material.js:79

Uncaught (in promise) TypeError: Cannot read property 'removeBehavior' of null
at s.updateBehavior (https://aframe.io/releases/0.3.0/aframe.min.js:87:1450)
at s.updateSchema (https://aframe.io/releases/0.3.0/aframe.min.js:87:1141)
at s.updateProperties (https://aframe.io/releases/0.3.0/aframe.min.js:143:2461)
at new s (https://aframe.io/releases/0.3.0/aframe.min.js:143:3586)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:3855)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:5048)
at e (https://aframe.io/releases/0.3.0/aframe.min.js:135:4639)
at Array.forEach (native)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:4855)
at t (https://aframe.io/releases/0.3.0/aframe.min.js:135:3097)

Uncaught (in promise) TypeError: Cannot read property 'addEventListener' of null
at s.init (https://aframe.io/releases/0.3.0/aframe.min.js:69:591)
at s.updateProperties (https://aframe.io/releases/0.3.0/aframe.min.js:143:2661)
at new s (https://aframe.io/releases/0.3.0/aframe.min.js:143:3586)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:3855)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:5048)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:5199)
at a-entity.value (https://aframe.io/releases/0.3.0/aframe.min.js:135:6335)
at r.setActiveCamera (https://aframe.io/releases/0.3.0/aframe.min.js:246:1589)
at s.update (https://aframe.io/releases/0.3.0/aframe.min.js:69:982)
at s.updateProperties (https://aframe.io/releases/0.3.0/aframe.min.js:143:2693)

Point package.json to dist/

Trying your project from NPM with Browserify. It says object-assign could not be found.

To make the build more consumable, change index to point to dist/ build in package.json.

Animating opacity crashes WebGL after looping a few times

Adding the following animation as a child of the bmfont-text component causes webGL to crash with

'GL_INVALID_OPERATION: glGenSyncTokenCHROMIUM: fence sync must be flushed before generating sync token'

followed by

'WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost'

and 'THREE.WebGLShader: gl.getShaderInfoLog() vertex null 1: precision highp float;

<a-animation attribute="bmfont-text.opacity" from="0.8" to="0.3" dur="500" repeat="indefinite" easing="linear" direction="alternate"> </a-animation>

For me it crashes after ~45 seconds.

webgl-snag

THREE.WebGLShader: Shader couldn't compile.

Hi.

Some Android phones, as Galaxy S5 Mini, throws this exeption on runetime:

THREE.WebGLShader: Shader couldn't compile.
WebGLShader @ aframe.js:37965
WebGLProgram @ aframe.js:37454
acquireProgram @ aframe.js:37868
initMaterial @ aframe.js:34193
setProgram @ aframe.js:34357
renderBufferDirect @ aframe.js:33358
renderObjects @ aframe.js:34125
render @ aframe.js:33882
render @ aframe.js:66733
value @ aframe.js:62886
aframe.js:37488 THREE.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders ERROR: 0:4: 'highp' : precision is not supported in fragment shader

WebGLProgram @ aframe.js:37488
acquireProgram @ aframe.js:37868
initMaterial @ aframe.js:34193
setProgram @ aframe.js:34357
renderBufferDirect @ aframe.js:33358
renderObjects @ aframe.js:34125
render @ aframe.js:33882
render @ aframe.js:66733
value @ aframe.js:62886

Actually i really don't need to fix the bug, but in first, at least make some programatically test. So i decided to make some like this:

function pixelShaderSupport() {
  console.log("Checking pixel shader...");
  var support = true;
  try {
    var textTry = '<a-scene><a-entity style="display: none;" class="animate" id="textTry" rotation="0 0 0" scale="1 1 1" position="1 1 1" bmfont-text="color: white; mode: pre; text: tmp" look-at="[camera]"></a-entity></a-scene>';
    $('body').append(textTry);
  } catch (error) {
    if (error)
      {
        console.log("Your device doesn't support the bmfont-text shader...");
        support = false;
      }
  }
  return support;
}

But is not throwing, i think because the shader itself is not running.

Any way to fix or to prevent test this exception?

Thanks,

Version releases

Compatibility with A-Frame v0.2.0 was broken with the last release (custom primitive?). So this would be a good idea going forward.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.