css3d_mixed.html 5.6 KB

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