1/** 2 * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs 3 * @author mrdoob / http://mrdoob.com/ 4 * @author yomotsu / https://yomotsu.net/ 5 */ 6 7THREE.CSS3DObject = function ( element ) { 8 9 THREE.Object3D.call( this ); 10 11 this.element = element; 12 this.element.style.position = 'absolute'; 13 this.element.style.pointerEvents = 'auto'; 14 15 this.addEventListener( 'removed', function () { 16 17 this.traverse( function ( object ) { 18 19 if ( object.element instanceof Element && object.element.parentNode !== null ) { 20 21 object.element.parentNode.removeChild( object.element ); 22 23 } 24 25 } ); 26 27 } ); 28 29}; 30 31THREE.CSS3DObject.prototype = Object.create( THREE.Object3D.prototype ); 32THREE.CSS3DObject.prototype.constructor = THREE.CSS3DObject; 33 34THREE.CSS3DSprite = function ( element ) { 35 36 THREE.CSS3DObject.call( this, element ); 37 38}; 39 40THREE.CSS3DSprite.prototype = Object.create( THREE.CSS3DObject.prototype ); 41THREE.CSS3DSprite.prototype.constructor = THREE.CSS3DSprite; 42 43// 44 45THREE.CSS3DRenderer = function () { 46 47 var _this = this; 48 49 var _width, _height; 50 var _widthHalf, _heightHalf; 51 52 var matrix = new THREE.Matrix4(); 53 54 var cache = { 55 camera: { fov: 0, style: '' }, 56 objects: new WeakMap() 57 }; 58 59 var domElement = document.createElement( 'div' ); 60 domElement.style.overflow = 'hidden'; 61 62 this.domElement = domElement; 63 64 var cameraElement = document.createElement( 'div' ); 65 66 cameraElement.style.WebkitTransformStyle = 'preserve-3d'; 67 cameraElement.style.transformStyle = 'preserve-3d'; 68 cameraElement.style.pointerEvents = 'none'; 69 70 domElement.appendChild( cameraElement ); 71 72 var isIE = /Trident/i.test( navigator.userAgent ); 73 74 this.getSize = function () { 75 76 return { 77 width: _width, 78 height: _height 79 }; 80 81 }; 82 83 this.setSize = function ( width, height ) { 84 85 _width = width; 86 _height = height; 87 _widthHalf = _width / 2; 88 _heightHalf = _height / 2; 89 90 domElement.style.width = width + 'px'; 91 domElement.style.height = height + 'px'; 92 93 cameraElement.style.width = width + 'px'; 94 cameraElement.style.height = height + 'px'; 95 96 }; 97 98 function epsilon( value ) { 99 100 return Math.abs( value ) < 1e-10 ? 0 : value; 101 102 } 103 104 function getCameraCSSMatrix( matrix ) { 105 106 var elements = matrix.elements; 107 108 return 'matrix3d(' + 109 epsilon( elements[ 0 ] ) + ',' + 110 epsilon( - elements[ 1 ] ) + ',' + 111 epsilon( elements[ 2 ] ) + ',' + 112 epsilon( elements[ 3 ] ) + ',' + 113 epsilon( elements[ 4 ] ) + ',' + 114 epsilon( - elements[ 5 ] ) + ',' + 115 epsilon( elements[ 6 ] ) + ',' + 116 epsilon( elements[ 7 ] ) + ',' + 117 epsilon( elements[ 8 ] ) + ',' + 118 epsilon( - elements[ 9 ] ) + ',' + 119 epsilon( elements[ 10 ] ) + ',' + 120 epsilon( elements[ 11 ] ) + ',' + 121 epsilon( elements[ 12 ] ) + ',' + 122 epsilon( - elements[ 13 ] ) + ',' + 123 epsilon( elements[ 14 ] ) + ',' + 124 epsilon( elements[ 15 ] ) + 125 ')'; 126 127 } 128 129 function getObjectCSSMatrix( matrix, cameraCSSMatrix ) { 130 131 var elements = matrix.elements; 132 var matrix3d = 'matrix3d(' + 133 epsilon( elements[ 0 ] ) + ',' + 134 epsilon( elements[ 1 ] ) + ',' + 135 epsilon( elements[ 2 ] ) + ',' + 136 epsilon( elements[ 3 ] ) + ',' + 137 epsilon( - elements[ 4 ] ) + ',' + 138 epsilon( - elements[ 5 ] ) + ',' + 139 epsilon( - elements[ 6 ] ) + ',' + 140 epsilon( - elements[ 7 ] ) + ',' + 141 epsilon( elements[ 8 ] ) + ',' + 142 epsilon( elements[ 9 ] ) + ',' + 143 epsilon( elements[ 10 ] ) + ',' + 144 epsilon( elements[ 11 ] ) + ',' + 145 epsilon( elements[ 12 ] ) + ',' + 146 epsilon( elements[ 13 ] ) + ',' + 147 epsilon( elements[ 14 ] ) + ',' + 148 epsilon( elements[ 15 ] ) + 149 ')'; 150 151 if ( isIE ) { 152 153 return 'translate(-50%,-50%)' + 154 'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)' + 155 cameraCSSMatrix + 156 matrix3d; 157 158 } 159 160 return 'translate(-50%,-50%)' + matrix3d; 161 162 } 163 164 function renderObject( object, scene, camera, cameraCSSMatrix ) { 165 166 if ( object instanceof THREE.CSS3DObject ) { 167 168 object.onBeforeRender( _this, scene, camera ); 169 170 var style; 171 172 if ( object instanceof THREE.CSS3DSprite ) { 173 174 // http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/ 175 176 matrix.copy( camera.matrixWorldInverse ); 177 matrix.transpose(); 178 matrix.copyPosition( object.matrixWorld ); 179 matrix.scale( object.scale ); 180 181 matrix.elements[ 3 ] = 0; 182 matrix.elements[ 7 ] = 0; 183 matrix.elements[ 11 ] = 0; 184 matrix.elements[ 15 ] = 1; 185 186 style = getObjectCSSMatrix( matrix, cameraCSSMatrix ); 187 188 } else { 189 190 style = getObjectCSSMatrix( object.matrixWorld, cameraCSSMatrix ); 191 192 } 193 194 var element = object.element; 195 var cachedObject = cache.objects.get( object ); 196
197 if ( cachedObject === undefined || cachedObject.style !== style ) { 198 199 element.style.WebkitTransform = style; 200 element.style.transform = style; 201 202 var objectData = { style: style }; 203 204 if ( isIE ) { 205 206 objectData.distanceToCameraSquared = getDistanceToSquared( camera, object ); 207 208 } 209 210 cache.objects.set( object, objectData ); 211 212 } 213 214 element.style.display = object.visible ? '' : 'none'; 215 216 if ( element.parentNode !== cameraElement ) { 217 218 cameraElement.appendChild( element ); 219 220 } 221 222 object.onAfterRender( _this, scene, camera ); 223 224 } 225 226 for ( var i = 0, l = object.children.length; i < l; i ++ ) { 227 228 renderObject( object.children[ i ], scene, camera, cameraCSSMatrix ); 229 230 } 231 232 } 233 234 var getDistanceToSquared = function () { 235 236 var a = new THREE.Vector3(); 237 var b = new THREE.Vector3(); 238 239 return function ( object1, object2 ) { 240 241 a.setFromMatrixPosition( object1.matrixWorld ); 242 b.setFromMatrixPosition( object2.matrixWorld ); 243 244 return a.distanceToSquared( b ); 245 246 }; 247 248 }(); 249 250 function filterAndFlatten( scene ) { 251 252 var result = []; 253 254 scene.traverse( function ( object ) { 255 256 if ( object instanceof THREE.CSS3DObject ) result.push( object ); 257 258 } ); 259 260 return result; 261 262 } 263 264 function zOrder( scene ) { 265 266 var sorted = filterAndFlatten( scene ).sort( function ( a, b ) { 267 268 var distanceA = cache.objects.get( a ).distanceToCameraSquared; 269 var distanceB = cache.objects.get( b ).distanceToCameraSquared; 270 271 return distanceA - distanceB; 272 273 } ); 274 275 var zMax = sorted.length; 276 277 for ( var i = 0, l = sorted.length; i < l; i ++ ) { 278 279 sorted[ i ].element.style.zIndex = zMax - i; 280 281 } 282 283 } 284 285 this.render = function ( scene, camera ) { 286 287 var fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf; 288 289 if ( cache.camera.fov !== fov ) { 290 291 if ( camera.isPerspectiveCamera ) { 292 293 domElement.style.WebkitPerspective = fov + 'px'; 294 domElement.style.perspective = fov + 'px'; 295 296 } else { 297 298 domElement.style.WebkitPerspective = ''; 299 domElement.style.perspective = ''; 300 301 } 302 303 cache.camera.fov = fov; 304 305 } 306 307 if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); 308 if ( camera.parent === null ) camera.updateMatrixWorld(); 309 310 if ( camera.isOrthographicCamera ) { 311 312 var tx = - ( camera.right + camera.left ) / 2; 313 var ty = ( camera.top + camera.bottom ) / 2; 314 315 } 316 317 var cameraCSSMatrix = camera.isOrthographicCamera ? 318 'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) : 319 'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ); 320 321 var style = cameraCSSMatrix + 322 'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)'; 323 324 if ( cache.camera.style !== style && ! isIE ) { 325 326 cameraElement.style.WebkitTransform = style; 327 cameraElement.style.transform = style; 328 329 cache.camera.style = style; 330 331 } 332 333 renderObject( scene, scene, camera, cameraCSSMatrix ); 334 335 if ( isIE ) { 336 337 // IE10 and 11 does not support 'preserve-3d'. 338 // Thus, z-order in 3D will not work. 339 // We have to calc z-order manually and set CSS z-index for IE. 340 // FYI: z-index can't handle object intersection 341 zOrder( scene ); 342 343 } 344 345 }; 346 347};
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.