TWaver MONO Design
使用DataBox
DataBox是管理所有数据对象的容器,在MVC框架中处于M(模型)层,它是视图的数据提供者,它的主要功能是对数据进行装载、卸载,并对数据元素的变化进行监听。
数据操作
DataBox中的数据可以通过API创建,也可以通过XML或JSON的方式进行序列化和反序列化。DataBox中提供了许多对数据操作的API,以下列出了常用的API:
- add(data, index) 往数据容器中添加一个数据
- addByDescendant(data) 如果节点有孩子,就把节点的孩子也添加到数据容器中
- remove(data) 从数据容器中删除某个数据
- removeById(id) 通过数据的ID编号从数据容器中删除该数据
- contains(data) 判断是否包含某个数据
- containsById(id) 通过数据ID判断是否包含某个数据
- getDataById(id) 根据数据的ID编号获取对应的数据
- getDatas() 获取数据容器中的所有数据
- getDataAt(index) 获取数据容器中某个序号上的数据
- size() 数据容器的大小,也就是容器中数据的数量
- lightsSize() 数据容器中光源的数量
- getLights() 获取数据容器中所有的光源
- clear() 清空数据容器中所有的数据
- removeSelection 删除所有选中的数据
- clearSelection 对所有数据取消选中
- clearEditing 对所有数据取消编辑
以下一段程序展示了对Databox中数据的增删改查:
var box = new mono.DataBox(); for(var i = 0; i < 3; i++) { var element = new mono.Element("element_" + i); element.setName("element_" + i); box.add(element); } box.forEach(function(element) { console.log(element.getName()); //element_0,element_1,element_2 }); var element0 = box.getDataAt(0); element0.setName("newElement"); console.log(element0.getName());//newElement box.remove(element0); console.log(box.size());//3 box.clear(); console.log(box.size());//0
如果想要呈现优美的3D场景,还需要DataBox和Network(视图层)关联,通过模型驱动视图来展现3D场景:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Cube</title> <script type="text/javascript" src = "mono.js"></script> <script type="text/javascript"> function init(){ var box = new mono.DataBox(); var camera = new mono.PerspectiveCamera(30, 1.5, 0.1, 10000); camera.setPosition(-800,800,-800); camera.look(new mono.Vec3(0, 0, 0)); var network= new mono.Network3D(box, camera, myCanvas); var interaction2 = new mono.SelectionInteraction(network); var interaction=new mono.DefaultInteraction(network); interaction.zoomSpeed=5; var interactions = [interaction, interaction2]; network.setInteractions(interactions); mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,'clientWidth','clientHeight'); var cube = new mono.Cube(200,200,200); cube.setStyle('m.type','basic'); cube.setStyle('m.color', "green"); cube.setPosition(0,0,0); box.add(cube); } </script> </head> <body onload = "init()"> <div id = "mainDiv"><canvas id="myCanvas" /></div> </body> </html>
事件监听
DataBox可以对容器中的数据对象的变化进行监听,DataBox提供了以下的事件监听器供用户使用:
- addDataBoxChangeListener(listener, scope, ahead) 当数据容器中的数据发生改变时(增加,删除,清空),就可以通过此方法监听
- removeDataBoxChangeListener(listener, scope) 移除数据容器的数据增减变化的监听器
- addDataPropertyChangeListener(listener,scope,ahead) 当数据容器中的数据属性发生变化时,比如网元位置,网元名称等,都可以通过此方法来监听
- removeDataPropertyChangeListener(listener, scope) 移除数据容器中数据的属性更改事件的监听器
以下一段程序展示了监听器的使用:
var box = new mono.DataBox(); var element = new mono.Element(); box.addDataBoxChangeListener(function (e) { console.log(e.kind); // "add","remove" }); var element2 = new mono.Element(); box.add(element2); box.remove(element);
使用Network组件
Network3D是一个用于交互的视图组件,可以展示3D场景,并实现用户和3D场景之间的交互,比如旋转镜头,选中3D对象,通过鼠标或键盘移动3D对象等。
在网页中添加Network
在网页中插入Network3D,首先自定义一个div,并创建一张画布canvas:
<div id = "mainDiv" > <canvas id="myCanvas" width="800" height="800"/> </div>
Network3D需要由一个与之关联的DataBox驱动,显示DataBox中的网元。当初始化Network3D时,DataBox默认会绑定在Network3D上。通过network3D构造方法创建network3D,并与DataBox、Camera和canvas绑定:
//构造方法 Network3D=function(dataBox,camera,canvas,parameters){};
下面的例子在html中创建了一个network3D,并展现出一个3D物体。
<!DOCTYPE html> <html> <head> <title>Room Inspection</title> <script type="text/javascript" src = "libs/mono.js"></script> <script type="text/javascript" src = "libs/twaver.js"></script> <script type="text/javascript"> var network, interaction; function load(){ var box = new mono.DataBox(); var camera = new mono.PerspectiveCamera(30, 1.5, 0.1, 10000); var target = new mono.Vec3(150,50,150); camera.setPosition(1000,500,1000); camera.lookAt(target); network = new mono.Network3D(box, camera, myCanvas); mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,'clientWidth','clientHeight'); box.add(new mono.AmbientLight(0xffffff)); createBall(box); } function createBall(box){ var ball=new mono.Sphere(300,100); ball.setStyle('m.texture.image','images/earth2.png'); ball.setStyle('m.type','phong'); ball.setStyle('m.texture.repeat',new mono.Vec2(1,1)); ball.setStyle('m.specularStrength',100); box.add(ball); } </script> </head> <body onload = 'load()'> <div id = "mainDiv" > <canvas id="myCanvas" width="800" height="800"/> </div> </body> </html>
Interaction交互模式
mono中提供了DefaultInteraction、SelectIonInteraction、EditInteraction等三种交互模式。DefaultInteraction交互模式包括可以在3D场景中旋转镜头,通过鼠标滚轮缩放镜头,键盘操作镜头等。设置SelectionInteraction交互模式,3D场景中的对象可以被选中,也可以按住ctrl键进行框选;在EditInteraction模式下可以编辑3D对象,例如平移,缩放,旋转等。
也可以通过setInteractions方法为network同时设置多种交互模式。
- DefaultInteraction.getRotateSpeed():获取镜头旋转的速度
- DefaultInteraction.setRotateSpeed(rotateSpeed):设置镜头旋转的速度
- DefaultInteraction.getZoomSpeed():获取镜头缩放的速度
- DefaultInteraction.setZoomSpeed(zoomSpeed):设置镜头缩放的速度
- DefaultInteraction.getPanSpeed():获取镜头平移的速度
- DefaultInteraction.setPanSpeed(panSpeed)设置镜头平移的速度
- EditInteraction.setShowHelpers(showHelpers):设置是否显示帮助的组件
- EditInteraction.setScaleable(scaleable):设置是否可缩放
- EditInteraction.setRotateable(rotateable):设置是否可旋转
- EditInteraction.setTranslateable(translateable):设置是否可平移
- EditInteraction.setDefaultMode(defaultMode):设置默认的模式,mono中提供了三种模式:translate,rotate和scale
- EditInteraction.setScaleRate(scaleRate):设置缩放率
- EditInteraction.setForceSameScale(forceSameScale):设置是否需要等比例缩放
下面代码为network设置了DefaultInteraction和SelectionInteraction两种交互模式。
network= new mono.Network3D(box, camera, myCanvas); interaction = new MONO.DefaultInteraction(network); interaction.zoomSpeed = 30; interaction.yLowerLimitAngle = Math.PI/180; interaction.yUpLimitAngle = Math.PI / 3; network.setInteractions([new MONO.SelectionInteraction(network), interaction]);
自适应缩放
自适应缩放会自动调整Network3D的Bounds值,使3D物体在network中的呈现更加友善。可通过如下方法实现:
autoAdjustNetworkBounds = function(network, o, w, h, left, top) {}
鼠标键盘交互事件
mono中为我们提供了非常友善的用户鼠标键盘交互事件,下面列出常用的事件。
-
鼠标交互事件
- 按住左键移动:旋转物体
- 按住右键移动:平移物体
- 滚轴:缩放物体
-
键盘交互事件
- pageup:沿着z轴正方向移动
- pagedown:沿着z轴负方向移动
- left:沿着x轴正方向移动
- up:沿着x轴负方向移动
- right:沿着y轴正方向移动
- down:沿着y轴负方向移动
- ctrl+A:全选
- ctrl+C:复制
- ctrl+V:粘贴
自动渲染
我们可以通过setRenderSelectFunction()方法过滤哪些选中的网元需要绘制选择边框,哪些不需要绘制边框。
setRenderSelectFunction = function(f) {}
我们还可以在分别监听到渲染前后,使用setBeforeRenderFunction()设置渲染Network3D前的执行方法,使用setRenderCallback()来设置渲染Network3D之后的回调方法。方法原型如下:
mono.Network3D.prototype.setRenderCallback = function(f) {} //调用setRenderCallback方法 network.setRenderCallback(function(){ //do something }); mono.Network3D.prototype.setBeforeRenderFunction = function(f) {} //调用setBeforeRenderFunction方法 network.setBeforeRenderFunction(function(){ //do something });