PageSourceSearch

https://aum-ar-2024.onrender.com/libs/three.js-r132/examples/jsm/renderers/CSS3DRenderer.js

js aum-ar-2024.onrender.com collected 2026-10-03 11:39:18 UTC 6,688 bytes, 307 lines download raw bytes

1import {
2	Matrix4,
3	Object3D,
4	Quaternion,
5	Vector3
6} from '../../../build/three.module.js';
7
8/**
9 * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs
10 */
11
12const _position = new Vector3();
13const _quaternion = new Quaternion();
14const _scale = new Vector3();
15
16class CSS3DObject extends Object3D {
17
18	constructor( element ) {
19
20		super();
21
22		this.element = element || document.createElement( 'div' );
23		this.element.style.position = 'absolute';
24		this.element.style.pointerEvents = 'auto';
25		this.element.style.userSelect = 'none';
26
27		this.element.setAttribute( 'draggable', false );
28
29		this.addEventListener( 'removed', function () {
30
31			this.traverse( function ( object ) {
32
33				if ( object.element instanceof Element && object.element.parentNode !== null ) {
34
35					object.element.parentNode.removeChild( object.element );
36
37				}
38
39			} );
40
41		} );
42
43	}
44
45	copy( source, recursive ) {
46
47		super.copy( source, recursive );
48
49		this.element = source.element.cloneNode( true );
50
51		return this;
52
53	}
54
55}
56
57CSS3DObject.prototype.isCSS3DObject = true;
58
59class CSS3DSprite extends CSS3DObject {
60
61	constructor( element ) {
62
63		super( element );
64
65		this.rotation2D = 0;
66
67	}
68
69	copy( source, recursive ) {
70
71		super.copy( source, recursive );
72
73		this.rotation2D = source.rotation2D;
74
75		return this;
76
77	}
78
79}
80
81CSS3DSprite.prototype.isCSS3DSprite = true;
82
83//
84
85const _matrix = new Matrix4();
86const _matrix2 = new Matrix4();
87
88class CSS3DRenderer {
89
90	constructor() {
91
92		const _this = this;
93
94		let _width, _height;
95		let _widthHalf, _heightHalf;
96
97		const cache = {
98			camera: { fov: 0, style: '' },
99			objects: new WeakMap()
100		};
101
102		const domElement = document.createElement( 'div' );
103		domElement.style.overflow = 'hidden';
104
105		this.domElement = domElement;
106
107		const cameraElement = document.createElement( 'div' );
108
109		cameraElement.style.transformStyle = 'preserve-3d';
110		cameraElement.style.pointerEvents = 'none';
111
112		domElement.appendChild( cameraElement );
113
114		this.getSize = function () {
115
116			return {
117				width: _width,
118				height: _height
119			};
120
121		};
122
123		this.render = function ( scene, camera ) {
124
125			const fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf;
126
127			if ( cache.camera.fov !== fov ) {
128
129				domElement.style.perspective = camera.isPerspectiveCamera ? fov + 'px' : '';
130				cache.camera.fov = fov;
131
132			}
133
134			if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
135			if ( camera.parent === null ) camera.updateMatrixWorld();
136
137			let tx, ty;
138
139			if ( camera.isOrthographicCamera ) {
140
141				tx = - ( camera.right + camera.left ) / 2;
142				ty = ( camera.top + camera.bottom ) / 2;
143
144			}
145
146			const cameraCSSMatrix = camera.isOrthographicCamera ?
147				'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) :
148				'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse );
149
150			const style = cameraCSSMatrix +
151				'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)';
152
153			if ( cache.camera.style !== style ) {
154
155				cameraElement.style.transform = style;
156
157				cache.camera.style = style;
158
159			}
160
161			renderObject( scene, scene, camera, cameraCSSMatrix );
162
163		};
164
165		this.setSize = function ( width, height ) {
166
167			_width = width;
168			_height = height;
169			_widthHalf = _width / 2;
170			_heightHalf = _height / 2;
171
172			domElement.style.width = width + 'px';
173			domElement.style.height = height + 'px';
174
175			cameraElement.style.width = width + 'px';
176			cameraElement.style.height = height + 'px';
177
178		};
179
180		function epsilon( value ) {
181
182			return Math.abs( value ) < 1e-10 ? 0 : value;
183
184		}
185
186		function getCameraCSSMatrix( matrix ) {
187
188			const elements = matrix.elements;
189
190			return 'matrix3d(' +
191				epsilon( elements[ 0 ] ) + ',' +
192				epsilon( - elements[ 1 ] ) + ',' +
193				epsilon( elements[ 2 ] ) + ',' +
194				epsilon( elements[ 3 ] ) + ',' +
195				epsilon( elements[ 4 ] ) + ',' +
196				epsilon( - elements[ 5 ] ) + ',' +
197				epsilon( elements[ 6 ] ) + ',' +
198				epsilon( elements[ 7 ] ) + ',' +
199				epsilon( elements[ 8 ] ) + ',' +
200				epsilon( - elements[ 9 ] ) + ',' +
201				epsilon( elements[ 10 ] ) + ',' +
202				epsilon( elements[ 11 ] ) + ',' +
203				epsilon( elements[ 12 ] ) + ',' +
204				epsilon( - elements[ 13 ] ) + ',' +
205				epsilon( elements[ 14 ] ) + ',' +
206				epsilon( elements[ 15 ] ) +
207			')';
208
209		}
210
211		function getObjectCSSMatrix( matrix ) {
212
213			const elements = matrix.elements;
214			const matrix3d = 'matrix3d(' +
215				epsilon( elements[ 0 ] ) + ',' +
216				epsilon( elements[ 1 ] ) + ',' +
217				epsilon( elements[ 2 ] ) + ',' +
218				epsilon( elements[ 3 ] ) + ',' +
219				epsilon( - elements[ 4 ] ) + ',' +
220				epsilon( - elements[ 5 ] ) + ',' +
221				epsilon( - elements[ 6 ] ) + ',' +
222				epsilon( - elements[ 7 ] ) + ',' +
223				epsilon( elements[ 8 ] ) + ',' +
224				epsilon( elements[ 9 ] ) + ',' +
225				epsilon( elements[ 10 ] ) + ',' +
226				epsilon( elements[ 11 ] ) + ',' +
227				epsilon( elements[ 12 ] ) + ',' +
228				epsilon( elements[ 13 ] ) + ',' +
229				epsilon( elements[ 14 ] ) + ',' +
230				epsilon( elements[ 15 ] ) +
231			')';
232
233			return 'translate(-50%,-50%)' + matrix3d;
234
235		}
236
237		function renderObject( object, scene, camera, cameraCSSMatrix ) {
238
239			if ( object.isCSS3DObject ) {
240
241				object.onBeforeRender( _this, scene, camera );
242
243				let style;
244
245				if ( object.isCSS3DSprite ) {
246
247					// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/
248
249					_matrix.copy( camera.matrixWorldInverse );
250					_matrix.transpose();
251
252					if ( object.rotation2D !== 0 ) _matrix.multiply( _matrix2.makeRotationZ( object.rotation2D ) );
253
254					object.matrixWorld.decompose( _position, _quaternion, _scale );
255					_matrix.setPosition( _position );
256					_matrix.scale( _scale );
257
258					_matrix.elements[ 3 ] = 0;
259					_matrix.elements[ 7 ] = 0;
260					_matrix.elements[ 11 ] = 0;
261					_matrix.elements[ 15 ] = 1;
262
263					style = getObjectCSSMatrix( _matrix );
264
265				} else {
266
267					style = getObjectCSSMatrix( object.matrixWorld );
268
269				}
270
271				const element = object.element;
272				const cachedObject = cache.objects.get( object );
273
274				if ( cachedObject === undefined || cachedObject.style !== style ) {
275
276					element.style.transform = style;
277
278					const objectData = { style: style };
279					cache.objects.set( object, objectData );
280
281				}
282
283				element.style.display = object.visible ? '' : 'none';
284
285				if ( element.parentNode !== cameraElement ) {
286
287					cameraElement.appendChild( element );
288
289				}
290
291				object.onAfterRender( _this, scene, camera );
292
293			}
294
295			for ( let i = 0, l = object.children.length; i < l; i ++ ) {
296
297				renderObject( object.children[ i ], scene, camera, cameraCSSMatrix );
298
299			}
300
301		}
302
303	}
304
305}
306
307export { CSS3DObject, CSS3DSprite, CSS3DRenderer };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.