本章我们来探索下如何添加补间动画以及添加库区。效果如下图所示:
2019.11.26 更新:我最近建立了个人网站,大家可以访问下面的链接查看演示
3D仓库演示
2019.11.28 更新:代码和图片资源等已上传至GitHub
https://github.com/xiao149/ThreeJsDemo
因为上传GIF的大小限制为5M,所以只能截个开门的动画,关门的动画类似大家可以自行脑补。
添加库区后效果如下,库区的位置、长宽、字体的大小位置颜色都是可以根据自己的配置调整的,为了演示方便,我在这里就只添加一个库区:
大家可以从TweenJS的官网:点击跳转 下载到最新的JS文件。
下载下来后我们把Tween.js这个文件放到自己项目的目录下,然后在HTML中引入:
<script src="./ThreeJs/js/Tween.js"></script>
我用自己的话来简单介绍下这个库,我觉得英文单词between非常形象地描述了这个库的功能(毕竟这个库也叫Tween),这个库主要的作用就是创建补间动画,比如一扇门初始状态是关闭的,结束状态是打开的,TweenJS的作用就是在开始点和结束点之间做过度动画,从而实现开门或者关门的效果。
因为我们是要点击一扇门之后,才会发生开门或者关门的动画,所以我们再次使用到了上一章自定义创建的ThreeJs_Composer.js,然后在这个文件中新增我们需要的代码:
首先我们定义四个全局变量(原谅我比较傻,四扇门只有创建四个变量了,true为关闭,false为打开):
var door_state_left1 = true; //默认是门是关闭的
var door_state_right1 = true; //默认是门是关闭的
var door_state_left2 = true; //默认是门是关闭的
var door_state_right2 = true; //默认是门是关闭的
然后在onMouseClick这个方法的最后添加:
if(intersects[0].object.name == "左门1"){
if(door_state_left1){
new TWEEN.Tween(intersects[0].object.rotation).to({
y: -0.5*Math.PI
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
}).start();
door_state_left1 = false;
}else{
new TWEEN.Tween(intersects[0].object.rotation).to({
y: 0
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
}).start();
door_state_left1 = true;
}
}
其他三扇门依葫芦画瓢一样的我就不发了,当我们的鼠标点击“左门1”这个物体时,就会进入这个IF条件。
new TWEEN.Tween(intersects[0].object.rotation).to({
y: -0.5*Math.PI
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
}).start();
上面这段关键代码的意思很简单,就是将点击到的物体的rotation属性,绕着Y轴旋转90度,5000是动画持续的时间,easing(TWEEN.Easing.Elastic.Out) 这段话的意思是动画会有个缓慢过渡的效果,大家可以看下面的两张GIF,前者是添加了easing效果的,关门后还会有一种来回晃动的效果(比较符合现实);后者是没有该效果的,关门时瞬间闭合。
最后我们需要在test.html中添加TweenJS动画的刷新,否则动画是没有效果的:
// 更新控件
function update() {
stats.update();
controls.update();
TWEEN.update(); //刷新动画
}
全部的代码我就不贴了,大家可以回到第三章回顾下,本章只是在第三章的基础上添加了一些内容。
在这里我们又需要创建一个自定义的JS文件Modules.js,该文件存放建模相关的内容,本章的库区以及未来要添加的货架货物等都会放在这个文件里面。
/**
* Modules.js是3D仓库显示模型存放的地方
*
* @author 谢宁
*/
/** ***************************************************************** */
//模型材质信息
var planeMat;
/** 初始化材质信息 */
function initMat() {
planeMat = new THREE.MeshLambertMaterial();
new THREE.TextureLoader().load( './ThreeJs/images/plane.png', function( map ) {
planeMat.map = map;
planeMat.transparent = true;
planeMat.opacity = 0.8;
planeMat.needsUpdate = true;
} );
}
//region 库区
/** 放置虚线框区域和库区名称 */
function addArea(x,z,width,length,scene,name,textColor,font_size,textposition) {
var geometry = new THREE.PlaneGeometry( width, length );
var obj = new THREE.Mesh( geometry, planeMat );
obj.position.set(x,1.5,z);
obj.rotation.x = -Math.PI / 2.0;
obj.name = "库区"+"$"+name.split("$")[1];
scene.add( obj );
new THREE.FontLoader().load('./ThreeJs/FZYaoTi_Regular.json',function(font){
////加入立体文字
var text= new THREE.TextGeometry(name.split("$")[1],{
// 设定文字字体
font:font,
//尺寸
size:font_size,
//厚度
height:0.01
});
text.computeBoundingBox();
//3D文字材质
var m = new THREE.MeshStandardMaterial({color:"#" + textColor});
var mesh = new THREE.Mesh(text,m)
if(textposition == "左对齐"){
mesh.position.x = x - width/2 + 10;
}else if(textposition == "居中"){
mesh.position.x = x - 15;
}else if(textposition == "右对齐"){
mesh.position.x = x + width/2 - 60;
}
mesh.position.y = 1.3;
mesh.position.z = z + length/2 - 20;
mesh.rotation.x = -Math.PI / 2.0;
scene.add(mesh);
});
}
//endregion
首先我们需要初始化库区这个物体的材质,我们使用了兰伯特材质的贴图,贴图就是一张正方形的框框,其他部分都是透明的,大家可以根据自己的喜好PS下。
再来描述下这个方法的参数,以我现在用的这个为例:x,z是库区的位置,width,length是库区的长度和宽度,scene是场景,name是库区的名字,用美元符号分隔,即 “库区英文ID$库区中文名”,textColor是显示文字的颜色,使用十六进制颜色代码,font_size是字体的大小,textposition是文字的位置,我这里提供了“左对齐”、“居中”、“右对齐”三种方式。
addArea(x,z,width,length,scene,name,textColor,font_size,textposition)
addArea(0,0,500,500,scene,"ID1$库区1号","FF0000",20,"左对齐");
最后我们需要在test.html中修改下init()方法:
// 初始化
function init() {
initMat();//初始化材质信息
initScene();
initCamera();
initRenderer();
initContent();
initLight();
initControls();
addArea(0,0,500,500,scene,"ID1$库区1号","FF0000",20,"左对齐"); //添加库区
//添加选中时的蒙版
composer = new THREE.ThreeJs_Composer(renderer, scene, camera);
document.addEventListener('resize', onWindowResize, false);
}
明天就是国庆节了,预祝大家国庆快乐!本章我们讲解了如何给门添加动画,以及如何添加库位。下一章我们将会推出如何添加货架和货物,敬请期待!
我跟广大学习ThreeJs的初学者一样,仍带着懵懂的心去探索这片新大陆,CSDN上的许多前辈都给了我很多关键的灵感和技术方法,如果大家有兴趣,也可以互相交流成长,欢迎大家指导咨询。PS:大家有兴趣可以点进去我的头像,陆陆续续也写了十来篇了。
链接:使用ThreeJs从零开始构建3D智能仓库——第一章: 点我跳转.
链接:使用ThreeJs从零开始构建3D智能仓库——第二章: 点我跳转.
链接:使用ThreeJs从零开始构建3D智能仓库——第三章: 点我跳转.
链接:使用ThreeJs从零开始构建3D智能仓库——第四章: 点我跳转.
链接:使用ThreeJs从零开始构建3D智能仓库——第五章: 点我跳转.