基于three.js的一个项目类的编写

本文介绍如何使用Three.js创建一个虚拟现实项目,包括构建基类、实现动画效果及与React框架集成的方法。

WebVR

这是一篇关于怎么样基于three.js进行可配置的three.js的对象创建的文章
项目地址

编写一个three.js的基类

这是创建的一个Three.js基类其中包含了场景,相机,渲染器,控制器以及一些方法

  // VRcore.js
  import * as THREE from 'three';
  const OrbitControls = require('three-orbit-controls')(THREE)
  let Scene, Camera, Renderer, Controls, loopID;

  function createScene({domContainer = document.body, fov = 50,far = 1000}){
    if (!(domContainer instanceof HTMLElement)) {
      throw new Error('domContainer is not a HTMLElement!');
    }
    // 初始化 scene
    Scene = new THREE.Scene();
    // 初始化 camera
    Camera = new THREE.PerspectiveCamera(fov, domContainer.clientWidth / domContainer.clientHeight, 1, far);
    Camera.position.set( 200, 200, 200 );
    Camera.lookAt(Scene.position);
    Scene.add(Camera);
    // 初始化 renderer
    Renderer = new THREE.WebGLRenderer({ canvas: domContainer, antialias: true, alpha: true } );
    Renderer.clear();
    Renderer.setClearColor( 0xeeeeee, 1); // 更改渲染器颜色
    Renderer.setSize(domContainer.clientWidth, domContainer.clientHeight);
    Renderer.shadowMap.Enabled = true;
    Renderer.setPixelRatio(domContainer.devicePixelRatio);
    initVR();
  }

  function initVR() {
      // 初始化控制器
      Controls = new OrbitControls(Camera, Renderer.domElement);;
      Controls.addEventListener('change', render);
      Controls.enableZoom = true;
  }

  function render() {
    Renderer.render(Scene, Camera);
  }

  function renderStart(callback) {
    loopID = 0; // 记录循环几次,后面有与清除场景中的物体
    if (loopID === -1) return;
    let animate = function(){
      loopID = requestAnimationFrame(animate);
      callback();
      Controls.update();
      render();
    }
    animate();
  }

  // 暂停动画渲染
  function renderStop() {
    if (loopID !== -1) {
        window.cancelAnimationFrame(loopID);
        loopID = -1;
    }
  }
  // 回收当前场景
  function clearScene() {
    for(let i = Scene.children.length - 1; i >= 0; i-- ) {
        Scene.remove(Scene.children[i]);
    }
  }
  // 清理页面
  function cleanPage() {
    renderStop();
    clearScene();
  }

  export {
    Scene,
    Camera,
    Renderer,
    Controls,
    createScene,
    initVR,
    renderStart,
    renderStop,
    clearScene,
    cleanPage
  }

创建一个VRpage基类

这是一个VRpage的基类,所有需要创建Three项目都需要继承这个类,然后生成一个Three项目

  // VRpage.js
  import * as THREE from 'three';
  import * as VRcore from './VRcore.js';

  export default class VRpage {
    constructor(options) {
      // 创建场景
      VRcore.createScene(options);
      this.start();
      this.loadPage();
    }
    loadPage() {
      VRcore.renderStart(() => this.update());
      this.loaded();
    }
    initPage() {
      this.loadPage();
      this.start();
    }
    start() {}
    loaded() {}
    update() {}
  }

生成一个Three.js的项目

下面的文件是一个继承了VRpage类的一个类,然后我们重写了start方法以及update方法,start方法中我们向场景中添加了一个正方体,update方法是我们给这个正方体的一个变形动画,他会结合VRcore.js里面的renderStart方法来进行动画效果

  // page.js
  import * as THREE from 'three';
  import VRpage from '../../utils/VRpage.js';
  import * as VRcore from '../../utils/VRcore.js';

  export default class Page extends VRpage {
    start() { // 启动渲染之前,创建场景3d模型
      let geometry = new THREE.CubeGeometry(100,100,100);
      let material = new THREE.MeshLambertMaterial( { color:0x0000ff} );
      this.box = new THREE.Mesh(geometry,material);
      this.box.position.set(3, -2, -3);
      const PointLight = new THREE.PointLight(0xffffff);
      PointLight.position.set(500, 500, 500);
      const AmbientLight = new THREE.AmbientLight( 0x404040 ); // soft white light
      VRcore.Scene.add(PointLight);
      VRcore.Scene.add(AmbientLight);
      VRcore.Scene.background = new THREE.Color( 0xeeeeee ); // 更改场景背景色
      VRcore.Scene.add(this.box);
    }
    update() {
      this.box.rotation.y += 0.01;
    }
  }

这里我使用的是react的框架

  // index.js
  import React, { Component } from 'react';
  import PropTypes from 'prop-types';
  import Page from './Page.js';
  class Oho extends Component {
    constructor() {
      super();
      this.init = this.init.bind(this);
    }

    componentDidMount() {
      const dom = document.querySelector('#Oho');
      this.init(dom);
    }

    init(dom) {
      const page = new Page({domContainer: dom});
    }

    render() {
      return (
        <div className="three-demo">
          <canvas id="Oho" ref="camera"></canvas>
        </div>
      );
    }
  }

  export default Oho;
基于Three.js的开源项目有许多,其中一个知名的项目是Gio.js。Gio.js一个基于Three.js的web 3D地球数据可视化的开源组件库。使用Gio.js,开发者可以快速地创建自定义的Web3D数据可视化模型,并将其作为一个组件整合到自己的应用中。通过在HTML页面中添加Three.js和Gio.js的依赖,可以开始基于Gio.js开发应用。您可以创建一个具有基础样式的Gio地球,具体代码如下所示: ``` <!DOCTYPE HTML> <html> <head> <!-- 引入 three.js --> <script src="three.min.js"></script> <!-- 引入 Gio.js --> <script src="gio.min.js"></script> </head> <body> <!-- 创建一个 div 作为 Gio 的绘制容器 --> <div id="globalArea"></div> </body> </html> ``` 除了Gio.js,还有其他基于Three.js的开源项目,如harp.gl。harp.gl是一个用TypeScript编写的3D网络地图渲染引擎,使用了Three.js。您可以在harp.gl的GitHub地址中找到更多相关信息。 github.com/syt123450/gio.js giojs.org/index_zh.html GitHub - heremaps/harp.gl: 3D web map rendering engine written in TypeScript using three.js<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [[开源] Gio.js -- 一个基于 Three.js 的 Web3D 地球数据可视化库](https://blog.csdn.net/weixin_34129696/article/details/87961256)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [基于ThreeJs的一些开源地图项目](https://blog.csdn.net/lg8883573/article/details/122596587)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值