赞
踩
目录
最近遇到一个新的需求,在threeJS的模型中加载我们的普通的H5页面,研究了下,发现threeJS中自带的CSS3DRenderer可以实现,先放一张展示图
可以看到,中间的面板就是加载的threeJS官网页面,并且可以操作互动
CSS3DRenderer通过CSS3的transforms属性,将层级的3D变换应用到Dom元素上,将Dom元素和WebGL的内容相结合,操作Dom元素的positionh和rotation属性来创建动画。
代码结构:
- /**
- * CSS3DRenderer通过CSS3的transforms属性,将层级的3D变换应用到Dom元素上,将Dom元素和WebGL的内容相结合,Dom => Object3D
- * 操作Dom元素的positionh和rotation属性来创建动画
- * @type {CSS3DRenderer}
- */
- this.labelRenderer = new CSS3DRenderer();
- this.labelRenderer.setSize(this.container.clientWidth, this.container.clientHeight);
- this.labelRenderer.domElement.style.position = "absolute";
- this.labelRenderer.domElement.style.top = 0;
- this.container.appendChild(this.labelRenderer.domElement);
- console.log(this.labelRenderer);
- //创建控件对象
- this.controls = new OrbitControls(this.camera, this.labelRenderer.domElement);
同时创建控件对象,把CSS3DRenderer的场景加入控制器中
CSS3DRenderer跟场景下的Render一样,需要进行render()场景渲染处理
this.labelRenderer.render(this.scene, this.camera);
配合CSS3DRenderer,将创建的Dom元素通过CSS3DObject包装成3D对象
DOM => Object3D
代码结构:
- let domEle = document.createElement("div");
- domEle.innerHTML = "<div class='domBox'><iframe src='https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene'></iframe></div>"
- /**
- * 将创建的Dom元素用过CSS3DObject包装成3D对象
- * @type {CSS3DObject}
- */
- let domEleObj = new CSS3DObject(domEle);
- domEleObj.position.set(-150, -50, -380);
- this.scene.add(domEleObj);
将把转换后的3D对象直接加入场景中即可
- <template>
- <div class="wrap">
- <div ref="container" id="container"></div>
- </div>
- </template>
- <script>
- import * as THREE from "three";
- import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js";
- import {CSS3DRenderer, CSS3DObject} from "three/examples/jsm/renderers/CSS3DRenderer.js";
-
- export default {
- name: "ThreeTest",
- mounted() {
- this.myReq = null
- this.container
- this.scene
- this.camera
- this.renderer
- this.labelRenderer
- this.controls
- this.initRender();
- this.initScene();
- this.initModel();
- this.animate();
- window.onresize = this.onWindowResize;
- },
- methods: {
- getTexturesFromAtlasFile(atlasImgUrl, tilesNum) {
- const textures = [];
- for (let i = 0; i < tilesNum; i++) {
- textures[i] = new THREE.Texture();
- }
- new THREE.ImageLoader().load(atlasImgUrl, (image) => {
- let canvas, context;
- const tileWidth = image.height;
- for (let i = 0; i < textures.length; i++) {
- canvas = document.createElement('canvas');
- context = canvas.getContext('2d');
- canvas.height = tileWidth;
- canvas.width = tileWidth;
- context.drawImage(image, tileWidth * i, 0, tileWidth, tileWidth, 0, 0, tileWidth, tileWidth);
- textures[i].image = canvas;
- textures[i].needsUpdate = true;
- }
- });
- return textures;
- },
- initRender: function () {
- this.container = document.getElementById("container");
- this.camera = new THREE.PerspectiveCamera(
- 70,
- this.container.clientWidth / this.container.clientHeight,
- 1,
- 1000
- );
- this.camera.position.z = 1;
- this.renderer = new THREE.WebGLRenderer({antialias: true});
- this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
- this.container.appendChild(this.renderer.domElement);
- /**
- * CSS3DRenderer通过CSS3的transforms属性,将层级的3D变换应用到Dom元素上,将Dom元素和WebGL的内容相结合,Dom => Object3D
- * 操作Dom元素的positionh和rotation属性来创建动画
- * @type {CSS3DRenderer}
- */
- this.labelRenderer = new CSS3DRenderer();
- this.labelRenderer.setSize(this.container.clientWidth, this.container.clientHeight);
- this.labelRenderer.domElement.style.position = "absolute";
- this.labelRenderer.domElement.style.top = 0;
- this.container.appendChild(this.labelRenderer.domElement);
- console.log(this.labelRenderer);
- //创建控件对象
- this.controls = new OrbitControls(this.camera, this.labelRenderer.domElement);
- },
- initScene() {
- this.scene = new THREE.Scene();
- },
- initModel() {
- const textures = this.getTexturesFromAtlasFile('source/sun_temple_stripe.jpg', 6);
- const materialArr = [];
- for (let i = 0; i < 6; i++) {
- materialArr.push(new THREE.MeshBasicMaterial({map: textures[i]}));
- }
- var boxGeometry = new THREE.BoxGeometry(200, 200, 200, 100, 100, 100);
- boxGeometry.scale(1, 1, -1);
- let cube = new THREE.Mesh(boxGeometry, materialArr);
- this.scene.add(cube);
- let domEle = document.createElement("div");
- domEle.innerHTML = "<div class='domBox'><iframe src='https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene'></iframe></div>"
- /**
- * 将创建的Dom元素用过CSS3DObject包装成3D对象
- * @type {CSS3DObject}
- */
- let domEleObj = new CSS3DObject(domEle);
- domEleObj.position.set(-150, -50, -380);
- this.scene.add(domEleObj);
- },
- render() {
- this.renderer.render(this.scene, this.camera);
- this.labelRenderer.render(this.scene, this.camera);
- },
- onWindowResize() {
- this.camera.aspect = window.innerWidth / window.innerHeight;
- this.camera.updateProjectionMatrix();
- this.render();
- this.renderer.setSize(window.innerWidth, window.innerHeight);
- },
- animate() {
- this.render();
- this.myReq = requestAnimationFrame(this.animate);
- }
- },
- beforeDestroy() {
- cancelAnimationFrame(this.myReq)
- this.scene = null
- this.scene.dispose()
- this.camera = null
- this.renderer = null
- this.labelRenderer = null
- this.controls = null
- }
- };
- </script>
- <style>
- .wrap {
- position: fixed;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- z-index: 100;
- }
-
- #container {
- height: 100%;
- }
-
- .domBox {
- width: auto;
- }
-
- </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。