基于 HTML5 WebGL 实现的医疗物流系统


Posted in HTML / CSS onOctober 08, 2019

前言

物联网( IoT ),简单的理解就是物体之间通过互联网进行链接。世界上的万事万物,都可以通过数据的改变进行智能化管理。IoT 的兴起在医疗行业中具有拯救生命的潜在作用。
不断的收集用户信息并且实时的进行诊断,所以未来  IoT 肯定在医疗行业的应用会呈覆盖性。下面是我最近做的一个医疗物流系统,用来观察医疗物流过程。

基于 HTML5 WebGL 实现的医疗物流系统

ht官网链接:http://www.hightopo.com/cn-index.html

demo链接: https://www.hightopo.com/demo/pivas/
 

实现过程

增加光源

 整个原场景其实是非常暗的,所以需要使用灯光的效果照亮整个场景,使其接近真实世界的场景。

 我们看下对比。

基于 HTML5 WebGL 实现的医疗物流系统

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 )。

基于 HTML5 WebGL 实现的医疗物流系统

 因为要定位医疗箱移动,所以这里使用到了 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)
            }
        })
    }

 

动画方法

 动画的过程中有个问题需要处理就是等待电梯的动画,医疗箱在动画过程中,需要判断电梯是否在上升,如果不在地面的话,需要等待。

基于 HTML5 WebGL 实现的医疗物流系统

 我的思路是,当医疗箱走到离电梯一点距离的时候,需要判断电梯是否在上升状态,如果是的话,需要调用动画暂停的方法。

 当 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 能够得到一些启发,同时也要相信自己能够创造不可能,为社会做出贡献。

HTML / CSS 相关文章推荐
利用CSS3实现自定义滚动条代码分享
Aug 18 HTML / CSS
可以随进度显示不同颜色的css3进度条分享
Apr 11 HTML / CSS
css3实例教程 一款纯css3实现的发光屏幕旋转特效
Dec 07 HTML / CSS
CSS3中新增的对文本和字体的设置
Feb 03 HTML / CSS
CSS3 input框的实现代码类似Google登录的动画效果
Aug 04 HTML / CSS
纯CSS3实现圆圈动态发光特效动画的示例代码
Mar 08 HTML / CSS
HTML5 Canvas API中drawImage()方法的使用实例
Mar 25 HTML / CSS
将HTML5 Canvas的内容保存为图片借助toDataURL实现
May 20 HTML / CSS
HTML5视频支持检测(检查浏览器是否支持视频播放)
Jun 08 HTML / CSS
HTML5实现一个能够移动的小坦克示例代码
Sep 02 HTML / CSS
canvas如何实现多张图片编辑的图片编辑器
Mar 10 HTML / CSS
CSS 新特性 contain控制页面的重绘与重排问题
Apr 30 HTML / CSS
html2canvas生成清晰的图片实现打印的示例代码
Sep 30 #HTML / CSS
html5视频媒体标签video的使用方法及完整参数说明详解
Sep 27 #HTML / CSS
Html5实现首页动态视频背景的示例代码
Sep 25 #HTML / CSS
HTML5自定义元素播放焦点图动画的实现
Sep 25 #HTML / CSS
使用Html5中的cavas画一面国旗
Sep 25 #HTML / CSS
关于canvas绘制模糊问题的解决方法
Sep 24 #HTML / CSS
html svg生成环形进度条的实现方法
Sep 23 #HTML / CSS
You might like
利用js调用后台php进行数据处理原码
2006/10/09 PHP
php empty,isset,is_null判断比较(差异与异同)
2010/10/19 PHP
php错误级别的设置方法
2013/06/17 PHP
微信公众号支付之坑:调用支付jsapi缺少参数 timeStamp等错误解决方法
2016/01/12 PHP
PHPMailer ThinkPHP实现自动发送邮件功能
2018/06/10 PHP
Prototype使用指南之array.js
2007/01/10 Javascript
javascript 进度条 实现代码
2009/07/30 Javascript
从零开始学习jQuery (二) 万能的选择器
2010/10/01 Javascript
文本有关的样式和jQuery求对象的高宽问题分别说明
2013/08/30 Javascript
jquery实现的鼠标下拉滚动置顶效果
2014/07/24 Javascript
jQuery插件pagewalkthrough实现引导页效果
2015/07/05 Javascript
浅析nodejs实现Websocket的数据接收与发送
2015/11/19 NodeJs
JavaScript控制输入框中只能输入中文、数字和英文的方法【基于正则实现】
2017/03/03 Javascript
代码详解JS操作剪贴板
2018/02/11 Javascript
使用JSON格式提交数据到服务端的实例代码
2018/04/01 Javascript
Vue全局分页组件的实现代码
2018/08/10 Javascript
微信小程序实现文字跑马灯
2020/05/26 Javascript
使用VUE+iView+.Net Core上传图片的方法示例
2019/01/04 Javascript
javascript网页随机点名实现过程解析
2019/10/15 Javascript
python中使用urllib2伪造HTTP报头的2个方法
2014/07/07 Python
Python中threading模块join函数用法实例分析
2015/06/04 Python
Python实现身份证号码解析
2015/09/01 Python
Python 基础之字符串string详解及实例
2017/04/01 Python
Python基于回溯法子集树模板解决0-1背包问题实例
2017/09/02 Python
Linux-ubuntu16.04 Python3.5配置OpenCV3.2的方法
2018/04/02 Python
如何利用python制作时间戳转换工具详解
2018/09/12 Python
浅析Python 读取图像文件的性能对比
2019/03/07 Python
简单了解python的break、continue、pass
2019/07/08 Python
Python 制作查询商品历史价格的小工具
2020/10/20 Python
印尼最大的在线购物网站:MatahariMall.com
2016/08/26 全球购物
this关键字的含义
2015/04/08 面试题
申报职称专业技术个人的自我评价
2013/12/12 职场文书
幼儿园教师培训制度
2014/01/16 职场文书
公务员更新知识培训实施方案
2014/03/31 职场文书
通知书大全
2015/04/27 职场文书
董事长开业致辞
2015/07/29 职场文书