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 是一个轻量级的图形用户界面库,使用这个库可以很容易地创建出能够改变代码变量的界面组件
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 会根据我们设置的属性类型来渲染使用不同的控件。
// contorls 存放需要改变的属性
var controls = new function () {
this.rotationSpeed = 0.02;
};
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed').name('旋转速度'); // name方法指定别名
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeedX').min(0);
gui.add(controls, 'rotationSpeedY').max(10);
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 });
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' ]);
var controls = new function () {
this.visible = true
};
var gui = new dat.GUI();
gui.add(controls, 'visible');
使用按钮(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);
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。