2 Star 1 Fork 0

大春哥/threejs练习

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

THREEJS 入门基础知识


three.js是什么

​ WebGL(Web Graphics Library)是一种3D绘图协议,它允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型。

​ 使用WebGL原生的API来写3D程序非常复杂,需要相对较多的数学知识,对于前端开发者来说学习成本较高。而Three.js对WebGL提供的接口进行了非常好的封装,简化了很多细节,大大降低了学习成本,成为前端开发者完成3D绘图的得力工具,目前在github上star数量已经达到了将近4万+。


三大基本组件

three.js使用面向对象的方式来构建程序,包含3个基本对象: 场景(scene), 相机(camera), 以及一个渲染器(renderer)。 比如看春晚,场景对应于整个舞台,相机是拍摄镜头,渲染器用来把拍摄好的舞台画面显示在电视屏幕上, 有了这三样东西, 才能够使用相机将场景渲染到网页上去。


场景

场景是所有物体的容器,如果要显示一个苹果,就需要将苹果对象加入场景中。在Threejs中场景就只有一种,用THREE.Scene来表示,要构件一个场景也很简单,只要new一个对象就可以了,代码如下:

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

### 相机

相机就像人的眼睛一样,人站在不同位置,抬头或者低头都能够看到不同的景色。

场景只有一种,但是相机却又很多种, 不同的相机呈相的结果不同, 可以用不同的场景, (比如人像,风景,微距), 对开发者来说,只要设置不同的相机参数,即可;

// 创建透视相机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); 
scene.add(camera); //添加相机

渲染器

​ 渲染器的作用就是将相机拍摄出的画面在浏览器中呈现出来。渲染器决定了渲染的结果应该画在页面的什么元素上面,并且以怎样的方式来绘制。three.js中有很多种类的渲染器,例如webGLRenderer、canvasRenderer、SVGRenderer,通常使用的是webGL渲染器。

var renderer = new THERR.WebGLRenderer(); // 创建webGL渲染器
renderer.render(scene,camera); // 渲染 

创建好染器后,需要调用render方法将之前创建好的场景和相机相结合从而渲染出来,即调用渲染器的render方法。


第一个场景

下面的代码, 我们将建立一个场景和一个旋转的立方体:

<html>

<head>
	<title>My first Three.js app</title>
	<style>
		body {
			margin: 0;
		}

		canvas {
			width: 100%;
			height: 100%
		}
	</style>
</head>

<body>
	<script src="./three.js"></script>
	<script>
		// 创建场景对象
		var scene = new THREE.Scene();
		// 创建透视相机  
		var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
		// 创建渲染器 
		var renderer = new THREE.WebGLRenderer();
		// 设置渲染器的尺寸
		renderer.setSize(window.innerWidth, window.innerHeight);
		// 将渲染器的canvas标签添加到页面
		document.body.appendChild(renderer.domElement);
		// 创建立方体几何模型
		var geometry = new THREE.BoxGeometry(1, 1, 1);
		// 创建基础材质对象
		var material = new THREE.MeshBasicMaterial({
			color: 0x00ff00
		});
		// 创建网格模型 
		var cube = new THREE.Mesh(geometry, material);
		// 将网格模型添加到 场景中
		scene.add(cube);
		// 设置相机位置
		camera.position.z = 5;
		// 渲染函数
		var render = function () {
			requestAnimationFrame(render);

			cube.rotation.x += 0.1;
			cube.rotation.y += 0.1;

			renderer.render(scene, camera);
		};

		render();
	</script>
</body>

</html>

轨道控制器

​ 轨道控制器OrbitControls.js是一个神奇的控件,可以实现场和鼠标、键盘交互,让场景动起来,控制场景的旋转、平移,缩放; 轨道控制器本质上改变的并不是场景,而是相机的参数,相机的位置角度不同,同一个场景的渲染效果是不一样,比如一个相机绕着一个场景旋转,就像场景旋转一样。 OrbitControls是对Three.js正投影相机和透视投影相机对象进行封装的,你想深入了解相机控制器OrbitControls的每一个功能,可以阅读Three.js\examples\js\controls目录下的OrbitControls.js 文件

构造函数参数数说明

new THREE.OrbitControls(object: Camera,domElement: HTMLDOMElement)
// object: 控制的相机
// domElement: 可选的,指定在特定的元素(例如画布 renderer.domElement)上工作

属性:

属性名 说明
autoRotate Boolean 默认false。设定为true时,相机自动围绕目标旋转但必须在animation中循环调用update();
autoRotateSpeed Float 当前者为true时默认2.0,代表每轮60fps用时30s,值越小转动越慢
rotateSpeed Float 旋转速度(ORBIT的旋转速度,鼠标左键),默认1
domElement HTMLDOMElement 侦听鼠标/触摸事件,必须在构造函数中传递,用作特性值更改后不会重新设置事件侦听器 默认是整个文档
enableDamping Boolean 默认false。设置为true则启用阻尼(惯性),用来给控制相机一个重量,必须调用update()在你的animation循环中
dampingFactor Float 前者为true时使用阻尼惯性(可理解为阻止向一个方向移动)
enabled Boolean 是否启用控件,默认true
enableKeys Boolean 能否用键盘控制,默认true ←↑→↓四个键控制物体的移动
keys Object 控制相机平移的四个键。默认四个箭头键{LEFT: 37,UP: 38,RIGHT: 39,DOWM:40} 所有的键值
enablePan Boolean 相机平移,默认true
panSpeed Float 移动的速度,默认1
keyPanSpeed Float 相机平移的速度,默认每按一次控制方向键移动7.0像素
enableRotate Boolean 水平垂直旋转相机,默认true。只想控制单轴,通过PolarAngle/AzimuthAngle的最小值和最大值设置为相同的值,这将导致垂直
maxAzimuthAngle Float 水平旋转,范围Math.PI~Math.PI 或者Infinity 默认Infinity
minAzimuthAngle Float 水平旋转,范围Math.PI~Math.PI 或者Infinity 默认Infinity
maxPolarAngle Float 垂直旋转,范围0~Math.PI 默认Math.PI
minPolarAngle Float 垂直旋转,范围0~Math.PI 默认0
maxDistance Float 拉远镜头(只能用在PerspectiveCamera),默认Infinity
minDistance Float 拉近镜头,默认0
maxZoom Float 拉远镜头(只能用在OthorgraphicCamera),默认Infinity
minZoom Float拉近镜头,默认0
mouseButton Object {ORBIT: THREE.MOUSE.LEFT,ZOOM: THREE.MOUSE.MIDDLE,PAN: THREE.MOUSE.RIGHT} 鼠标控制缩放移动和旋转
object Camera 正在控制的相机
position0 Vector3 在reset()和saveState()内部使用
screenSpacePaning Boolean 平移时摄像机位置的转换。true,相机的平移在屏幕空间;false,摄像机在与摄像机向上方向正交的平面上平移,默认false
target Vector3在reset()和saveState()内部使用
zoom0 Vector3 在reset()和saveState()内部使用
zoomSpeed Float zoom(变焦)的速度,默认1

方法:

方法名 说明
dispose() null 移除所有的事件监听
getAzimuthalAngle() radians 获得用弧度表示的当前水平旋转角度
getPolarAngle() radians获得用弧度表示的当前垂直旋转角度
reset() null 通过最近一次调用saveState()或者初始状态来重置为当前的状态
saveState() null 保存当前控制的状态,可以稍后通过reset()来恢复
update() false 更新控件,在手动改变了摄像机的钻换后必须调用。在设置了autoRotate或enableDamping时也要在循环中调用

事件

事件名称 说明
change OrbitControls的变化事件

对于一个静态的场景,可能不需要一直周期性调用渲染函数渲染场景,而是鼠标旋转缩放场景的时候才重新渲染,就可以通过OrbitControls的变化事件change监听触发函数调用渲染函数render。

// 渲染函数 
function render() {
    renderer.render(scene, camera);
}
varcontrols = newTHREE.OrbitControls(camera);
//监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
controls.addEventListener('change', render);

dat.GUI.js 界面组件

dat.GUI 是一个轻量级的图形用户界面库,使用这个库可以很容易地创建出能够改变代码变量的界面组件

使用步骤

1 引包

<script type="text/javascript" src="../libs/dat.gui.js"></script>

2 定义一个 JavaScript 对象(如:controls),该对象中保存要通过 dat.GUI 改变的属性

var controls = new function () {
    this.rotationSpeed = 0.02;
    //......
};

3 接下来需要将这个 JavaScript 对象传递给 dat.gui 对象,并设置各个属性的取值范围

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);

4 最后当用户对 dat.GUI 控件进行操作时,controls 里的属性值也会同步修改。在程序中直接引用这个属性值即可

控件类型

dat.GUI 会根据我们设置的属性类型来渲染使用不同的控件。

数字类型(Number)

// contorls 存放需要改变的属性 
var controls = new function () {
    this.rotationSpeed = 0.02;
};
  • 如果没有设置限制条件,则为一个 input 输入框。
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed').name('旋转速度'); // name方法指定别名
  • 可以设置最小值最大值范围,则显示为 slider 滑块组件(当然右侧还是有 input 输入)
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
  • 还可以只单独限制最小值或者最大值,这个同样为一个 input 输入框。
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeedX').min(0);
gui.add(controls, 'rotationSpeedY').max(10);
  • 可以配合 step 限制步长。
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeedX').step(0.5);
gui.add(controls, 'rotationSpeedY', 0, 3).step(0.5);
gui.add(controls, 'rotationSpeedZ').max(10).step(0.5);
  • 如果数字只是有限的几种固定值,那还可以使用下拉框的形式。
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', { Stopped: 0, Slow: 0.02, Fast: 5 });

字符串类型(String)

  • 默认情况下就是一个 input 输入框。
var controls = new function () {
    this.site = "hangge.com"
};
 
var gui = new dat.GUI();
gui.add(controls, 'site');
  • 只是有限的几种固定值,那还可以使用下拉框的形式。
var controls = new function () {
    this.site = "hangge.com"
};
 
var gui = new dat.GUI();
gui.add(controls, 'site', [ 'google.com', 'hangge.com', '163.com' ]);

布尔类型(Boolean )

  • 使用复选框(Checkbox)的形式控制
var controls = new function () {
    this.visible = true
};
 
var gui = new dat.GUI();
gui.add(controls, 'visible');

自定义函数(Function)

使用按钮(button)的形式控制,点击按钮会调用相应的方法。

var controls = new function () {
    this.hello = function() {
      alert("欢迎访问 hangge.com");
    }
};
 
var gui = new dat.GUI();
gui.add(controls, 'hello');

颜色值

dat.GUI 一共提供了 4 种类型颜色输入控制:CSS、RGB、RGBA、Hue(注意:颜色使用 addColor 方法添加控件)

var controls = new function () {
    this.color0 = "#ffae23";                // CSS string
    this.color1 = [0, 128, 255];            // RGB array
    this.color2 = [0, 128, 255, 0.3];       // RGB with alpha
    this.color3 = {h: 350, s: 0.9, v: 0.3}; // Hue, saturation, value
};
 
var gui = new dat.GUI();
gui.addColor(controls, 'color0');
gui.addColor(controls, 'color1');
gui.addColor(controls, 'color2');
gui.addColor(controls, 'color3');

事件监听

对于面板中的每一个控制项,我们都可以设置 onChange 和 onFinishChange 监听事件。

var controls = new function () {
    this.speed = 1;
};
 
var gui = new dat.GUI();
var speedController = gui.add(controls, 'speed', 0, 5);
 
//对应控制项值改变时响应(比如拖动滑块过程中)
speedController.onChange(function(value) {
  //value 要改变的数据
  console.log("onChange:" + value)
});
 
//对应控制项值修改完毕响应
speedController.onFinishChange(function(value) {
  console.log("onFinishChange" + value)
});

选项组

可以使用文件夹给选项分组

var gui = new dat.GUI();
// 第一组
var f1 = gui.addFolder('Flow Field');
f1.add(text, 'speed');
f1.add(text, 'noiseStrength');
// 第二组
var f2 = gui.addFolder('Letters');
f2.add(text, 'growthSpeed');
f2.add(text, 'maxSize');
f2.add(text, 'message');
// 展开第二组
f2.open();

把模型渲染到场景

下面代码是将一个立方体添加到场景中:

// 1-创建立方体几何模型
var geometry = new THREE.BoxGeometry(1, 1, 1);
// 2-创建基础材质对象
var material = new THREE.MeshBasicMaterial({
    color: 0x00ff00
});
// 3-创建网格模型 
var cube = new THREE.Mesh(geometry, material);
// 4-将网格模型添加到 场景中
scene.add(cube);

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/dttx123/threejs_exercise.git
git@gitee.com:dttx123/threejs_exercise.git
dttx123
threejs_exercise
threejs练习
master

搜索帮助