如今的棉花加工行业还停留在传统的反应式维护模式当中,当棉花加下厂的设备忽然出现故障时,控制程序须要更换。这种状况下,首先须要客户向设备生产厂家请求派出技术人员进行维护,而后生产厂家才能根据状况再派人到现场进行处理。因为棉花加工设备分布在中国各地乃至出口到世界各地,从客户反应问题到厂家派人到达现场的时间周期就会很长,少则 一天,个别偏远的地方可能会须要几天,不一样程度地影响到企业生产活动的继续进行。传统的反应式维护存在如下缺点:售后服务响应速度慢;维护成本高;生产效率低下;停车率高;管理成本高;没法应对合格工程师不足的状况。html
远程监控系统主要是经过分布于棉花加工生产线各类设备的传感器、开关信号、视频监控设备、 PLC 控制器等装置,经过智能联网设备集成到互联网和局域网上面,实现对生产、运营状况的随时掌握,创建网络范围内的监控数据和网上知识资源库,根据现场采集的设备运行数据进行远程诊断和在线维修。json
http://www.hightopo.com/demo/Plucker/数组
首先是建立一个三维场景,经过将场景中的元素添加到保存数据的数据容器中便可:网络
var dm = new ht.DataModel();// 数据容器 var g3d = new ht.graph3d.Graph3dView(dm);// 三维组件 g3d.addToDOM();// 将三维组件添加到 body 体中
上面代码中出现的 addToDOM 方法是将调用此方法的组件经过 getView 方法获取到此组件的底层 div,随后将此 div 添加到 body 体中。HT 的组件通常都会嵌入 BorderPane、SplitView 和 TabView 等容器中使用,而最外层的HT组件则须要用户手工将 getView() 返回的底层 div 元素添加到页面的 DOM 元素中,这里须要注意的是,当父容器大小变化时,若是父容器是 BorderPane 和 SplitView 等这些HT预约义的容器组件,则HT的容器会自动递归调用孩子组件 invalidate 函数通知更新。但若是父容器是原生的 html 元素, 则 HT 组件没法获知须要更新,所以最外层的 HT 组件通常须要监听 window 的窗口大小变化事件,调用最外层组件 invalidate 函数进行更新。app
addToDOM = function(){ var self = this, view = self.getView(),//获取组件的底层 div style = view.style; document.body.appendChild(view);//将组件底层div添加进body中 style.left = '0';//ht 默认将全部的组件的position都设置为absolute绝对定位 style.right = '0'; style.top = '0'; style.bottom = '0'; window.addEventListener('resize', function () { self.iv(); }, false);//窗口大小改变事件,调用刷新函数 }
整个大环境搭建好了后,咱们须要向场景中添加 3D 模型,并进行位置的摆放,这里采用的是将整个场景的模型以及模型的摆放放在一个 JSON 格式的文件中,而后经过将这个 JSON 文件反序列化到数据容器 DataModel 中,便可呈现 JSON 文件中的场景内容以及模型的摆放位置:异步
ht.Default.xhrLoad('scenes/抓棉机.json', function(text) {// 加载 JSON 文件 dm.deserialize(text);// 将 JSON 反序列化到数据容器中 });
上面出现的 ht.Default.xhrLoad 方法是一个封装好的异步加载文件的函数,能够经过这种方法来加载 JSON 文件,由于此方法为异步加载,因此若是要操做此函数反序列化后的数据容器中的元素,须要在此函数中进行后续的操做。ide
由于整个场景中的元素都是今后 JSON 文件中反序列化出来的,此 JSON 文件中保存的只有场景的内容,并不包括动画以及交互,对于不一样部分的元素的动画也不一样,咱们须要单独将这些元素取出来,这里经过 dm.getDataByTag(tag) 方法实现,此方法经过 tag 惟一标识来获取节点的信息:函数
var equipment = dm.getDataByTag('equipment');// 获取轧棉机的节点 var hand = dm.getDataByTag('hand');// 获取轧棉机“手”节点 var light = dm.getDataByTag('light');// 获取轧棉机顶部的指示灯的节点
获取到这些须要作动画的节点后,这里我用的是动画插件 setAnimation 方法来作的,动画插件更进一步对动画进行封装,用户只需用描述性的说明 HT 便可自动实现动画过程,动画插件能够将图元的一个或多个属性值 (如 width、height、opacity 等)从一个值平滑的缓动至另外一个值,同时提供了丰富的缓动方式用于实现各类效果。可是使用这个插件前得先引入 ht-animation.js 文件:动画
<script src="ht.js"></script> <!--先引入ht.js--> <script src="ht-animation.js"></script>
这里总共有三个部分有动画,采用的方法大体相同,这里仅对整个轧棉机的机身的左右移动的动画进行说明。ui
equipment.setAnimation({// 动画调用方法 moveDown: {// 定义了一个名为 moveDown 的动画过程,这个动画过程改变图元的 x 轴坐标,将其从 623 变化至 -256 from: 623,// 动画开始时的属性值 to: -256,// 动画结束时的属性值 interval: equipInterval,// 动画间隔,单位ms next: ["moveUp"],// 字符串类型,指定当前动画完成以后,要执行的下个动画,可将多个动画融合 onUpdate: function(value) {// 回调函数,动画的每一帧都会回调此函数 this.setX(value);// 设置该节点的 x 轴的值为当前动画 from 到 to 的值 formPane.getItemById('xValue').element = value.toFixed(2);// 获取 form 表单上的 xValue 元素,同时改变此值 formPane.iv();// 表单内容变化后要通知表单进行刷新变化 } }, moveUp: {// 定义了一个名为 moveUp 的动画过程,这个动画过程改变图元的 x 轴坐标,将其从 -256 变化至 623 from: -256, to: 623, interval: equipInterval, next: ["moveDown"], onUpdate: function(value) { this.setX(value); formPane.getItemById('xValue').element = value.toFixed(2); formPane.iv(); } }, start: ['moveDown']// start是一个数组,用于指定要启动的一个或多个动画 });
注意,要使用动画,首先您须要调用 ht.DataModel#enableAnimation(interval) 启动全局动画定时器,默认 interval 为 16ms,若是不设置此参数值,则 DataModel 定时器每隔 16ms 左右就会遍历本身全部的 Data,根据 Data 的 animation 配置执行动画。
dm.enableAnimation();
前面代码中出现的 form 表单,是经过 createForm 方法建立的,此方法定义以下(PS:因为 form 表单的列表稍长,这里就选取几个比较有表明性的表单元素进行说明):
// 建立 form 表单 function createForm() { var fp = new ht.widget.FormPane();// 建立表单组件实例 fp.setWidth(200);// 设置表单组件的宽度 fp.setHeight(250);// 设置表单组件的高度 fp.getView().style.top = '8%';// 设置表单组件的样式 fp.getView().style.right = 0; fp.getView().style.background = 'rgba(255, 255, 255, 0.3)'; document.body.appendChild(fp.getView());// 将表单组件的底层 div 添加到 body 体中 var equipment = dm.getDataByTag('equipment');// 经过 tag 惟一标识获取元素 var hand = dm.getDataByTag('hand'); fp.setLabelAlign('right');// 设置表单的文本对齐方式 fp.addRow([// 向表单中添加一行 此方法的参数一为元素数组,可在一行中添加多个元素 {// 元素一 显示文本内容为 “机器号” element: '机器号', color: '#fff' }, {// 元素二 显示文本内容为 “Machine” element: 'Machine', color: '#fff' } ], [0.1, 0.1]);// 参数二为每一个元素宽度信息数组,宽度值大于1表明固定绝对值,小于等于1表明相对值,也可为80+0.3的组合 fp.addRow([// 向表单中添加一行 此方法的参数为一个数组,可在一行中添加多个元素 {// 元素一 显示文本内容为 “机器号” element: '抓棉机动画', color: '#fff' }, {// 元素二 显示文本内容为 一个按钮元素 button: { label: '开始', onClicked: function() {// 按钮点击触发事件,启动轧棉机左右移动动画 dm.enableAnimation();// 启动全局动画定时器 var light = dm.getDataByTag('light'); if (!light) return; lightColor(light); colorTimer = setInterval(function() { lightColor(light); }, 1000); } } }, { button: { label: '中止', onClicked: function() {// 按钮点击触发事件,关闭轧棉机左右移动动画 dm.disableAnimation();// 中止全局动画定时器 clearInterval(colorTimer); var light = dm.getDataByTag('light'); if (light) light.s('all.color', 'rgba(0,0,255,0.51)'); } } } ], [0.2, 0.1, 0.1]);// 将一行中的三个元素都分配宽度进行显示 fp.addRow([// 向表单中添加一行 此方法的参数为一个数组,可在一行中添加多个元素 {// 元素一 显示文本内容为“小车行走速度” element: '小车行走速度', color: '#fff' }, {// 元素二 显示文本内容为一个 滑动条 id: 'slide', slider: {// 滑动条 value: equipInterval,// slider 当前值 min: 0,// slider 最小值 max: 300,// slider 最大值 step: 20,// slider 每移动一步的值 onValueChanged: function() {// slider 值变化触发事件 var anim = dm.getDataAnimation(equipment);// 得到参数data的动画配置 anim.moveDown.interval = this.getValue();// 设置 moveDown 动画的 interval 内容 anim.moveUp.interval = this.getValue();// 设置 moveUp 动画的 interval 内容 } } } ], [0.1, 0.1]); fp.addRow([// 向表单中添加一行 此方法的参数为一个数组,可在一行中添加多个元素 { element: 'X 轴', color: '#fff' }, { id: 'xValue', element: equipment.getX().toFixed(2),// 获取轧棉机当前 x 轴值 color: '#fff' } ], [0.1, 0.1]); return fp; }
有趣的部分就说这么多,若是有什么建议和意见,欢迎留言或者私信~
之前对 animation 动画用的比较少,此次也是特意用它仔细研究一下 animation 的机制,就 animation 设置的动画可以以一种“平和”的方式进行值的变化,动画也看起来比较有条理一些;固然还有可以设置下一次动画须要作什么的操做,这个设计也很是的人性化;同时还能经过 getDataAnimation 获取对象的动画配置,并经过此方法对对象的动画进行从新配置,这些优势都是值得拿出来跟你们分享的。