<div> This is DOM content. (click/drag to reveal teal square)</div>
body, html {
background-color: #000;
margin: 0px;
overflow: hidden;
}
body {
perspective: 800px;
}
body, body > div {
transform-style: preserve-3d;
}
div {
width: 100px;
height: 100px;
background: pink;
position: absolute;
left: 50%;
top: 50%;
transform: translate3d(-50%, -52%, 0);
overflow: hidden;
}
import * as THREE from 'https://unpkg.com/three@0.116.1/build/three.module.js'
import {OrbitControls} from 'https://unpkg.com/three@0.116.1/examples/jsm/controls/OrbitControls.js'
const visibleHeightAtZDepth = ( depth, camera ) => {
// vertical fov in radians
const vFOV = camera.fov * Math.PI / 180;
// Math.abs to ensure the result is always positive
return 2 * Math.tan( vFOV / 2 ) * Math.abs( depth );
};
const visibleWidthAtZDepth = ( depth, camera ) => {
const height = visibleHeightAtZDepth( depth, camera );
return height * camera.aspect;
};
// Simple three.js example
var mesh, renderer, scene, camera, controls;
var cameraZ = 20
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 0, cameraZ );
// controls
controls = new OrbitControls( camera, document );
// ambient
scene.add( new THREE.AmbientLight( 0x222222 ) );
// light
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 0, 20, 0 );
scene.add( light );
var screenDepth
console.log( '---: ', screenDepth = findScreenDepth( camera, renderer ) )
// full width red rectangle at z = -100
//const redGeom = new THREE.BoxBufferGeometry( visibleWidthAtZDepth( -100, camera), 1, 1 );
const redGeom = new THREE.BoxBufferGeometry( 100, 100, 0.0001 );
const redMat = new THREE.MeshBasicMaterial( { color: 'skyblue' } );
const redMesh = new THREE.Mesh( redGeom, redMat );
redMesh.position.set( 0, 0, - screenDepth + cameraZ );
scene.add( redMesh, camera );
}
function findScreenDepth( camera, renderer ) {
const { near, far } = camera
const { height:physicalViewHeight } = renderer.getDrawingBufferSize()
console.log( window.innerHeight, physicalViewHeight )
const threshold = 0.00000000000001
return _findScreenDepth( near, far )
function _findScreenDepth( near, far ) {
const midpoint = ( far - near ) / 2 + near
const midpointHeight = visibleHeightAtZDepth( -midpoint, camera )
if ( Math.abs( ( physicalViewHeight / midpointHeight ) - 1 ) <= threshold )
return midpoint
if ( physicalViewHeight < midpointHeight )
return _findScreenDepth( near, midpoint )
else if ( physicalViewHeight > midpointHeight )
return _findScreenDepth( midpoint, far )
else if ( midpointHeight == physicalViewHeight ) // almost never happens
return midpoint
}
}
function animate() {
requestAnimationFrame( animate );
//controls.update();
renderer.render( scene, camera );
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.