protectwise / troika

A JavaScript framework for interactive 3D and 2D visualizations
MIT License
1.61k stars 118 forks source link

Feature: troika-3d-text: text editing #28

Open lojjic opened 4 years ago

lojjic commented 4 years ago

Following on from cursor positioning and text selection (#27, #25), we need text editing.

The big unknown here is how to input text. On screen it should take input from the keyboard just like HTML inputs. (Maybe use a hidden input/textarea behind the scenes?)

In XR, we may need an in-world keyboard. We could also look into utilizing speech-to-text.

michaelybecker commented 3 years ago

We have an interesting (and somewhat unique) use case where we can't actually use html elements due to the way we leverage iFrames to composit multiple XR scenes (or "apps") - meaning, input processing has to be done at the keydown level and I have to capture inputs like newline and backspace manually and somewhat gruesomely. That said, a hidden textarea is indeed a great solution for general-purpose WebXR (I've tested it as one of the approaches - broke in our multiapp implementation but works as a standalone WebXR app).

One thing that currently eludes me is caret implementation, which might be beyond the scope of this library or support you're willing to offer. The helper methods are - well, helpful - particularly for raycasting and mapping texture x/y to char index, but I'm not familiar with the basic way to implement carets (that presumably represent an index in the string, etc? But how is it typically superimposed on the actual text? I don't imagine it just exists in the string at a certain location? Knowledge gap on my end, here.).

It's not a blocker for what I'm working on, but in terms of developing a nice-feeling, functional text editor in VR, this is the main missing feature at this moment; everything else is extremely well supplied by troika-3d-text (by the way, plug-and-playing .ttfs that just work out of the box with no conversion needed is such a great QoL touch!)

lojjic commented 3 years ago

@MichaelHazani Ahh your multiapp scenario is indeed very interesting! I'd struggled coming up with examples of DOM-less environments but that's definitely a good one. Something I'll keep in mind.

By "caret implementation" are you talking about the actual rendering of a visible caret? If so, I think that's definitely in scope, or soon will be. I imagine it would be very similar to text selection (the rendering of selection rects is coming soon as part of #110) where it's a separate geometry added as a child of the Text object. The getSelectionRects helper function could be passed equal start/end values to give you a zero-width rect that is the caret position, and then you just move your caret object to that position...?

michaelybecker commented 3 years ago

Yes! That's exactly what I had in mind. And, similarly to curved UI, not something I'd have considered a potential feature - the pleasant surprises keep piling up:). Text selection and visible caret would be wildly useful, for multiple use cases I imagine. The features mentioned in that PR sound great in general.

As an unrelated $0.02: I fully agree with Mr. d00b's comment elsewhere - referring to this solution somewhere in the threejs docs is highly worthwhile. It saddens me to think anyone would waste time on texturizing canvases or using any other suboptimal solution due to not being aware of troika-3d-text. One low-overhead way to get more visibility and awareness is to add this library as another option in the adding text page. In light of the general enthusiasm around this solution I think it would get easily approved, and might be less contentious or tricky than a more formalized solution (like integrating troika-3d-text into three).

lojjic commented 3 years ago

add this library as another option in the adding text page

Thanks for the +1 on that idea. I've opened: https://github.com/mrdoob/three.js/pull/21708