DGIOT开源物联网集成threejs 3D场景

首页技术文章

file
[小 迪 导读] : 制造了三维立体场景的感觉,能够给用户带来视觉冲击力的体验,同时使数据监测更加的具象化

1.引入threejs 与 gsap

npm install three --save
npm install gsap --save
import * as THREE from "three";
import gsap from "gsap";
npm install three --save npm install gsap --save import * as THREE from "three"; import gsap from "gsap";
  • GSAP(GreenSock Animation Platform)是一个从flash时代一直发展到今天的专业动画库
  • three.js是JavaScript编写的WebGL第三方库

2.场景创建

  • 场景借助three.js来进行显示,我们需要以下几个对象:场景、相机和渲染器
const scene = new THREE.Scene(); //场景
//相机
const container = this.$refs.container; // 获取实例
var width = container.clientWidth; // 窗口宽度
var height = container.clientHeight; // 窗口高度
var k = width / height; // 窗口宽高比
var s = 300; // 三维场景显示范围控制系数,系数越大,显示的范围越大
// -s * k, s * k, s, -s, 1, 1000
const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 0.1, 10000);
// 相机位置
camera.position.set(-300, 300, -800); // 设置相机位置
camera.lookAt(scene.position); // 设置相机方向(指向的场景对象)
//渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true, // 去锯齿
});
renderer.setSize(container.clientWidth, container.clientHeight);
renderer.shadowMap.enabled = true; //允许渲染器阴影
// renderer.physicallyCorrectLights = false;
renderer.setClearColor(0x838788); // 设置背景颜色
const scene = new THREE.Scene(); //场景 //相机 const container = this.$refs.container; // 获取实例 var width = container.clientWidth; // 窗口宽度 var height = container.clientHeight; // 窗口高度 var k = width / height; // 窗口宽高比 var s = 300; // 三维场景显示范围控制系数,系数越大,显示的范围越大 // -s * k, s * k, s, -s, 1, 1000 const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 0.1, 10000); // 相机位置 camera.position.set(-300, 300, -800); // 设置相机位置 camera.lookAt(scene.position); // 设置相机方向(指向的场景对象) //渲染器 const renderer = new THREE.WebGLRenderer({ antialias: true, // 去锯齿 }); renderer.setSize(container.clientWidth, container.clientHeight); renderer.shadowMap.enabled = true; //允许渲染器阴影 // renderer.physicallyCorrectLights = false; renderer.setClearColor(0x838788); // 设置背景颜色

模型创建以及导入

  1. 几何体模型
    • 模型创建基本需要:几何体以及其材质
var geometry2 = new THREE.BoxGeometry(300, 2, 300); //几何体创建
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); //材质
var mesh2 = new THREE.Mesh(geometry2, material); //网格模型对象Mesh
mesh2.position.set(-100, 1, -100); //位置设置
scene.add(mesh2); //网格模型添加到场景中
//材质贴图
function loadtexture(url) {
var loder = new THREE.TextureLoader();
var texture = loder.load(url);
var basicMaterial = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide,
// 前面FrontSide 背面:BackSide 双面:DoubleSide
});
return basicMaterial; //这个就是图片所造的一个面的材料
}
var cicle = new THREE.SphereGeometry(60, 60, 60); //球
var material = new THREE.MeshDepthMaterial(loadtexture('http://localhost:5080/dgiot_file/material/test.jpg'));
var mesh = new THREE.Mesh(cicle, material);
mesh.position.set(300, 350, 100);
scene.add(mesh); //网格模型添加到场景中
var geometry2 = new THREE.BoxGeometry(300, 2, 300); //几何体创建 const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); //材质 var mesh2 = new THREE.Mesh(geometry2, material); //网格模型对象Mesh mesh2.position.set(-100, 1, -100); //位置设置 scene.add(mesh2); //网格模型添加到场景中 //材质贴图 function loadtexture(url) { var loder = new THREE.TextureLoader(); var texture = loder.load(url); var basicMaterial = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide, // 前面FrontSide 背面:BackSide 双面:DoubleSide }); return basicMaterial; //这个就是图片所造的一个面的材料 } var cicle = new THREE.SphereGeometry(60, 60, 60); //球 var material = new THREE.MeshDepthMaterial(loadtexture('http://localhost:5080/dgiot_file/material/test.jpg')); var mesh = new THREE.Mesh(cicle, material); mesh.position.set(300, 350, 100); scene.add(mesh); //网格模型添加到场景中
  1. .glb模型导入
// 初始化解压模型
const dracoloader = new DRACOLoader();
dracoloader.setDecoderPath("./draco/gltf/");
const gltfloader = new GLTFLoader(); //创建加载器
gltfloader.setDRACOLoader(dracoloader);
gltfloader.load("LittlestTokyo.glb", (gltf) => {
const model = gltf.scene;
mixer = new THREE.AnimationMixer(model);
mixer.clipAction(gltf.animations[0]).play();
this.animate();
});
// 初始化解压模型 const dracoloader = new DRACOLoader(); dracoloader.setDecoderPath("./draco/gltf/"); const gltfloader = new GLTFLoader(); //创建加载器 gltfloader.setDRACOLoader(dracoloader); gltfloader.load("LittlestTokyo.glb", (gltf) => { const model = gltf.scene; mixer = new THREE.AnimationMixer(model); mixer.clipAction(gltf.animations[0]).play(); this.animate(); });
  1. .fbx 模型导入
const loader = new FBXLoader();//创建加载器
loader.load(
"dancing.fbx",
(fbx) => {
this.model.fbx = fbx;
this.model.fbx.position.set(200, -60, 100);
this.model.fbx.scale.set(0.7, 0.7, 0.7);
scene.add(this.model.fbx);
});
const loader = new FBXLoader();//创建加载器 loader.load( "dancing.fbx", (fbx) => { this.model.fbx = fbx; this.model.fbx.position.set(200, -60, 100); this.model.fbx.scale.set(0.7, 0.7, 0.7); scene.add(this.model.fbx); });

控制器的添加

// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
var controls = new OrbitControls(camera, renderer.domElement); //用户交互
controls.target.set(100, 0, 0);
//设置相机的角度范围
controls.maxPolarAngle = Math.PI * 0.5;
//设置相机距离原点的最远距离
controls.minDistance = 0;
//设置相机距离原点的最远距离
controls.maxDistance = 2000;
// 把canvas挂载到container中
container.appendChild(renderer.domElement);
// 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; var controls = new OrbitControls(camera, renderer.domElement); //用户交互 controls.target.set(100, 0, 0); //设置相机的角度范围 controls.maxPolarAngle = Math.PI * 0.5; //设置相机距离原点的最远距离 controls.minDistance = 0; //设置相机距离原点的最远距离 controls.maxDistance = 2000; // 把canvas挂载到container中 container.appendChild(renderer.domElement);

//浏览器自动渲染下一帧

animate() {
// 浏览器自动渲染下一帧
controls.update();
const delta = clock.getDelta();
mixer.update(delta);
// TWEEN.update(); tween.js是一款可生成平滑动画效果的js动画库
requestAnimationFrame(this.animate);
// 渲染到页面
renderer.render(scene, camera);
}
animate() { // 浏览器自动渲染下一帧 controls.update(); const delta = clock.getDelta(); mixer.update(delta); // TWEEN.update(); tween.js是一款可生成平滑动画效果的js动画库 requestAnimationFrame(this.animate); // 渲染到页面 renderer.render(scene, camera); }

动画效果

let mixer = new THREE.AnimationMixer(); //创建动画混合器(播放器)
gltfloader.load("LittlestTokyo.glb", (gltf) => {
mixer = new THREE.AnimationMixer(model); //创建动画混合器(播放器)载入模型
mixer.clipAction(gltf.animations[0]).play(); //返回所传入的剪辑参数的AnimationAction, 根对象参数可选,默认值为混合器的默认根对象。第一个参数可以是动画剪辑(AnimationClip)对象或者动画剪辑的名称。
}
const delta = clock.getDelta(); //混合器时间
mixer.update(delta) //推进混合器时间并更新动画
let mixer = new THREE.AnimationMixer(); //创建动画混合器(播放器) gltfloader.load("LittlestTokyo.glb", (gltf) => { mixer = new THREE.AnimationMixer(model); //创建动画混合器(播放器)载入模型 mixer.clipAction(gltf.animations[0]).play(); //返回所传入的剪辑参数的AnimationAction, 根对象参数可选,默认值为混合器的默认根对象。第一个参数可以是动画剪辑(AnimationClip)对象或者动画剪辑的名称。 }) const delta = clock.getDelta(); //混合器时间 mixer.update(delta) //推进混合器时间并更新动画

样式参考

file
file
[小 迪 点评]

  • 增强了用户的交互体验感。

想了解更多 dgiot 的具体细节,欢迎大家在GitHub上查看相关源代码。

上一篇:
上一篇:

加小迪为好友
即可加入交流群

点击填写表单
获得解决方案专家帮助
点击前往 GitHub
查看源代码