JSFiddle - React, Tailwind, and code Playground
by grano
HTML
<button type="button" id="start-button">start</button>
<video id="video" crossOrigin="anonymous" src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" loop style="display:none">
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/loaders/GLTFLoader.js"></script>
<script src='https://threejs.org/examples/js/postprocessing/EffectComposer.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/RenderPass.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/ShaderPass.js'></script>
<script src='https://threejs.org/examples/js/shaders/CopyShader.js'></script>
<script src="https://threejs.org/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/UnrealBloomPass.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
CSS
#start-button {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 250px;
height: 100px;
}
JavaScript
let camera, scene, renderer, video;
init();
animate();
const startButton = document.getElementById('start-button')
startButton.addEventListener('click', ()=> {
video.play();
startButton.style.display = 'none'
})
function getFittedSize(camera) {
const cameraZ = camera.position.z;
const planeZ = 0;
const distance = cameraZ - planeZ;
const aspect = window.innerWidth / window.innerHeight;
const vFov = (camera.fov * Math.PI) / 180;
const fittedHeight = 2 * Math.tan(vFov / 2) * distance;
const fittedWidth = fittedHeight * aspect;
return [fittedWidth, fittedHeight];
};
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.01, 1000 );
camera.position.set( 0, 0, 140 );
camera.lookAt( 0, 0, 0 );
scene = new THREE.Scene();
const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2);
directionalLight.position.set(2, 2, 2);
scene.add(directionalLight);
video = document.getElementById( 'video' );
const texture = new THREE.VideoTexture( video );
const planeSizes = getFittedSize(camera)
const plane = new THREE.Mesh(new THREE.PlaneGeometry(1,1), new THREE.MeshBasicMaterial({map: texture}));
plane.scale.set(planeSizes[0], planeSizes[1], 1)
plane.position.set(0,0,0);
scene.add(plane);
window.addEventListener('resize', function() {
const w = window.innerWidth;
const h = window.innerHeight;
camera.aspect = w / h;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
const newPlaneSizes = getFittedSize(camera)
// plane.scale.set(newPlaneSizes[0], newPlaneSizes[1], 1)
})
renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.target.set( 0, 0, 0 );
}
function animate() {
...