Skip to content

Commit f9b0be4

Browse files
authored
Merge pull request #13959 from yomotsu/css2d-renderer-respect-z
CSS2DRenderer: add z respecting
2 parents 83eb608 + 412f58a commit f9b0be4

File tree

4 files changed

+216
-0
lines changed

4 files changed

+216
-0
lines changed

docs/examples/renderers/CSS2DRenderer.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ <h1>[name]</h1>
3333
<h2>Examples</h2>
3434

3535
<p>
36+
[example:css2d_label]<br>
3637
[example:webgl_loader_pdb molecules]
3738
</p>
3839

examples/css2d_label.html

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
6+
<title>three.js css2d - label</title>
7+
<style>
8+
body {
9+
background-color: #000;
10+
margin: 0;
11+
overflow: hidden;
12+
}
13+
#info {
14+
position: absolute;
15+
top: 0px;
16+
width: 100%;
17+
color: #FFF;
18+
padding: 5px;
19+
font-family: Monospace;
20+
font-size: 13px;
21+
text-align: center;
22+
z-index: 1;
23+
}
24+
25+
.label{
26+
color: #FFF;
27+
font-family: sans-serif;
28+
padding: 2px;
29+
background: rgba( 0, 0, 0, .6 );
30+
}
31+
32+
a {
33+
color: #000000;
34+
}
35+
36+
</style>
37+
</head>
38+
<body>
39+
<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - three.js css2d - label</div>
40+
41+
<script src="../build/three.js"></script>
42+
43+
<script src="js/controls/OrbitControls.js"></script>
44+
45+
<script src="js/renderers/CSS2DRenderer.js"></script>
46+
47+
<script>
48+
49+
var camera, scene, renderer, labelRenderer;
50+
var controls;
51+
var clock = new THREE.Clock();
52+
var textureLoader = new THREE.TextureLoader();
53+
54+
var earth, moon;
55+
56+
init();
57+
animate();
58+
59+
function init() {
60+
61+
var EARTH_RADIUS = 1;
62+
var MOON_RADIUS = 0.27;
63+
64+
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
65+
camera.position.set( 10, 5, 20 );
66+
67+
controls = new THREE.OrbitControls( camera );
68+
69+
scene = new THREE.Scene();
70+
71+
scene2 = new THREE.Scene();
72+
73+
dirLight = new THREE.DirectionalLight( 0xffffff );
74+
dirLight.position.set( 0, 0, 1 );
75+
scene.add( dirLight );
76+
77+
var axesHelper = new THREE.AxesHelper( 5 );
78+
scene.add( axesHelper );
79+
80+
//
81+
82+
var earthGeometry = new THREE.SphereBufferGeometry( EARTH_RADIUS, 16, 16 );
83+
var earthMaterial = new THREE.MeshPhongMaterial( {
84+
specular: 0x333333,
85+
shininess: 5,
86+
map: textureLoader.load( 'textures/planets/earth_atmos_2048.jpg' ),
87+
specularMap: textureLoader.load( 'textures/planets/earth_specular_2048.jpg' ),
88+
normalMap: textureLoader.load( 'textures/planets/earth_normal_2048.jpg' ),
89+
normalScale: new THREE.Vector2( 0.85, 0.85 )
90+
} );
91+
earth = new THREE.Mesh( earthGeometry, earthMaterial );
92+
scene.add( earth );
93+
94+
var moonGeometry = new THREE.SphereBufferGeometry( MOON_RADIUS, 16, 16 );
95+
var moonMaterial = new THREE.MeshPhongMaterial( {
96+
shininess: 5,
97+
map: textureLoader.load( 'textures/planets/moon_1024.jpg' )
98+
} );
99+
moon = new THREE.Mesh( moonGeometry, moonMaterial );
100+
scene.add( moon );
101+
102+
//
103+
104+
var earthDiv = document.createElement( 'div' );
105+
earthDiv.className = 'label';
106+
earthDiv.textContent = 'Earth';
107+
earthDiv.style.marginTop = '-1em';
108+
var earthLabel = new THREE.CSS2DObject( earthDiv );
109+
earthLabel.position.set( 0, EARTH_RADIUS, 0 );
110+
earth.add( earthLabel );
111+
112+
var moonDiv = document.createElement( 'div' );
113+
moonDiv.className = 'label';
114+
moonDiv.textContent = 'Moon';
115+
moonDiv.style.marginTop = '-1em';
116+
var moonLabel = new THREE.CSS2DObject( moonDiv );
117+
moonLabel.position.set( 0, MOON_RADIUS, 0 );
118+
moon.add( moonLabel );
119+
120+
//
121+
122+
renderer = new THREE.WebGLRenderer();
123+
renderer.setPixelRatio( window.devicePixelRatio );
124+
renderer.setSize( window.innerWidth, window.innerHeight );
125+
document.body.appendChild( renderer.domElement );
126+
127+
labelRenderer = new THREE.CSS2DRenderer();
128+
labelRenderer.setSize( window.innerWidth, window.innerHeight );
129+
labelRenderer.domElement.style.position = 'absolute';
130+
labelRenderer.domElement.style.top = 0;
131+
document.body.appendChild( labelRenderer.domElement );
132+
133+
}
134+
135+
function animate() {
136+
137+
requestAnimationFrame( animate );
138+
139+
var elapsed = clock.getElapsedTime();
140+
141+
moon.position.set( Math.sin( elapsed ) * 5, 0, Math.cos( elapsed ) * 5 );
142+
143+
renderer.render( scene, camera );
144+
labelRenderer.render( scene, camera );
145+
146+
}
147+
148+
</script>
149+
</body>
150+
</html>

examples/files.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,9 @@ var files = {
360360
"css3d_sprites",
361361
"css3d_youtube"
362362
],
363+
"css2d": [
364+
"css2d_label"
365+
],
363366
"canvas": [
364367
"canvas_ascii_effect",
365368
"canvas_camera_orthographic",

examples/js/renderers/CSS2DRenderer.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ THREE.CSS2DRenderer = function () {
3737
var viewMatrix = new THREE.Matrix4();
3838
var viewProjectionMatrix = new THREE.Matrix4();
3939

40+
var cache = {
41+
objects: new WeakMap()
42+
};
43+
4044
var domElement = document.createElement( 'div' );
4145
domElement.style.overflow = 'hidden';
4246

@@ -79,6 +83,12 @@ THREE.CSS2DRenderer = function () {
7983
element.style.oTransform = style;
8084
element.style.transform = style;
8185

86+
var objectData = {
87+
distanceToCameraSquared: getDistanceToSquared( camera, object )
88+
};
89+
90+
cache.objects.set( object, objectData );
91+
8292
if ( element.parentNode !== domElement ) {
8393

8494
domElement.appendChild( element );
@@ -95,6 +105,57 @@ THREE.CSS2DRenderer = function () {
95105

96106
};
97107

108+
var getDistanceToSquared = function () {
109+
110+
var a = new THREE.Vector3();
111+
var b = new THREE.Vector3();
112+
113+
return function ( object1, object2 ) {
114+
115+
a.setFromMatrixPosition( object1.matrixWorld );
116+
b.setFromMatrixPosition( object2.matrixWorld );
117+
118+
return a.distanceToSquared( b );
119+
120+
};
121+
122+
}();
123+
124+
var filterAndFlatten = function ( scene ) {
125+
126+
var result = [];
127+
128+
scene.traverse( function ( object ) {
129+
130+
if ( object instanceof THREE.CSS2DObject ) result.push( object );
131+
132+
} );
133+
134+
return result;
135+
136+
};
137+
138+
var zOrder = function ( scene ) {
139+
140+
var sorted = filterAndFlatten( scene ).sort( function ( a, b ) {
141+
142+
var distanceA = cache.objects.get( a ).distanceToCameraSquared;
143+
var distanceB = cache.objects.get( b ).distanceToCameraSquared;
144+
145+
return distanceA - distanceB;
146+
147+
} );
148+
149+
var zMax = sorted.length;
150+
151+
for ( var i = 0, l = sorted.length; i < l; i ++ ) {
152+
153+
sorted[ i ].element.style.zIndex = zMax - i;
154+
155+
}
156+
157+
};
158+
98159
this.render = function ( scene, camera ) {
99160

100161
scene.updateMatrixWorld();
@@ -105,6 +166,7 @@ THREE.CSS2DRenderer = function () {
105166
viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );
106167

107168
renderObject( scene, camera );
169+
zOrder( scene );
108170

109171
};
110172

0 commit comments

Comments
 (0)