diff --git a/examples/css2d_label.html b/examples/css2d_label.html index ce6a7d10d8777f..85317677784ed6 100644 --- a/examples/css2d_label.html +++ b/examples/css2d_label.html @@ -80,7 +80,7 @@ const MOON_RADIUS = 0.27; camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 200 ); - camera.position.set( 10, 5, 20 ); + camera.position.set( 5, 2, 10 ); camera.layers.enableAll(); scene = new THREE.Scene(); @@ -127,32 +127,37 @@ earthDiv.className = 'label'; earthDiv.textContent = 'Earth'; earthDiv.style.backgroundColor = 'transparent'; + earthDiv.style.border = "1px solid white"; const earthLabel = new CSS2DObject( earthDiv ); earthLabel.position.set( 1.5 * EARTH_RADIUS, 0, 0 ); - earthLabel.center.set( 0, 1 ); + earthLabel.center.set( 0, 1 ); // lower-left earth.add( earthLabel ); earthLabel.layers.set( 0 ); + earthLabel.rotationAngle = Math.PI / 8; const earthMassDiv = document.createElement( 'div' ); earthMassDiv.className = 'label'; earthMassDiv.textContent = '5.97237e24 kg'; earthMassDiv.style.backgroundColor = 'transparent'; + earthMassDiv.style.border = "1px solid white"; const earthMassLabel = new CSS2DObject( earthMassDiv ); earthMassLabel.position.set( 1.5 * EARTH_RADIUS, 0, 0 ); - earthMassLabel.center.set( 0, 0 ); + earthMassLabel.center.set( 0, 0 ); // upper-left earth.add( earthMassLabel ); earthMassLabel.layers.set( 1 ); + earthMassLabel.rotationAngle = - Math.PI / 8; const moonDiv = document.createElement( 'div' ); moonDiv.className = 'label'; moonDiv.textContent = 'Moon'; moonDiv.style.backgroundColor = 'transparent'; + moonDiv.style.border = "1px solid white"; const moonLabel = new CSS2DObject( moonDiv ); moonLabel.position.set( 1.5 * MOON_RADIUS, 0, 0 ); - moonLabel.center.set( 0, 1 ); + moonLabel.center.set( 0, 1 ); // lower-left moon.add( moonLabel ); moonLabel.layers.set( 0 ); @@ -160,10 +165,11 @@ moonMassDiv.className = 'label'; moonMassDiv.textContent = '7.342e22 kg'; moonMassDiv.style.backgroundColor = 'transparent'; + moonMassDiv.style.border = "1px solid white"; const moonMassLabel = new CSS2DObject( moonMassDiv ); moonMassLabel.position.set( 1.5 * MOON_RADIUS, 0, 0 ); - moonMassLabel.center.set( 0, 0 ); + moonMassLabel.center.set( 0, 0 ); // upper-left moon.add( moonMassLabel ); moonMassLabel.layers.set( 1 ); diff --git a/examples/jsm/renderers/CSS2DRenderer.js b/examples/jsm/renderers/CSS2DRenderer.js index 4e350c711fad66..b4b88efb3fe884 100644 --- a/examples/jsm/renderers/CSS2DRenderer.js +++ b/examples/jsm/renderers/CSS2DRenderer.js @@ -46,14 +46,23 @@ class CSS2DObject extends Object3D { this.element.setAttribute( 'draggable', false ); /** - * The 3D objects center point. - * `( 0, 0 )` is the lower left, `( 1, 1 )` is the top right. + * The object's anchor point, and the point around which the object rotates. + * A value of `(0.5, 0.5)` corresponds to the midpoint of the object. A value + * of `(0, 0)` corresponds to the upper left corner of the object. * * @type {Vector2} * @default (0.5,0.5) */ this.center = new Vector2( 0.5, 0.5 ); + /** + * The object's angle of rotation, counterclockwise, in radians. + * + * @type {number} + * @default 0 + */ + this.rotationAngle = 0; + this.addEventListener( 'removed', function () { this.traverse( function ( object ) { @@ -97,8 +106,7 @@ const _a = new Vector3(); const _b = new Vector3(); /** - * This renderer is a simplified version of {@link CSS3DRenderer}. The only transformation that is - * supported is translation. + * This renderer is a simplified version of {@link CSS3DRenderer}. * * The renderer is very useful if you want to combine HTML based labels with 3D objects. Here too, * the respective DOM elements are wrapped into an instance of {@link CSS2DObject} and added to the @@ -235,7 +243,20 @@ class CSS2DRenderer { object.onBeforeRender( _this, scene, camera ); - element.style.transform = 'translate(' + ( - 100 * object.center.x ) + '%,' + ( - 100 * object.center.y ) + '%)' + 'translate(' + ( _vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - _vector.y * _heightHalf + _heightHalf ) + 'px)'; + // pivot point + const cx = 100 * object.center.x; + const cy = 100 * object.center.y; + element.style.transformOrigin = `${cx}% ${cy}%`; + + // angle of rotation, counter-clockwise convention + const angle = - object.rotationAngle; + + // coordinates + const tx = _vector.x * _widthHalf + _widthHalf; + const ty = -_vector.y * _heightHalf + _heightHalf; + + // transform + element.style.transform = `translate(${-cx}%, ${-cy}%) translate(${tx}px, ${ty}px) rotate(${angle}rad)`; if ( element.parentNode !== domElement ) {