一、建立项目
准备工作完成后,使用用vs code建立项目,为搭建基本功能样式,结构如下图1:
css文件夹:包括基本样式文件main.css,基本代码如下:
html,
body {
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
color: #fff;
font-family: '微软雅黑';
text-align: center;
}
/*画布容器*/
.canvas-frame {
border: none;
cursor: pointer;
width: 100%;
overflow: hidden;
background-color: #ffffff;
}
images文件夹:存放各种图标文件;
js文件夹:存放自定义js,基本框架所需的有:
1)main.js。用于存放主程序方法,包括预加载等。
2)divcontrol.js。用存放页面样式相关方法。
3)z3d.js。用于存放基于three.js自封装的相关方法。
lib文件夹:存放three.js 、jquery、Detector.js(用于判断显卡或浏览器是否支持WebGL)等基类。
二、创建three基本框架
依据上述项目结构,创建three.基本框架。
实现目标为:空白的、随窗口变化自适应的三维空间。
1)初始化三维空间
a.为初始化三维空间,需要对渲染器Render,相机Camera,场景Scene进行声明;
/**
* 初始化渲染器
*/
z3D.prototype.initThree = function () {
var _this = this;
_this.renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: _this.option.antialias
});
_this.renderer.setSize(_this.width, _this.height); //设置画布大小
$("#" + _this.fId).append(_this.renderer.domElement);
_this.renderer.setClearColor(_this.option.clearCoolr, 1.0);
_this.renderer.shadowMap.enabled = true; //阴影
_this.renderer.shadowMapSoft = true;
//鼠标事件监听
_this.renderer.domElement.addEventListener('mousedown', _this.onDocumentMouseDown, false);
_this.renderer.domElement.addEventListener('mousemove', _this.onDocumentMouseMove, false);
};
/**
* 初始化摄像机
*/
z3D.prototype.initCamera = function () {
var _this = this;
_this.camera = new THREE.PerspectiveCamera(45, _this.width / _this.height, 1, 10000); //透视摄像投影
_this.camera.name = 'mainCamera';
_this.camera.position.x = 0;
_this.camera.position.y = 1000;
_this.camera.position.z = -1800;
_this.camera.up.x = 0;
_this.camera.up.y = 0;
_this.camera.up.z = 1;
_this.camera.lookAt({
x: 0,
y: 0,
z: 0
});
_this.objects.push(_this.camera);
};
/**
* 创建场景
*/
z3D.prototype.initScene = function () {
var _this = this;
_this.scene = new THREE.Scene();
};
b.为增强渲染效果,还需要增加光影效果Light;
/**
* 灯光布置
* @description{
* AmbientLight: 环境光,基础光源,它的颜色会被加载到整个场景和所有对象的当前颜色上。
* PointLight:点光源,朝着所有方向都发射光线
* SpotLight :聚光灯光源:类型台灯,天花板上的吊灯,手电筒等
* DirectionalLight:方向光,又称无限光,从这个发出的光源可以看做是平行光.
* }
*/
z3D.prototype.initLight = function () {
var _this = this;
//方向光
var light = new THREE.DirectionalLight(0xFF0000, 1.0, 0);
light.position.set(100, 100, 200);
_this.scene.add(light);
//环境光
var light1 = new THREE.AmbientLight(0xcccccc);
light.position.set(0, 0, 0);
_this.scene.add(light1);
//点光源
var light2 = new THREE.PointLight(0x555555);
light2.shadow.camera.near = 1;
light2.shadow.camera.far = 5000;
light2.position.set(0, 350, 0);
light2.castShadow = true; //表示这个光是可以产生阴影的
_this.scene.add(light2);
};
c.为方便计算坐标,绘制图形,还需增加/辅助网格HelpGrid;
/**
* 创建网格线
*/
z3D.prototype.initHelpGrid = function () {
var _this = this;
if (_this.option.showHelpGrid) {
var helpGrid = new THREE.GridHelper(1000, 50);
_this.scene.add(helpGrid);
}
};
d.为体现三维空间操作,引入three.js插件OrbitControls.js实现对鼠标操作功能的声明和实现;
/**
* 创建鼠标控制器
*/
z3D.prototype.initMouseCtrl = function () {
var _this = this;
_this.controls = new THREE.OrbitControls(_this.camera); //应用OrbitControls插件,实现鼠标控制
_this.controls.rotateSpeed = 0.1;//角度变换速度
_this.controls.zoomSpeed = 5;//缩放速度
_this.controls.panSpeed = 1;//平移速度
_this.controls.enableZoom = true; //是否允许缩放
_this.controls.enablePan = true;//是否允许移动
_this.controls.enableDamping = true; //是否允许缓冲效果
_this.controls.dampingFactor = 0.1; //缓冲大小
};
e.实现随窗口变化自适应,方法如下:
/**
* 将元素变为与浏览器相同大小
*/
z3D.prototype.initResize = function () {
var _this = this;
var browser_width = $(document.body).width();
var browser_height = $(document.body).height();
$("#" + _this.fId).css("width", browser_width);
$("#" + _this.fId).css("height", browser_height);
_this.camera.aspect = browser_width / browser_height;
_this.camera.updateProjectionMatrix();
_this.renderer.setSize(browser_width, browser_height);
//元素随窗口变化而变化
$(window).resize(function () {
browser_width = $(document.body).width();
browser_height = $(document.body).height();
$("#" + _this.fId).css("width", browser_width);
$("#" + _this.fId).css("height", browser_height);
_this.camera.aspect = browser_width / browser_height;
_this.camera.updateProjectionMatrix();
_this.renderer.setSize(browser_width, browser_height);
});
};
f.最终达到动态效果,必须声明的循环渲染功能,生成游戏循环;
/**
* 循环渲染界面
*/
z3D.prototype.animation = function () {
var _this = z3DObj;
_this.renderer.clear();
_this.renderer.render(_this.scene, _this.camera);
requestAnimationFrame(_this.animation);//循环渲染关键
};
2)封装成z3D.js
按照上述方法,可实现三维空间场景的基本搭建,方法可封装为z3d.js,方便后期调用:
/**
* 作者:Mr.Zhai
* 创建时间:2018年1月11日
* 版本:V0.0.1.bug
* 功能描述:用户创建three组态
*/
/**
* 使用方式
* var zstation=new z3D();
* zstation.initz3D('divid',{...});
* zstation.start();
*/
function z3D() {}
var z3DObj = null;
/**
* 方法:初始化
* @param {*} _fId 画布所属div的Id
* @param {*} _option 参数 {
* antialias:true,//抗锯齿效果为设置有效
* clearCoolr:0xFFFFFF,
* showHelpGrid:false,//是否显示网格线
* }
*/
z3D.prototype.initz3D = function (_fId, _option) {
//参数处理
this.option = new Object();
this.option.antialias = _option.antialias || true; //抗锯齿效果为设置有效
this.option.clearCoolr = _option.clearCoolr || 0x1b7ace; //背景色
this.option.showHelpGrid = _option.showHelpGrid || false; //是否显示网格线
//对象
this.fId = _fId; //div容器id
this.width = $(document.body).width();
this.height = $(document.body).height();
this.renderer = null; //渲染器
this.camera = null; //摄像机
this.scene = null; //场景
this.objects = [];
this.mouseClick = new THREE.Vector2();
this.raycaster = new THREE.Raycaster();
this.controls = null; //鼠标控制器
var _this = this;
};
/**
* 启动three
*/
z3D.prototype.start = function () {
//此处用于判断浏览器
if (!Detector.webgl) {
var warning = Detector.getWebGLErrorMessage();
document.getElementById(_this.fId).appendChild(warning);
return;
}
//开始
var _this = this;
z3DObj = _this;
_this.initThree(_this.fId);
_this.initCamera();
_this.initScene();
_this.initLight(); //光线
_this.initHelpGrid(); //辅助网格
_this.initMouseCtrl(); //鼠标控制器
_this.initResize(_this.fId);
_this.animation(); //循环渲染界面
};
3)Html页面编写
基本功能方法已经编写完成,只需要在html页面中进行引用即可
3D机房
4)最终实现效果如下: