Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'm not especially familiar with Three.js, but here's the usual steps:</p> <ul> <li>Choose a point on the surface of your object you want to align the label to.</li> <li>Use <code>projector.projectVector</code> to get an on-screen point from the in-world point.</li> <li>(You may need to scale the result from NDC (-1 to 1) to canvas (0 to canvas.width) coordinates here; I'm not sure.)</li> <li>Use the X and Y to set CSS absolute positioning for your label.</li> </ul> <p>Here's code I wrote to do the same thing in my <a href="https://github.com/kpreid/cubes">Cubes</a> project (not using Three.js, but the principles are the same). It is slightly more complex because what it does is position the element so that it is <em>next to</em> an object represented by a set of points (which are provided to the callback passed to <code>pointGenerator</code>). It also tries to do sensible things when the object is out of view of the camera.</p> <p>Feel free to reuse this code and adapt it to your liking.</p> <pre><code>// Position an overlay HTML element adjacent to the provided set of points. function positionByWorld(element, keepInBounds, pointGenerator) { var canvasStyle = window.getComputedStyle(theCanvas,null); var canvasWidth = parseInt(canvasStyle.width, 10); var canvasHeight = parseInt(canvasStyle.height, 10); var elemStyle = window.getComputedStyle(element, null); var elemWidth = parseInt(elemStyle.width, 10); var elemHeight = parseInt(elemStyle.height, 10); var slx = Infinity; var sly = Infinity; var shx = -Infinity; var shy = -Infinity; var toScreenPoint = vec4.create(); pointGenerator(function (x, y, z, w) { toScreenPoint[0] = x; toScreenPoint[1] = y; toScreenPoint[2] = z; toScreenPoint[3] = w; renderer.transformPoint(toScreenPoint); toScreenPoint[0] /= toScreenPoint[3]; toScreenPoint[1] /= toScreenPoint[3]; toScreenPoint[2] /= toScreenPoint[3]; if (toScreenPoint[3] &gt; 0) { slx = Math.min(slx, toScreenPoint[0]); shx = Math.max(shx, toScreenPoint[0]); sly = Math.min(sly, toScreenPoint[1]); shy = Math.max(shy, toScreenPoint[1]); } }); if (shx &gt; -1 &amp;&amp; shy &gt; -1 &amp;&amp; slx &lt; 1 &amp;&amp; sly &lt; 1 /* visible */) { // convert to screen slx = (slx + 1) / 2 * canvasWidth; //shx = (shx + 1) / 2 * canvasWidth; //sly = (sly + 1) / 2 * canvasHeight; shy = (shy + 1) / 2 * canvasHeight; if (keepInBounds) { slx = Math.max(0, Math.min(canvasWidth - elemWidth, slx)); shy = Math.max(0, Math.min(canvasHeight - elemHeight, shy)); } element.style.left = slx + "px"; element.style.bottom = shy + "px"; } else { element.style.left = canvasWidth + "px"; } } </code></pre> <p>—<a href="https://github.com/kpreid/cubes/blob/5a26a35769734a50140a39638ff7e008544b943b/main.js#L107">Permalink on GitHub</a></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload