webgl api 源码(基于 HTML5 WebGL 实现的医疗物流系统)
webgl api 源码
基于 HTML5 WebGL 实现的医疗物流系统前言
物联网( IoT ),简单的理解就是物体之间通过互联网进行链接。世界上的万事万物,都可以通过数据的改变进行智能化管理。IoT 的兴起在医疗行业中具有拯救生命的潜在作用。
不断的收集用户信息并且实时的进行诊断,所以未来 IoT 肯定在医疗行业的应用会呈覆盖性。下面是我最近做的一个医疗物流系统,用来观察医疗物流过程。
ht官网链接:http://www.hightopo.com/cn-index.html
demo链接: https://www.hightopo.com/demo/pivas/
实现过程
增加光源
整个原场景其实是非常暗的,所以需要使用灯光的效果照亮整个场景,使其接近真实世界的场景。
我们看下对比。
light 的一些属性:
type 代表灯光的类型
color 代表灯光的颜色
intensity 代表灯光的强度(1是最大值)
range 代表范围
addLight() { const skyBox = this.dm.getDataByTag('skyBox') // 限制视野在天空球之内 this.gv.setSkyBox(skyBox) const light = new ht.Light() const lightSource = this.dm.getDataByTag('sunlight').p3() const config = { 'light.type': 'point', 'light.color': 'white', 'light.intensity': 0.3, 'light.range': 10000 } light.s(config) light.p3(lightSource)this.dm.add(light) }
看向物体
看到左下角的一个小窗口,其实是另一个3d场景,把它定位到左下角的,两个场景都使用了反序列化( deserialize )。
因为要定位医疗箱移动,所以这里使用到了 flyTo 方法 。
var renderCanvas = function (medical, duration) { ht.Default.startAnim({ duration, easing(v, t) { return t }, action(v, t) { outScreenG3d.flyTo(medical, { direction: [-5, 3, 5], distance: 300 }) } }) }
封装动画
如果要实现这么多的动画,首先想到的是一个个物体进行移动的过程。医疗箱的行走、电梯的升降、传送带运送医疗箱等我们都可以对它们的动作进行封装。
如图可以看到医疗箱总是在动,所以定义了一个行走的动画,每次医疗箱行走的距离、行走方向、动画的配置都进行传参。
这里要说明的参数:
1.node(对应的元素)
2.fn(动画执行完进行回调的函数)
3.config(动画配置)
4.coord(方向轴)
// 行走动画 walkAnim(node, fn, config, coord) { const { duration, space } = config const positionArray = node.p3() let isShadow = false let ShadowNode = null // 如果移动的元素是icu车或者供应车的话 获取它的阴影跟随元素移动 if (node.getTag() === 'supply' || node.getTag() === 'icuCar') { isShadow = true ShadowNode = this.dm.getDataByTag(`${node.getTag()}Shadow`) } ht.Default.startAnim({ duration, easing: function (t) { return t }, action(v, t) { if (coord === 'x') { node.p3(positionArray[0] + t * space, positionArray[1], positionArray[2]) isShadow && ShadowNode.p3(positionArray[0] + t * space, positionArray[1], positionArray[2]) } else if (coord === 'y') { node.p3(positionArray[0], positionArray[1] + t * space, positionArray[2]) isShadow && ShadowNode.p3(positionArray[0], positionArray[1] + t * space, positionArray[2]) } else { node.p3(positionArray[0], positionArray[1], positionArray[2] + t * space) isShadow && ShadowNode.p3(positionArray[0], positionArray[1], positionArray[2] + t * space) } }, finishFunc() { typeof fn === 'function' && fn(node) } }) }
物体之间的影响
电梯的升降会影响很多东西,比如频台的移动会带着传送带和医疗箱,这里我用到了 sethost 吸附方法(吸附:节点指定宿主,宿主进行改变会影响节点)。
很多场景下非常合适,我需要电梯升降的过程中带用医疗箱和频台一起上升,还有医疗箱放到传送带的时候,医疗箱要动起来,感觉是这真的传送带在带动医疗箱进行运动。
这里要说明的参数:
1.node(操作的电梯元素)
2.medicalKit(医疗箱)
3.fn(动画执行完进行回调的函数)
4.status (电梯上升和下降的状态)
5.config(动画配置)
// 电梯升降动画 elevatorAnim(node, medicalKit, fn, status, config) { const self = this // 获取电梯的index 让对应的频台也跟着动 const elevatorIndex = node.getTag().replace(/[^0-9]/ig, '') - 0 // 获取医疗箱的index 控制电梯升降的距离 const medicalKitIndex = medicalKit.getTag().replace(/[^0-9]/ig, '') - 0 const positionArray = node.p3() const station = self.dm.getDataByTag(`station${elevatorIndex}`) //吸附宿主 station.setHost(node) medicalKit.setHost(node) // 设置升降状态 if (elevatorIndex === 3) self.elevatorRunning = true // 升降距离 status 为 0 的时候是下降 最低部位的距离是固定的 所以只需要控制上升的距离 const medicalKitLevel = self.returnMedicalKitLevel(medicalKitIndex) // 电梯的属性 // 最低点的位置 Lowest // 如果有轨道的话 就去轨道的位置 否则就按照层数 orbitalP // 第一层的位置 distance let space const addSpace = medicalKitIndex === 7 ? 100 : 0 if (status == 1) { space = config.orbitalP ? config.orbitalP : config.distance + addSpace + (400 * medicalKitLevel) } else { space = config.Lowest } // 下降状态时 医疗箱不会做动作 if (status === 0) { medicalKit.setHost() } return ht.Default.startAnim({ duration: config.orbitalP ? 2000 : (medicalKitLevel === 0 && elevatorIndex == 3 ? 700 : 2500 + (medicalKitLevel * 1000)), action(v, t) { node.p3( positionArray[0], positionArray[1] + ((space - positionArray[1]) * t), positionArray[2] ) }, finishFunc() { station.setHost() typeof fn === 'function' && fn(node) } }) }
动画方法
动画的过程中有个问题需要处理就是等待电梯的动画,医疗箱在动画过程中,需要判断电梯是否在上升,如果不在地面的话,需要等待。
我的思路是,当医疗箱走到离电梯一点距离的时候,需要判断电梯是否在上升状态,如果是的话,需要调用动画暂停的方法。
当 elevatorRunning 为 false 的时候代表电梯没有运动,否则在运动中。
电梯动画开始的时候设置为 true,结束后设置变量为 false, 就可以监控它的状态了。
ht.Default.startAnim 方法返回一个实例,利用 action 方法, 实现轮询监听动画状态,然后进行操作。
当 elevatorRunning 为 true 的话, 使用 anim.pause() 暂停当前动画。
当 elevatorRunning 为 false 的话, 使用 anim.resume() 继续当前动画。
const anim = ht.Default.startAnim({ duration, action(v, t) { node.p3( positionArray[0], positionArray[1], positionArray[2] - (tpMax - positionArray[2]) * t ); if (index > 1 && self.elevatorRunning === true) { if (node.p3()[2] <= stopMax) { anim.pause(); const t = setInterval(() => { if (self.elevatorRunning === false) { anim.resume(); clearInterval(t); } }, 100); } } }, finishFunc() { typeof fn === "function" && fn(); } });
事件监听(发布、订阅)
因为需要监听某个当前动画的结束,然后进行相机位移。
如图,我需要监听第一个 3d 场景中显示提示文字动画结束,然后执行第二个 3d 场景的显示。因为2个是不同的场景,是不能用回调的方法监听到的,所以这里就用到了 eventBus 事件总线。
下面是 eventBus 的使用,第一个参数代表要监听的注册函数名,第二个是回调函数。
// 事件总线 监听事件 eventbus.on('animation1', _ => { const medical = dm.getDataByTag('medicalKit1') renderView(medical, dm, gv) })
下面是 eventBus 发射的使用,第一个参数代表要触发的函数名,第二个是发射给函数的参数。
// 触发事件 eventbus.emit("animation1", null);
总结
做完这个 demo 之后,除了对 HT for Web 更加熟练之外,对物联网也有了更深刻的概念。
我身为一名前端工作者,在这个时代感觉非常的自豪,因为我能通过自己的技能创造出许多能造福和改善人们生活的东西。
希望大家看到我的 demo 能够得到一些启发,同时也要相信自己能够创造不可能,为社会做出贡献。
- html5实时通讯(使用Html5 Stream开发实时监控系统)
- vscode快速生成html框架(VSCode 自定义html5模板的实现)
- html5怎么将字体变为红色(Html5自定义字体解决方法)
- html5移动app开发实战(html5启动原生APP总结)
- html5怎么设置倾斜(HTML5 body设置自适应全屏)
- 用html5的canvas绘制剪裁图像(Html5 canvas画图白板踩坑)
- html5canvas怎么改扇形起始角(HTML5 Canvas实现放大镜效果示例)
- html5基础知识入门(萌新HTML5 入门指南二)
- html5怎么设置左边input(HTML5中input输入框默认提示文字向左向右移动的示例代码)
- html5基本标签详解(详解HTML5布局和HTML5标签)
- html5 布局设计(Html5导航栏吸顶方案原理与对比实现)
- html5浏览界面怎么设置(HTML5textarea高度自适应的两种方案)
- html5布局(Html5让容器充满屏幕高度或自适应剩余高度的布局实现)
- html5如何控制内容(html5拖拽应用记录及注意点)
- html5页面传值表(html5的pushstate以及监听浏览器返回事件的实现)
- HTML5 <abbr>标签
- 三人行,她们是育人路上的 铁三角 团队(她们是育人路上的)
- 阴阳师 孟婆山兔CP不倒 新皮肤草稿 孟婆兔 让痒痒鼠点赞(阴阳师孟婆山兔CP不倒)
- 阴阳师孟婆御魂推荐 孟婆御魂搭配毕业套(阴阳师孟婆御魂推荐)
- 袁冰妍终于接到新剧,饰演反追男主,看到合作演员 眼光果然毒辣(袁冰妍终于接到新剧)
- 记忆中的台词(记忆中的台词)
- 袁冰妍轧戏 拍《琉璃》的同时还在拍《将夜》,难怪被骂演技差(拍琉璃的同时还在拍将夜)
热门推荐
- axios调用接口(如何实现axios的自定义适配器adapter)
- 获取数据库中所有的索引信息
- SQLServer数据库从高版本降级到低版本实例详解(SQLServer数据库从高版本降级到低版本实例详解)
- knn算法详细步骤(Python实现KNNK-近邻算法的示例代码)
- css 三级层级菜单(利用CSS3实现动态的二级三级菜单效果实例源码)
- centos7.6 安装docker(Centos7安装Docker2020最新亲测可用,直接复制粘贴即可)
- 前端单行文本垂直居中(移动端的text-overflow多行文本溢出显示省略号…)
- 怎么样才知道云服务器够不够用(新手应该怎么选择云服务器才能避免被坑?)
- sqlserver 比较日期(解析SQL Server中SQL日期转换出错的原因)
- 云服务器可以自己建网站吗(自己建网站怎么选择服务器)