Utilizing the CSS2DRenderer in THREE.js to accurately place HTML elements starting from the top left corner

The CSS2DRenderer feature allows for the positioning of an HTML element within a 3D scene based on specific coordinates, which can be associated with an object in that scene. For instance, you could execute:

const mesh; // <some other mesh in the scene>

const el = document.createElement('div')
el.innerHTML = 'hello world'
const objectCSS = new CSS2DObject(el)
objectCSS.position.set(0, 0, 0)

mesh.add(objectCSS)

By doing this, the hello world div will be placed directly at the center of the mesh, like so:

_________________
|               |
|  hello world  |
|_______________|

Is there a way to adjust the position of the hello world div so that it aligns with the top left corner of the div, rather than its center? For example:

 _________________
|               |
|       hello world  
|_______________|

EDIT: It's important to note that the intention here is not only to shift the text. The goal is to alter the alignment. Simply offsetting the text would result in something like this:

_________________
|               |
|  hello world blah blah blah
|_______________|

Whereas changing the alignment would yield:

_________________
|               |
|       hello world blah blah blah
|_______________|

Answer №1

I encountered a similar issue. Specifically, I noticed that either Line 131 or Line 135 in the CSS2DRenderer applies the transform translate(-50%,-50%) to center the HTML element around the specified position. One potential solution could be to introduce some flexibility in this process by allowing for additional arguments when creating the CSS2DObject. Perhaps suggesting an optional parameter? Would it be worthwhile to submit a Pull Request for this change?

Answer №2

While working through a similar issue, I stumbled upon the center property in CSS2DObject.

By following this code snippet:

const element = document.createElement('div');
element.textContent = `Content to display in the div`;

element.className = 'ADD_OPTIONAL_CSS_CLASSES_HERE';

element.style.left = '50px'; // positioning works

const objectCSS = new CSS2DObject(element);
objectCSS.center.x = 0;
objectCSS.center.y = 0;

I was able to achieve my desired outcome, which involved aligning the top left corner of the div with the screen coordinates of a 3D point.

In this scenario, an additional offset of 50px was applied using element.style.left. This step can be omitted if only the top left alignment is required, as it's included here for illustrative purposes.

Update: Additionally, by setting:

objectCSS.center.x = 1;
objectCSS.center.y = 1;

Your div will be aligned to the bottom right corner.

Answer №4

If you're looking to improve the structure, one solution could be inserting a container in between the css2dObject parent and the content. Here's an example:

<div class="css2dObject">
    <div class="container" style="transform: translate(50%, 50%)"><!-- new addition -->
        <div class="content">...</div>
    </div>
</div>

This added container effectively negates the translate(-50%,-50%) previously set by the css2drenderer on the css2dObject. While this is a temporary fix, I do agree with @Jonathan Davidson that a cleaner solution should be pursued. Perhaps I'll work on a PR for this when time permits.

Answer №5

For achieving my goal, I utilized nested div containers in my code implementation. The final version of my code looked something akin to the following:

const mesh; // <some other mesh in the scene>

// Create necessary HTML elements.
const el = document.createElement('div')
const container = document.createElement('div');
const inner = document.createElmeent('div');

// Applying styles.
container.style.display = 'flex'
container.style.flexDirection = 'column'
container.style.width = 'fit-content'  // Used for resetting width calculations

// Assigning text content.
inner.innerHTML = 'HELLO WORLD'

// Configuring the remaining THREE object components.
const objectCSS = new CSS2DObject(el)
objectCSS.position.set(0, 0, 0)
objectCSS.element.style.overflow = 'visible'
objectCSS.element.style.width = '1px'  
objectCSS.element.style.height = '1px'

mesh.add(objectCSS)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best approach to decipher an obfuscated JavaScript file?

While browsing a site, I came across a javascript file that appears like this: eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,Str ...

The removeEventListener method in JavaScript fails to function properly

On my website, I have a unique feature where clicking an image will display it in a lightbox. Upon the second click, the mouse movement is tracked to move the image accordingly. This functionality is working as intended, but now I'm faced with the cha ...

Java has trouble decoding non-ASCII characters sent through Ajax

When I send an AJAX request using jQuery post() and serialize, the encoding used is UTF-8. For instance, if 'ś' is input as a name value, JavaScript displays name=%C5%9B. Despite my attempts to set form encoding, it has not been successful. < ...

The jQuery formvalidator plugin for file validation isn't functioning as expected

I am attempting to validate the file type input using the formvalidator.net plugin, however, I am not seeing any errors. What could be wrong with the code below? It is functioning properly for other types of input. Here is an example of what I am trying: ...

Different placeholder text rendered in two text styles

Can an input box placeholder have two different styles? Here's the design I have in mind: https://i.stack.imgur.com/7OH9A.png ...

Utilize Jquery to send a preset value through an ajax request

I am working on a select box functionality where the selected option is sent via ajax to a server-side script. The current setup is functioning properly. Here is the code for the select box: <select id="main_select"> <option selecte ...

JS Unable to get scrollIntoView function to work with mousewheel event

I have been working with the script provided above. It correctly displays the id in the browser console, but unfortunately, it is not triggering the scrolling function as expected. var divID = null; var up = null; var down = null; function div(x) { s ...

Determine whether child components in React Native contain additional child elements

I'm facing an issue while trying to determine if the children (AssetExample2) of my parent (AssetExample) component have their own children. The goal is to use this logic for the splash screen of my app to hide it once the children have loaded. Howeve ...

What is the best way to implement a seamless left-to-right sliding effect for my side navigation using CSS and Javascript?

I am currently working on creating a CSS and JavaScript side navigation. Below is the code that I have implemented so far: var nav = document.getElementById('nav'); function show(){ nav.style.display = "block"; } .side-nav{ background-color:bl ...

Error in IONIC 3: The code is unable to read the 'nativeElement' property due to an undefined value, resulting in a TypeError

I am currently learning about IONIC 3 and working on an app that utilizes the Google Maps API. However, when I try to launch my app, I encounter the following error message: inicio.html Error: Uncaught (in promise): TypeError: Cannot read property ' ...

Optimizing HTML, CSS, and JS files through minification

During my research on various minification techniques used by different websites, I noticed that most sites employ JS minification, concatenation, and bundling all JS files into one, which I believe is a good practice. However, CSS and HTML minification s ...

The issue with mapDispathToProps is that it is failing to assign a function

import React, { Component } from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; import { ShelfModal } from "./shelf-modal"; import { openShelfModal } from "../../../redux/actions/shelf-modal"; export class ShelfTest ex ...

What is the best way to update my component when the selected value is changed?

Currently, I am facing an issue with my map component. It plots polyline data based on the option selected from the select menu component. The problem arises when I change the value in the select menu and click the play button for the animation. Instead of ...

Posting photos to MongoDB using Node.js and Express

I am currently facing an issue while attempting to upload an image using multer in Node.js. I have configured multer to save the uploaded images in the "upload" directory, and upon form submission, the image is successfully sent to the directory. However, ...

Having trouble with executing dual actions in React, causing state to behave incorrectly

Within a component, I am faced with the challenge of dispatching two distinct actions from two separate reducers that update different states within my application. Below is some excerpt of the code snippet for the said component: onSubmit = e => { ...

Spinning divs using JavaScript when the mouse hovers over them, and then returning them to their original position when the mouse moves

I am looking to create a functionality where a div rotates when the mouse enters it and returns to its original position when the mouse leaves. Everything works fine when interacting with one div, but as soon as I try hovering over other divs, it starts gl ...

The key to creating efficient routers in Express: Don't Repeat Yourself!

Currently, I am in the process of developing a web application in the form of a network structure that involves basic CRUD operations. However, I am facing the issue of having overly large router files, prompting me to consider splitting them up. One of t ...

When using CSS media queries and Javascript, the menu behaves differently on desktop compared to mobile devices. While it works well on

Encountering a difficulty with CSS media queries and a UL tag involving two menus (left and right) along with a search bar. The issue arises when the right menu goes off screen on desktop, even though it works correctly on mobile. When users activate the m ...

Exploring Vue.js: Accessing nested elements

Trying to convert this to vuejs has presented some challenges. First off, How do I access nested sub elements? <div ref="tickerwrapper" class="tickerwrapper"> <ul ref="list" class='list'> <li re ...

When comparing TypeScript class functions with regular functions and variables, which one yields better performance?

When it comes to defining functions, is it better to use variables or functions directly? Also, how does this affect tree-shaking? I am dealing with a lot of calculation-intensive helper classes and I am unsure about the optimal approach in terms of memor ...