当前位置:   article > 正文

threeJS 模型中加载html页面_three.js添加dom

three.js添加dom

目录

0. 效果图

1. CSS3DRenderer介绍

2. CSS3DObject介绍

3. 完整代码

0. 效果图

最近遇到一个新的需求,在threeJS的模型中加载我们的普通的H5页面,研究了下,发现threeJS中自带的CSS3DRenderer可以实现,先放一张展示图

 可以看到,中间的面板就是加载的threeJS官网页面,并且可以操作互动

1. CSS3DRenderer介绍

CSS3DRenderer通过CSS3的transforms属性,将层级的3D变换应用到Dom元素上,将Dom元素和WebGL的内容相结合,操作Dom元素的positionh和rotation属性来创建动画。

代码结构:

  1. /**
  2. * CSS3DRenderer通过CSS3的transforms属性,将层级的3D变换应用到Dom元素上,将Dom元素和WebGL的内容相结合,Dom => Object3D
  3. * 操作Dom元素的positionh和rotation属性来创建动画
  4. * @type {CSS3DRenderer}
  5. */
  6. this.labelRenderer = new CSS3DRenderer();
  7. this.labelRenderer.setSize(this.container.clientWidth, this.container.clientHeight);
  8. this.labelRenderer.domElement.style.position = "absolute";
  9. this.labelRenderer.domElement.style.top = 0;
  10. this.container.appendChild(this.labelRenderer.domElement);
  11. console.log(this.labelRenderer);
  12. //创建控件对象
  13. this.controls = new OrbitControls(this.camera, this.labelRenderer.domElement);

同时创建控件对象,把CSS3DRenderer的场景加入控制器中

CSS3DRenderer跟场景下的Render一样,需要进行render()场景渲染处理

this.labelRenderer.render(this.scene, this.camera);

2. CSS3DObject介绍

配合CSS3DRenderer,将创建的Dom元素通过CSS3DObject包装成3D对象

DOM => Object3D

代码结构:

  1. let domEle = document.createElement("div");
  2. domEle.innerHTML = "<div class='domBox'><iframe src='https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene'></iframe></div>"
  3. /**
  4. * 将创建的Dom元素用过CSS3DObject包装成3D对象
  5. * @type {CSS3DObject}
  6. */
  7. let domEleObj = new CSS3DObject(domEle);
  8. domEleObj.position.set(-150, -50, -380);
  9. this.scene.add(domEleObj);

将把转换后的3D对象直接加入场景中即可

3. 完整代码

  1. <template>
  2. <div class="wrap">
  3. <div ref="container" id="container"></div>
  4. </div>
  5. </template>
  6. <script>
  7. import * as THREE from "three";
  8. import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js";
  9. import {CSS3DRenderer, CSS3DObject} from "three/examples/jsm/renderers/CSS3DRenderer.js";
  10. export default {
  11. name: "ThreeTest",
  12. mounted() {
  13. this.myReq = null
  14. this.container
  15. this.scene
  16. this.camera
  17. this.renderer
  18. this.labelRenderer
  19. this.controls
  20. this.initRender();
  21. this.initScene();
  22. this.initModel();
  23. this.animate();
  24. window.onresize = this.onWindowResize;
  25. },
  26. methods: {
  27. getTexturesFromAtlasFile(atlasImgUrl, tilesNum) {
  28. const textures = [];
  29. for (let i = 0; i < tilesNum; i++) {
  30. textures[i] = new THREE.Texture();
  31. }
  32. new THREE.ImageLoader().load(atlasImgUrl, (image) => {
  33. let canvas, context;
  34. const tileWidth = image.height;
  35. for (let i = 0; i < textures.length; i++) {
  36. canvas = document.createElement('canvas');
  37. context = canvas.getContext('2d');
  38. canvas.height = tileWidth;
  39. canvas.width = tileWidth;
  40. context.drawImage(image, tileWidth * i, 0, tileWidth, tileWidth, 0, 0, tileWidth, tileWidth);
  41. textures[i].image = canvas;
  42. textures[i].needsUpdate = true;
  43. }
  44. });
  45. return textures;
  46. },
  47. initRender: function () {
  48. this.container = document.getElementById("container");
  49. this.camera = new THREE.PerspectiveCamera(
  50. 70,
  51. this.container.clientWidth / this.container.clientHeight,
  52. 1,
  53. 1000
  54. );
  55. this.camera.position.z = 1;
  56. this.renderer = new THREE.WebGLRenderer({antialias: true});
  57. this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
  58. this.container.appendChild(this.renderer.domElement);
  59. /**
  60. * CSS3DRenderer通过CSS3的transforms属性,将层级的3D变换应用到Dom元素上,将Dom元素和WebGL的内容相结合,Dom => Object3D
  61. * 操作Dom元素的positionh和rotation属性来创建动画
  62. * @type {CSS3DRenderer}
  63. */
  64. this.labelRenderer = new CSS3DRenderer();
  65. this.labelRenderer.setSize(this.container.clientWidth, this.container.clientHeight);
  66. this.labelRenderer.domElement.style.position = "absolute";
  67. this.labelRenderer.domElement.style.top = 0;
  68. this.container.appendChild(this.labelRenderer.domElement);
  69. console.log(this.labelRenderer);
  70. //创建控件对象
  71. this.controls = new OrbitControls(this.camera, this.labelRenderer.domElement);
  72. },
  73. initScene() {
  74. this.scene = new THREE.Scene();
  75. },
  76. initModel() {
  77. const textures = this.getTexturesFromAtlasFile('source/sun_temple_stripe.jpg', 6);
  78. const materialArr = [];
  79. for (let i = 0; i < 6; i++) {
  80. materialArr.push(new THREE.MeshBasicMaterial({map: textures[i]}));
  81. }
  82. var boxGeometry = new THREE.BoxGeometry(200, 200, 200, 100, 100, 100);
  83. boxGeometry.scale(1, 1, -1);
  84. let cube = new THREE.Mesh(boxGeometry, materialArr);
  85. this.scene.add(cube);
  86. let domEle = document.createElement("div");
  87. domEle.innerHTML = "<div class='domBox'><iframe src='https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene'></iframe></div>"
  88. /**
  89. * 将创建的Dom元素用过CSS3DObject包装成3D对象
  90. * @type {CSS3DObject}
  91. */
  92. let domEleObj = new CSS3DObject(domEle);
  93. domEleObj.position.set(-150, -50, -380);
  94. this.scene.add(domEleObj);
  95. },
  96. render() {
  97. this.renderer.render(this.scene, this.camera);
  98. this.labelRenderer.render(this.scene, this.camera);
  99. },
  100. onWindowResize() {
  101. this.camera.aspect = window.innerWidth / window.innerHeight;
  102. this.camera.updateProjectionMatrix();
  103. this.render();
  104. this.renderer.setSize(window.innerWidth, window.innerHeight);
  105. },
  106. animate() {
  107. this.render();
  108. this.myReq = requestAnimationFrame(this.animate);
  109. }
  110. },
  111. beforeDestroy() {
  112. cancelAnimationFrame(this.myReq)
  113. this.scene = null
  114. this.scene.dispose()
  115. this.camera = null
  116. this.renderer = null
  117. this.labelRenderer = null
  118. this.controls = null
  119. }
  120. };
  121. </script>
  122. <style>
  123. .wrap {
  124. position: fixed;
  125. top: 0;
  126. bottom: 0;
  127. left: 0;
  128. right: 0;
  129. z-index: 100;
  130. }
  131. #container {
  132. height: 100%;
  133. }
  134. .domBox {
  135. width: auto;
  136. }
  137. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/135218
推荐阅读