基于vue3使用three.js在三维直角坐标系中创建时空立方体

上一篇使用原生js在直角坐标系中创建时空立方体,本篇使用vue3在直角坐标系中创建时空立方体。与原生js创建方式类似,但是有个别细节还是有一定的差异,接下来就开启创建简单的时空立方体吧!

1、先避一个坑,在vue3的函数中直接获取dom元素获取到的是null,并不能直接获取到该dom元素。因为获取dom元素执行的是异步操作,此时就需要导入nextTick库并借助nextTick函数。

import { nextTick } from "vue";
const init= async () => {
    await nextTick();
    document.getElementById("XXX")...
    ...
}

2、接下来的步骤与原生js大同小异,创建vue3项目,导入需要用到的包,个别原生js中THREE有的方法在vue3中被单独拿了出来,比如FontLoader、TextGeometry等。同时可以查看其文件存在的位置。

import * as THREE from "three"; 
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";

3、添加场景、摄像机、渲染器、坐标轴、灯光。因为默认坐标系是右手坐标系,z轴朝向屏幕,因此需要设置摄像机的camera.up.z = 1,使得z轴朝上。

// 创建场景
var scene = new THREE.Scene();

// 灯光
var light = new THREE.DirectionalLight(0xffffff);
// 点光源位置
light.position.set(1, 1, 1);
// 点光源添加到场景中
scene.add(light);

// 创建相机对象
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 10000);
camera.up.x = 0;
camera.up.y = 0;
camera.up.z = 1;
camera.position.set(30, 0, 0); 
camera.lookAt(scene.position);

// 相机设置
var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight); 
renderer.shadowMap.enabled = true;
renderer.setClearColor(0xffffff, 1.0); 
document.getElementById("bar_chart").appendChild(renderer.domElement); 

// 坐标轴
var axes = new THREE.AxesHelper(10);
scene.add(axes);

4、给坐标轴添加文字。因为前一步对坐标轴做了旋转,因此该步骤需要使用rotation对文字进行旋转。这一步对之前的代码进行整合优化,略简洁一些。这里在添加的时候文字一直无法显示(此处似乎又是一个坑,原生js中没有这个问题),后来经过好久的尝试才发现:给的变量如果是字符串可以正常显示;如果是其他数据类型就使用toString方法转为字符串形式就可以正常显示。(此处只显示x轴,y轴和z轴的添加方法类似,仅仅是位置和旋转稍有不同)

var loader = new FontLoader();
// 坐标轴上文字
loader.load('fonts/helvetiker_regular.typeface.json', function(font) {
    // console.log("font", font)
    // 坐标轴字体
    const options = {
        font: font,
        size: 0.5,
        height: 0.1,
        curveSegments: 12,
    }
    // 坐标轴字体材质
    var materialtext = new THREE.MeshPhongMaterial({
        color: 0xEEA2AD,
        specular:0xEEA2AD,
        shininess:0,
    });
    for(var i=1; i<=10; i++){
        // x轴
        var meshtextx = new THREE.Mesh(new TextGeometry(i.toString(), options), materialtext);
        meshtextx.position.set(i-0.2,10,-0.5);
        meshtextx.rotation.x = -Math.PI/2;
        meshtextx.rotation.z = Math.PI;
        scene.add(meshtextx);
    }
});

5、此处添加立方体时CubeGeometry方法会报THREE.CubeGeometry is not a constructor的错误,因此就使用了BoxGeometry方法进行创建并使用add方法添加到场景中。

var boxGeometry = new THREE.BoxGeometry(0.9, 0.9, 0.9)
var material = new THREE.MeshLambertMaterial({color: 0x00ff00*i*j/100 })
material.transparent = true;
material.opacity = 0.8;
var cube = new THREE.Mesh(boxGeometry, material)
cube.position.set(i+0.5, j+0.5, 0.5);
scene.add(cube)

6、同时创建直线的方法也不适用了。原生js中使用LineBasicMaterial方法,在vue3中并不适用。

var geometry = new THREE.BufferGeometry();
var vertices = new Float32Array( [0, 0, 0, 0, 0, 10] );
geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
var material = new THREE.LineBasicMaterial( { color: 0xeeeeee } );
var line = new THREE.Line( geometry, material );
scene.add( line );

7、添加执行渲染函数并运行,完成图像的加载和显示。

var controls = new OrbitControls( camera, renderer.domElement );
function renderScene(){
    controls.update();
    requestAnimationFrame(renderScene);
    renderer.render(scene, camera);
}

以上是vue3中使用three.js创建简单的三维直角坐标系,并添加几何体对象的步骤,如果大家还有其他的方法和思路也欢迎多多交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值