1. 安装
npm i -s three
2.在vue中使用
最好是在vue2.x版本中使用,我在vue3.x版本使用,总是报错误。 以下代码都是在vue 2.6.11版本的下运行的
<template>
<div>
<div id="container"></div>
</div>
</template>
<script>
import * as THREE from "three";
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import json from "@/assets/02.json";
export default {
name: "THREETest",
data() {
return {
// 相机
camera: null,
// 场景
scene: null,
// 渲染器
renderer: null,
// 几何体
mesh: null,
// 鼠标控制
controls: null,
};
},
methods: {
init: function () {
//创建场景对象Scene
this.scene = new THREE.Scene();
// 获取根容器
let container = document.getElementById("container");
/**
* 正投影相机设置
*/
var width = container.clientWidth; //窗口宽度
var height = container.clientHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 400; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s + 100);
this.camera.position.set(0, -600, 200); //设置相机位置
this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象)
//创建渲染器对象
this.renderer = new THREE.WebGLRenderer({
antialias: true,
});
this.renderer.setSize(container.clientWidth, container.clientHeight); //设置渲染区域尺寸
this.renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
container.appendChild(this.renderer.domElement); //body元素中插入canvas对象
//辅助三维坐标系AxisHelper
this.axisHelper = new THREE.AxisHelper(250);
this.scene.add(this.axisHelper);
// 地图数据
let mapData = json.geometry.coordinates[0];
// 声明一个空数组,来存放用来生成的点
let points = [];
// 转化为Vector2构成的顶点数组
mapData.forEach((elem) => {
// 这里我把坐标都缩小100倍
points.push(new THREE.Vector2(elem[0] / 100, elem[1] / 100));
});
// 样条曲线生成更多的点
var SplineCurve = new THREE.SplineCurve(points);
var shape = new THREE.Shape(SplineCurve.getPoints(300));
//拉伸造型,把二维平面拉伸成立体的
let geometry = new THREE.ExtrudeGeometry(
shape, //二维轮廓
//拉伸参数
{
amount: 12, //拉伸长度
bevelEnabled: false, //无倒角
}
);
// 给几何体设置贴纸
var texture1 = new THREE.TextureLoader().load(
"https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2170086043,2766494990&fm=26&gp=0.jpg"
);
// 立即使用纹理进行材质创建
var material1 = new THREE.MeshBasicMaterial({
map: texture1,
});
var mesh1 = new THREE.Mesh(geometry, material1); //网格模型对象Mesh
this.scene.add(mesh1); //点模型添加到场景中
/**
*设置光源
*/
var point = new THREE.PointLight(0xcccccc); //代表模型的亮度
point.position.set(100, 100, 100); //点光源位置
this.scene.add(point); //点光源添加到场景中
// 加载图片
var textureTree = new THREE.TextureLoader().load("s.png");
// 批量创建表示一个树的精灵模型
for (let i = 0; i < 100; i++) {
var spriteMaterial = new THREE.SpriteMaterial({
map: textureTree, //设置精灵纹理贴图
});
// 创建精灵模型对象
var sprite = new THREE.Sprite(spriteMaterial);
this.scene.add(sprite);
// 控制精灵大小,
sprite.scale.set(30, 30, 1); //// 只需要设置x、y两个分量就可以
var k1 = Math.random() - 0.5;
var k2 = Math.random() - 0.5;
// 设置精灵模型位置,在xoz平面上随机分布
sprite.position.set(500 * k1, 600 * k2, 20);
}
},
render: function () {
// 浏览器 动画 默认每秒60次
requestAnimationFrame(this.render); //请求再次执行渲染函数render
this.renderer.render(this.scene, this.camera); //执行渲染操作
},
// 创建控件对象
createControls() {
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
},
},
// 虚拟dom挂载后加载
mounted() {
this.init();
this.render();
this.createControls();
},
};
</script>
<style scoped>
#container {
height: 700px;
}
</style>
效果如下:
3. 封装tree.js,便于以后调用
- camera 相机
- scene 场景
- renderer渲染器
- point光源
我们来根据这基本的参数来封装一个基本的map类
1.新建map.js
2.引入tree.js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
3.创建一个类,并导出
class Map {
}
export default Map
4.初始化这类
class Map {
camera = null//相机
scene = null//场景
renderer = null//渲染对象
controls = null//控制对象
constructor(container) {
//这个是要加载的容器
this.container = container
}
// 初始化方法
init() {
//将容器赋值给container
let container = this.container
/**
* 创建场景对象Scene
*/
/**
* 创建网格模型
*/
// var geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象
let geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
let material = new THREE.MeshLambertMaterial({
color: 0x0000ff
}); //材质对象Material
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
this.scene.add(mesh); //网格模型添加到场景中
this.scene = new THREE.Scene();
/**
* 光源设置
*/
//点光源
var point = new THREE.PointLight(0xcccccc); //代表模型的亮度
point.position.set(0, -600, 200); //点光源位置
this.scene.add(point); //点光源添加到场景中
//环境光
var ambient = new THREE.AmbientLight(0x444444);
this.scene.add(ambient);
/**
* 相机设置
*/
var width = container.clientWidth; //窗口宽度
var height = container.clientHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 400; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
// 正向投影
this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s + 100);
this.camera.position.set(0, -400, 200); //设置相机位置
this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象)
//辅助三维坐标系AxisHelper
this.axisHelper = new THREE.AxisHelper(250);
this.scene.add(this.axisHelper);
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
this.renderer.setSize(width, height); //设置渲染区域尺寸
//设置背景颜色,我这里设置的是透明色
this.renderer.setClearColor(0xEEEEEE, 0.0);
container.appendChild(this.renderer.domElement); //body元素中插入canvas对象
}
//定义渲染函数
render = () => {
requestAnimationFrame(this.render); //请求再次执行渲染函数render
this.renderer.render(this.scene, this.camera);//执行渲染操作
}
//初始化,鼠标控件
createControls() {
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
// this.controls.addEventListener("change", this.test);
}
}
- 在组件中使用
<template>
<div class="home">
<div id="maps"></div>
</div>
</template>
<script>
import Map from "@/utils/map.js";
export default {
data() {
return {
map: null,
};
},
mounted() {
this.init();
},
methods: {
init() {
let container = document.getElementById("maps");
this.map = new Map(
container,
);
this.map.init();
this.map.render();
this.map.createControls();
},
}
};
</script>
<style scoped>
.home {
width: 100%;
height: 100%;
background-color: #a9a9a9;
}
#maps {
height: 700px;
}
</style>
效果如下:
现在tree.js第一篇就到这,tree.js的文档地址www.webgl3d.cn/,下一片我们学习,室内…