css3d_mixed.html 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>three.js css3d - mixed</title>
  5. <meta charset="utf-8">
  6. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  7. <meta property="og:title" content="three.js css3d - mixed">
  8. <meta property="og:type" content="website">
  9. <meta property="og:url" content="https://threejs.org/examples/css3d_mixed.html">
  10. <meta property="og:image" content="https://threejs.org/examples/screenshots/css3d_mixed.jpg">
  11. <link type="text/css" rel="stylesheet" href="main.css">
  12. <style>
  13. body {
  14. background-color: #ffffff;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <script type="importmap">
  20. {
  21. "imports": {
  22. "three": "../build/three.module.js",
  23. "three/addons/": "./jsm/"
  24. }
  25. }
  26. </script>
  27. <script type="module">
  28. import * as THREE from 'three';
  29. import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
  30. import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';
  31. let camera, scene, rendererCSS3D, rendererWebGL;
  32. let controls;
  33. init();
  34. function init() {
  35. const controlsDomElement = document.createElement( 'div' );
  36. controlsDomElement.style.position = 'absolute';
  37. controlsDomElement.style.top = '0';
  38. controlsDomElement.style.width = '100%';
  39. controlsDomElement.style.height = '100%';
  40. document.body.appendChild( controlsDomElement );
  41. rendererCSS3D = new CSS3DRenderer();
  42. rendererCSS3D.setSize( window.innerWidth, window.innerHeight );
  43. document.body.appendChild( rendererCSS3D.domElement );
  44. rendererWebGL = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
  45. rendererWebGL.domElement.style.position = 'absolute';
  46. rendererWebGL.domElement.style.top = '0';
  47. rendererWebGL.domElement.style.pointerEvents = 'none';
  48. rendererWebGL.setPixelRatio( window.devicePixelRatio );
  49. rendererWebGL.setSize( window.innerWidth, window.innerHeight );
  50. rendererWebGL.toneMapping = THREE.NeutralToneMapping;
  51. rendererWebGL.setAnimationLoop( animate );
  52. document.body.appendChild( rendererWebGL.domElement );
  53. camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
  54. camera.position.set( - 1000, 500, 1500 );
  55. scene = new THREE.Scene();
  56. scene.background = new THREE.Color( 0xf0f0f0 );
  57. // Add room
  58. const roomGeometry = new THREE.EdgesGeometry( new THREE.BoxGeometry( 4000, 2000, 4000, 10, 5, 10 ) );
  59. const roomMaterial = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2, transparent: true } );
  60. const room = new THREE.LineSegments( roomGeometry, roomMaterial );
  61. scene.add( room );
  62. // Add light
  63. const hemisphereLight = new THREE.HemisphereLight( 0xffffff, 0x444444, 4 );
  64. hemisphereLight.position.set( - 25, 100, 50 );
  65. scene.add( hemisphereLight );
  66. // Add cutout mesh
  67. const geometry = new THREE.PlaneGeometry( 1024, 768 );
  68. const material = new THREE.MeshBasicMaterial( {
  69. color: 0xff0000,
  70. blending: THREE.NoBlending,
  71. opacity: 0,
  72. premultipliedAlpha: true
  73. } );
  74. const mesh = new THREE.Mesh( geometry, material );
  75. scene.add( mesh );
  76. // Add frame
  77. const frame = buildFrame( 1024, 768, 50 );
  78. scene.add( frame );
  79. // Add CSS3D element
  80. const iframe = document.createElement( 'iframe' );
  81. iframe.style.width = '1028px';
  82. iframe.style.height = '768px';
  83. iframe.style.border = '0px';
  84. iframe.style.backfaceVisibility = 'hidden';
  85. iframe.src = './#webgl_animation_keyframes';
  86. scene.add( new CSS3DObject( iframe ) );
  87. // Add controls
  88. controls = new OrbitControls( camera );
  89. controls.connect( controlsDomElement );
  90. controls.addEventListener( 'start', () => iframe.style.pointerEvents = 'none' );
  91. controls.addEventListener( 'end', () => iframe.style.pointerEvents = 'auto' );
  92. controls.enableDamping = true;
  93. window.addEventListener( 'resize', onWindowResize );
  94. }
  95. function buildFrame( width, height, thickness ) {
  96. const group = new THREE.Group();
  97. const material = new THREE.MeshStandardMaterial( { color: 0x2200ff } );
  98. // Create the frame border
  99. const outerShape = new THREE.Shape();
  100. outerShape.moveTo( - ( width / 2 + thickness ), - ( height / 2 + thickness ) );
  101. outerShape.lineTo( width / 2 + thickness, - ( height / 2 + thickness ) );
  102. outerShape.lineTo( width / 2 + thickness, height / 2 + thickness );
  103. outerShape.lineTo( - ( width / 2 + thickness ), height / 2 + thickness );
  104. outerShape.lineTo( - ( width / 2 + thickness ), - ( height / 2 + thickness ) );
  105. // Create inner rectangle (hole)
  106. const innerHole = new THREE.Path();
  107. innerHole.moveTo( - width / 2, - height / 2 );
  108. innerHole.lineTo( width / 2, - height / 2 );
  109. innerHole.lineTo( width / 2, height / 2 );
  110. innerHole.lineTo( - width / 2, height / 2 );
  111. innerHole.lineTo( - width / 2, - height / 2 );
  112. outerShape.holes.push( innerHole );
  113. const frameGeometry = new THREE.ExtrudeGeometry( outerShape, {
  114. depth: thickness,
  115. bevelEnabled: false
  116. } );
  117. const frameMesh = new THREE.Mesh( frameGeometry, material );
  118. frameMesh.position.z = - thickness / 2;
  119. group.add( frameMesh );
  120. // Add back plane
  121. const backGeometry = new THREE.PlaneGeometry( width + ( thickness * 2 ), height + ( thickness * 2 ) );
  122. const backMesh = new THREE.Mesh( backGeometry, material );
  123. backMesh.position.set( 0, 0, - thickness / 2 );
  124. backMesh.rotation.y = Math.PI;
  125. group.add( backMesh );
  126. return group;
  127. }
  128. function onWindowResize() {
  129. camera.aspect = window.innerWidth / window.innerHeight;
  130. camera.updateProjectionMatrix();
  131. rendererWebGL.setSize( window.innerWidth, window.innerHeight );
  132. rendererCSS3D.setSize( window.innerWidth, window.innerHeight );
  133. }
  134. function animate() {
  135. controls.update();
  136. rendererWebGL.render( scene, camera );
  137. rendererCSS3D.render( scene, camera );
  138. }
  139. </script>
  140. </body>
  141. </html>
粤ICP备19079148号