vue中添加threeJS

一、首先第一步就是下载

npm install three

二、引入(引入在页面中引入就行),在哪里用就在那里引入,不用全局引入

import * as THREE from 'three'
// 引入fbx模型加载库FBXLoader
import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader.js'
// 移动旋转 three/...等于D:/demoR/vue-admin-template/vueTemplateMock/node_modules/three/examples/jsm/controls/OrbitControls"
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 可视化变换控件引入
import { TransformControls } from "three/examples/jsm/controls/TransformControls.js"//三维坐标轴

三、使用

这里呢我看别的博主写的都是在页面中使用,参数挂载到data中 。这是参考的别人写的文章,这种方式就不在这里在进行赘述了
https://blog.csdn.net/u014452812/article/details/82783991
https://zhuanlan.zhihu.com/p/333615381
https://www.jb51.net/article/192999.htm
我自己则用了另一种方式进行写,
直接把相关的threejs处理逻辑独立出去了,然后在把个别要在页面加载的函数抛出来,在页面引用使用,(主要光搭架子就好多行代码,要是页面还有其他东西要写,看着烦死了)
页面.vue

<template>
    <div>
      <div class="threeJSBox">
        <div id="container"></div>
      </div>
    </div>
</template>
 
<script>
import { animate,threeExcute,FnDestroy } from "./index.js";
export default {
  name: 'ThreeTest',
  data() {
    return {

    }
  },
  methods: {},
  mounted() {
    threeExcute()
    animate()
  },
  beforeDestroy() {
    FnDestroy()
  }
}
</script>
<style scoped>

  .threeJSBox,#container{
    width: 1300px;
    height: 700px;
    border: 1px solid #f00;
  }
</style>

threejs逻辑.js

import * as THREE from 'three'
// 引入fbx模型加载库FBXLoader
import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader.js'
// 移动旋转
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 可视化变换控件引入
import { TransformControls } from "three/examples/jsm/controls/TransformControls.js"//三维坐标轴
//-----------------------

//------------
var transformControl;

var renderer,scene,camera,controls,timer;
var width,height;

// 初始化渲染器 Renderer
function initRenderer() {
    width = document.getElementById("container").clientWidth;
    height = document.getElementById("container").clientHeight;
    renderer = new THREE.WebGLRenderer({
        antialias:true,
        alpha:true
        // canvas: document.getElementById('box')
    });/*生成渲染器对象(属性:抗锯齿效果为设置有效)*/
    renderer.setSize(width,height);
    document.getElementById("container").appendChild(renderer.domElement);
    /*设置canvas背景色(clearColor)和背景色透明度(clearAlpha)必须设置alpha:true 再WebGLRenderer中 */
    renderer.setClearColor(0x00ff00, 0.0); //设置背景颜色
}
// 初始化场景 Scene
function initScene(){
    scene = new THREE.Scene();
    // // 辅助坐标系  参数250表示坐标系大小,可以根据场景大小去设置
    // var axisHelper = new THREE.AxisHelper(120);
    // scene.add(axisHelper);
}
// 初始化相机 Camera
function initCamera() {
    // PerspectiveCamera 透视摄像机 四个参数:视野角度(fov),长宽比(aspect ratio)、近切面(near)、远切面(far)
    camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
    //定义camera的位置 相机角度
    // (x,y,z)x:负数为向左、正数为向右,y:负数为向下、正数为向上,z:负数越大离得越远、正数越大离得越远(两者方向相反)
    // camera.position.set(-30, 0, 60);
    camera.translateZ(700)
    //这里的lookAt函数是将视角指定为看原点
    camera.lookAt(new THREE.Vector3(0, 0, 0));
    scene.add( camera );
    // camera=new THREE.OrthographicCamera(-2, 2, 1.5, -1.5, 1, 10);
    // //将camera添加到scene中
    // scene.add(camera);
}
//可视化变换控件对象
function initTransformControls(){
    transformControl = new TransformControls( camera,renderer.domElement );
    scene.add( transformControl );//控件对象添加到场景对象
}
// 初始化光源light
function initLight() {
    //环境光
    var ambient = new THREE.AmbientLight(0xFFFFFF);
    scene.add(ambient);
}
// 相机空间
function initcontrols() {
    controls = new OrbitControls( camera, renderer.domElement );
    controls.target.set( 0, 0.5, 0 );
    controls.update();
    controls.enablePan = false;
    controls.enableDamping = true;
}

//2d文字精灵图
function init2DSpriteFont(){
makeTextPlaneMate2('小可爱').then(function (m) {
    let sprite = new THREE.Sprite(m);
    sprite.position.set(145, 11.5864898576271, -135);
    sprite.scale.set(-461.55739713473173, -535.010759450665, -6.212728214410121);
    sprite.name='guang'
    scene.add(sprite);
    transformControl.attach(sprite);
})
}
function makeTextPlaneMate2(text1) {
//绘制画布做为Sprite的材质
var canvasText = document.createElement("canvas");
canvasText.width = 700;
canvasText.height = 700;
var ctx = canvasText.getContext("2d");
//添加背景图片,进行异步操作
return new Promise((resolve, reject) => {
    let img = new Image();
    img.src = "/img/textBorder.png";
    //图片加载之后的方法
    img.onload = () => {
        //将画布处理为透明
        // ctx.clearRect(0, 0, 300, 300);
        //绘画图片
        ctx.drawImage(img, 0, 0, 300, 150);

        resolve(makeText(ctx, canvasText,text1))
    };
    //图片加载失败的方法
    img.onerror = (e) => {
        reject(e)
    }
});
}
function makeText(ctx, canvas,text1) {
//文字
const x = 10;
const y = 50
ctx.font = "40px Arial";
ctx.fillText(text1, x, y);

let texture = new THREE.CanvasTexture(canvas);
// let picaizhi=new THREE.SpriteMaterial({ map: texture });
return new THREE.SpriteMaterial({ map: texture });
}
// 全部加载
function threeExcute() {
    //初始化渲染器
    initRenderer();
    //初始化场景
    initScene();
    //初始化照相机
    initCamera();
    initTransformControls()
    //初始化光源
    initLight();
    //相机空间
    initcontrols();
    init2DSpriteFont()

}
var animate = function () {
    timer=requestAnimationFrame( animate );
    controls.update();
    renderer.render( scene, camera );
    // console.log(xPosition,'-xPosition');
    // let obj =scene.getObjectByName ("guang")
    // if (obj) {
    //     obj.position.x=xPosition
    // }

};
function FnDestroy(){
    cancelAnimationFrame(timer)
    transformControl=null
    renderer=null
    scene=null
    camera=null
    controls=null
    width=null
    height=null
}

export{
    threeExcute,
    animate,
    FnDestroy
}

posted @ 2021-10-09 17:07  嗯哼Nymph  阅读(1303)  评论(0编辑  收藏  举报