Opened 2 years ago

Closed 2 years ago

# Allow longer text in Three.js viewer

Reported by: Owned by: Joshua Campbell minor sage-9.2 graphics threejs text length clipping Paul Masson Joshua Campbell Paul Masson N/A a574963

### Description

There's currently a limit to the length of text that can be displayed in the Three.js viewer before the text starts getting clipped at either end.

I've updated threejs_template.html so that the dimensions of the underlying texture are set based on the fontsize and length of the text instead of being hard-coded to 128x32 pixels.

I made sure to keep the pixel scaling intact and to continue using powers of two for the dimensions to prevent the text from becoming blurry. I also tried to keep the resulting size of the text onscreen the same before and after the change with some scale factors.

Tested on Ubuntu 18.04 using a standard display as well as on Windows 10 using a high-DPI display.

### comment:1 Changed 2 years ago by Joshua Campbell

Branch: → u/gh-jcamp0x2a/29758-threejs-text-clipping → eabeb5e3df9a80169c75b278112d8adb3ac2c1e0 new → needs_review

An example that would result in clipping before:

p1 = text3d("Hello world, how are you doing today?", (10, 20, 30))
p2 = text3d("Just fine! Thanks for asking!", (-30, -20, -10))
show(p1 + p2, projection='perspective')


### comment:2 Changed 2 years ago by Joshua Campbell

Cc: Paul Masson added

Apologies Paul, I neglected to CC you on this when creating the ticket.

### comment:3 Changed 2 years ago by Paul Masson

This is a good feature to add! Since you're touching the rescaling, this is also a good time to remove it. Recent versions of Three.js have a sizeAttenuation that can be set to false on SpriteMaterial to prevent scaling with distance. I had planned to activate that feature at some point and this is a good ticket for it. The vector scratch is only there for scaling so you can remove it as well.

### comment:4 Changed 2 years ago by Paul Masson

You may also want to wait till the next beta to resolve the MathUtils issue.

### comment:5 Changed 2 years ago by Joshua Campbell

I'll look into sizeAttenuation so I can incorporate it into this branch once MathUtils is there. May help out a bit in performance for animation, too, since there's a lot more objects in the scene the rescaling is currently looping over.

### comment:6 Changed 2 years ago by Paul Masson

When using sizeAttenuation the scale of the sprite needs to be decreased by something like a factor of 1/4. Need to look into the source code to figure out why...

Also since you have the proper equipment, please make sure #24601 doesn't resurface in the context of these changes. Thanks!

### comment:7 Changed 2 years ago by git

Commit: eabeb5e3df9a80169c75b278112d8adb3ac2c1e0 → a574963aaba4ba75b01b6de453c308bbe1daee8f

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

 ​a574963 Fix clipping of long text in Three.js viewer

### comment:8 Changed 2 years ago by Joshua Campbell

I've updated the branch to work with the new version of Three.js (r117) as well as to use sizeAttenuation=false instead of resizing every frame. The scaling factors were also adjusted to keep the text size consistent before and after this change.

### comment:9 follow-up:  11 Changed 2 years ago by Paul Masson

Status: needs_review → positive_review

Works as described, so positive review. It did get me thinking as to how we could support multiline text since fillTextwon't do that directly. Would have to parse the string for line breaks and write on different parts of a taller canvas. Interested in adding that?

### comment:10 Changed 2 years ago by Paul Masson

Reviewers: → Paul Masson

### comment:11 in reply to:  9 ; follow-up:  16 Changed 2 years ago by Joshua Campbell

Works as described, so positive review. It did get me thinking as to how we could support multiline text since fillTextwon't do that directly. Would have to parse the string for line breaks and write on different parts of a taller canvas. Interested in adding that?

Thanks Paul. That seems like a good addition, and I'll look into doing so. I also want to be able to pass in the text size from the Python so we can make use of that fontsize parameter in addLabel.

### comment:12 Changed 2 years ago by Volker Braun

Branch: u/gh-jcamp0x2a/29758-threejs-text-clipping → a574963aaba4ba75b01b6de453c308bbe1daee8f → fixed positive_review → closed

### comment:13 Changed 2 years ago by Samuel Lelièvre

Commit: a574963aaba4ba75b01b6de453c308bbe1daee8f

### comment:14 Changed 2 years ago by Joshua Campbell

I'm not aware of an existing ticket, nor could I find one with a quick search, but this is something I've also been contemplating recently.

The MathJax? library seems to be already included in Sage and the Jupyter notebook, so I don't think it would be much effort to get some LaTeX rendered on the page. The problem is getting it rendered in the scene so that it moves around / rotates / zooms with everything else in the scene.

We'd need an HTML canvas or a raster image that can be drawn on an HTML canvas in order to put the text in the scene, but with my current understanding of MathJax? (admittedly little), it doesn't support either of those as output formats.

It does support SVG output, though, so perhaps we have a chance of then rendering that into a canvas using an approach like this. There's also the html2canvas library that might be able to go straight from the MathJax? HTML output to canvas as mentioned in this StackOverflow answer.

I'll do some more research into it and see if I can get a working example going.

### comment:15 Changed 2 years ago by Samuel Lelièvre

Thanks! I opened #30226.

### comment:16 in reply to:  11 Changed 2 years ago by Joshua Campbell

Works as described, so positive review. It did get me thinking as to how we could support multiline text since fillTextwon't do that directly. Would have to parse the string for line breaks and write on different parts of a taller canvas. Interested in adding that?
Thanks Paul. That seems like a good addition, and I'll look into doing so. I also want to be able to pass in the text size from the Python so we can make use of that fontsize parameter in addLabel.
Sorry for replying to an old ticket, but for completeness's sake: the fontsize parameter is being made use of as of #30614.