| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- <!DOCTYPE html>
- <html>
- <head>
- <title>three.js css3d - mixed</title>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
- <link type="text/css" rel="stylesheet" href="main.css">
- <style>
- body {
- background-color: #ffffff;
- }
- </style>
- </head>
- <body>
- <script type="importmap">
- {
- "imports": {
- "three": "../build/three.module.js",
- "three/addons/": "./jsm/"
- }
- }
- </script>
- <script type="module">
- import * as THREE from 'three';
- import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
- import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';
- let camera, scene, rendererCSS3D, rendererWebGL;
- let controls;
- init();
- function init() {
- const controlsDomElement = document.createElement( 'div' );
- controlsDomElement.style.position = 'absolute';
- controlsDomElement.style.top = '0';
- controlsDomElement.style.width = '100%';
- controlsDomElement.style.height = '100%';
- document.body.appendChild( controlsDomElement );
- rendererCSS3D = new CSS3DRenderer();
- rendererCSS3D.setSize( window.innerWidth, window.innerHeight );
- document.body.appendChild( rendererCSS3D.domElement );
- rendererWebGL = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
- rendererWebGL.domElement.style.position = 'absolute';
- rendererWebGL.domElement.style.top = '0';
- rendererWebGL.domElement.style.pointerEvents = 'none';
- rendererWebGL.setPixelRatio( window.devicePixelRatio );
- rendererWebGL.setSize( window.innerWidth, window.innerHeight );
- rendererWebGL.toneMapping = THREE.NeutralToneMapping;
- rendererWebGL.setAnimationLoop( animate );
- document.body.appendChild( rendererWebGL.domElement );
- camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
- camera.position.set( - 1000, 500, 1500 );
- scene = new THREE.Scene();
- scene.background = new THREE.Color( 0xf0f0f0 );
- // Add room
- const roomGeometry = new THREE.EdgesGeometry( new THREE.BoxGeometry( 4000, 2000, 4000, 10, 5, 10 ) );
- const roomMaterial = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2, transparent: true } );
- const room = new THREE.LineSegments( roomGeometry, roomMaterial );
- scene.add( room );
- // Add light
- const hemisphereLight = new THREE.HemisphereLight( 0xffffff, 0x444444, 4 );
- hemisphereLight.position.set( - 25, 100, 50 );
- scene.add( hemisphereLight );
- // Add cutout mesh
- const geometry = new THREE.PlaneGeometry( 1024, 768 );
- const material = new THREE.MeshBasicMaterial( {
- color: 0xff0000,
- blending: THREE.NoBlending,
- opacity: 0,
- premultipliedAlpha: true
- } );
- const mesh = new THREE.Mesh( geometry, material );
- scene.add( mesh );
- // Add frame
- const frame = buildFrame( 1024, 768, 50 );
- scene.add( frame );
- // Add CSS3D element
- const iframe = document.createElement( 'iframe' );
- iframe.style.width = '1028px';
- iframe.style.height = '768px';
- iframe.style.border = '0px';
- iframe.style.backfaceVisibility = 'hidden';
- iframe.src = './#webgl_animation_keyframes';
- scene.add( new CSS3DObject( iframe ) );
- // Add controls
- controls = new OrbitControls( camera );
- controls.connect( controlsDomElement );
- controls.addEventListener( 'start', () => iframe.style.pointerEvents = 'none' );
- controls.addEventListener( 'end', () => iframe.style.pointerEvents = 'auto' );
- controls.enableDamping = true;
- window.addEventListener( 'resize', onWindowResize );
- }
- function buildFrame( width, height, thickness ) {
- const group = new THREE.Group();
- const material = new THREE.MeshStandardMaterial( { color: 0x2200ff } );
- // Create the frame border
- const outerShape = new THREE.Shape();
- outerShape.moveTo( - ( width / 2 + thickness ), - ( height / 2 + thickness ) );
- outerShape.lineTo( width / 2 + thickness, - ( height / 2 + thickness ) );
- outerShape.lineTo( width / 2 + thickness, height / 2 + thickness );
- outerShape.lineTo( - ( width / 2 + thickness ), height / 2 + thickness );
- outerShape.lineTo( - ( width / 2 + thickness ), - ( height / 2 + thickness ) );
- // Create inner rectangle (hole)
- const innerHole = new THREE.Path();
- innerHole.moveTo( - width / 2, - height / 2 );
- innerHole.lineTo( width / 2, - height / 2 );
- innerHole.lineTo( width / 2, height / 2 );
- innerHole.lineTo( - width / 2, height / 2 );
- innerHole.lineTo( - width / 2, - height / 2 );
- outerShape.holes.push( innerHole );
- const frameGeometry = new THREE.ExtrudeGeometry( outerShape, {
- depth: thickness,
- bevelEnabled: false
- } );
- const frameMesh = new THREE.Mesh( frameGeometry, material );
- frameMesh.position.z = - thickness / 2;
- group.add( frameMesh );
- // Add back plane
- const backGeometry = new THREE.PlaneGeometry( width + ( thickness * 2 ), height + ( thickness * 2 ) );
- const backMesh = new THREE.Mesh( backGeometry, material );
- backMesh.position.set( 0, 0, - thickness / 2 );
- backMesh.rotation.y = Math.PI;
- group.add( backMesh );
- return group;
- }
- function onWindowResize() {
- camera.aspect = window.innerWidth / window.innerHeight;
- camera.updateProjectionMatrix();
- rendererWebGL.setSize( window.innerWidth, window.innerHeight );
- rendererCSS3D.setSize( window.innerWidth, window.innerHeight );
- }
- function animate() {
- controls.update();
- rendererWebGL.render( scene, camera );
- rendererCSS3D.render( scene, camera );
- }
- </script>
- </body>
- </html>
|