基于 HTML5 Canvas 的病毒模拟视觉试验台
前言
2020 年 1 月 12 日,世界卫生组织以武汉病毒肺炎病例命名了一种病毒,2019新型冠状病毒 ( 2019-nCoV ) 。随着春运的到来,该病毒迅速的蔓延开来,大家都唯恐避之不及。病毒的爆发并不单单只有中国这人口大国,纵观整个地球,2020 年,还有很多国家也在“水深火热”中努力进行着“自救”。美国,近几个月来爆发了非常致命的流感--乙型流感病毒,据相关数据统计,到目前为止全美范围已经有超 1300 万人感染了该病毒, 12 万人住院治疗,死亡人数可能高达 6600 多人;波兰,2019 年 12 月 31 日至 2020 年 1 月 4 日,该国卢布林省和大波兰省发生 8 起 H5N8 亚型高致病性禽流感,此次疫情可能导致多达 4 万只禽类被宰杀,方圆3公里多达 35 万只家禽受到威胁;中国,农业农村新闻办公室 2 月 1 日发布,湖南省邵阳市双清区发生一起家禽 H5N1 亚型高致病性禽流感疫情,养殖户存栏肉鸡 7850 只,发病死亡 4500 只,疫情发生后,当地按照有关预案和防治技术规范要求切实做好疫情处置工作,已扑杀家禽 17828 只,全部病死和扑杀家禽均已无害化处理......在病毒面前,人类真的很脆弱,此次新型冠状病毒虽然致死率低,但传染性极强,如果传播过程中发生了可怕的变异,导致致死率提升,那么造成的后果难以估量。如果大家早期能够认识到病毒的危害,提高自我防范意识,那么就能有效的控制疫情的蔓延。此次春节在家,发现大多数的长辈都对此次疫情不以为然,依旧到处串门喝茶聊天,进出人群密集的地方时,不戴口罩,多番劝阻无果,很是无奈,依旧有部分人不了解病毒的危害。此篇文章就以 HIV 病毒为例,采用 2/3D 结合的可视化效果,直观展示病毒的微观世界。补充说明:人类免疫缺陷病毒 ( Human Immunodeficiency Virus;abbe:HIV ),即艾滋病 ( AIDS,获得性免疫缺陷综合征) 病毒,属逆转录病毒的一种。
demo: http://www.hightopo.com/demo/hiv-test-bed/
效果图:
1.HIV 活性实验台
该模块主要模拟在不同环境不同试剂的情况下,病毒活性的变化。
功能点1:左侧为实验控制台,可拖拽其值进度条来改变数值,通过一定的计算公式进而去动态修改 3D 场景中病毒的活性面板的相关显示值。
功能实现:监听 2D 图纸的交互器,在图元拖拽中进行去进行相关参数值的修改( addInteractorListener,简写为 mi ),接着通过模型中 Data 元素属性变化监听器( addDataPropertyChangeListener,简写为 md )去监听每一次参数的变化,然后通过一定的计算公式去计算活性面板的最终显示值,最后以数据驱动方式去修改活性面板的数据。
主要代码:
this.operator = { temperature: 60, humidity: 60, time: 25, sorbitol: 35, FBS: 50 } // 温度、湿度、时间、山梨醇、胎牛血清 this.g2d.dm().md(handleInterActivePanel, this); function handleInterActivePanel(e) { // 温度、湿度、时间、山梨醇、胎牛血清 if (this.operator.hasOwnProperty(e.data.getTag()) && e.property === 'a:value') { this.operator[e.data.getTag()] = e.newValue; const operator = this.operator; let node = this.g3d.dm().getDataByTag('activePanel'); let dataSource = node.a('dataSource'); let calc = [ { value: parseFloat((100 * (1 - operator.temperature / 100) * (1 - operator.time / 60) * (1 - operator.sorbitol / 100) * (1 - operator.FBS / 100) * (operator.humidity / 100) ).toFixed(2)) }, { value: parseFloat((90 * (1 - operator.temperature / 100) * (1 - operator.time / 60) * (1 - operator.sorbitol / 100) * (1 - operator.FBS / 100) * (operator.humidity / 100) ).toFixed(2)) }, { value: parseFloat((60 * (1 - operator.temperature / 100) * (1 - operator.time / 60) * (1 - operator.sorbitol / 100) * (1 - operator.FBS / 100) * (operator.humidity / 100) ).toFixed(2)) }, { value: parseFloat((10 * (operator.temperature / 100) * (operator.time / 60) * (operator.sorbitol / 100) * (operator.FBS / 100) * (1 - operator.humidity / 100) + 0.01 ).toFixed(2)) }, ] dataSource = dataSource.map((i, index) => { return { rising: i.value > calc[index].value, value: calc[index].value, } }) node.a('dataSource', []); node.a('dataSource', dataSource); } }
功能点2:放大镜查看。
功能实现:根据放大镜左侧倍数控制器的值去动态设置放大镜中图元的缩放值。
主要代码:
// 获取病毒图元 this._virusNode = virus2D.dm().getDataByTag('virusNode'); // 对图元进行缩放 function setScale(value) { this._virusNode.setScale(value, value); } this.g2d.dm().mp(function (e) { if (e.property === "a:virusScale") { if (this.virus2D) { setScale(e.newValue); this._virusNode.setScale(value, value);
} } }, this);
功能点3:病毒成分剖面示意图及其 RNA 链。 2D 及 3D 的效果展示,使微观病毒更加具象化,帮助人们更加清晰的认识病毒。
功能点4: 3D 场景中病毒的呼吸效果。
功能实现:使用 HT 的动画功能,不断的去设置病毒图元自身的缩放值。
主要代码:
let params = { duration: 10000, // 动画周期毫秒数,默认采用`ht.Default.animDuration` easing: (t) => { return t }, // 动画缓动函数,默认采用`ht.Default.animEasing` action: (v, t) => { this.virus.forEach((i, index) => { let count = 0; if (i.a('count')) { count = i.a('count'); } else { count = 0; } count += 0.5; let scale = this.virusScales[index] + 0.1 * Math.cos( (((count % 36) * Math.PI) / 180) * 10 + ((360 / this.virus.length) * index * Math.PI) / 180 ); i.eachChild(data => { data.setScale3d(scale, scale, scale); }); i.a('count', count) }) }, finishFunc: () => { if (this._continuous) { this.breating(); } }, // 动画结束后调用的函数。 } this.anim = ht.Default.startAnim(params);
2.免疫系统侵入演示
动画步骤描述:
① 病毒侵入,免疫激活
开始:场景中只有三个白细胞(两个小的白细胞离大号的较远);
过程:病毒渐显(粉色颗粒,上面无附着抗体标记);
结束:场景中只存在三个白细胞和病毒
② 白细胞释放趋化因子和增值化学物质
开始:场景中有三个白细胞和六个病毒;
过程:趋化因子从大号白细胞内部释放出来,渐显,而后另外两个白细胞向大号靠近到一定距离,然后趋化因子渐隐消失
结束:场景中存在三个白细胞(两个小的白细胞靠近大号的)、六个病毒
③ 白细胞产生抗体标记靶向细菌/病毒
开始:场景中有三个白细胞(两个小的白细胞靠近大号的)和六个病毒;
过程:抗体标记从大号白细胞里渐显飞出,最后附着在病毒上,此时出现提示面板(内容:病毒/细菌被白细胞标记抗体),最后面板渐隐
结束:场景中存在三个白细胞(两个小的白细胞靠近大号的)、六个病毒和抗体标记(附着在病毒上)
④ 白细胞吞噬靶向细胞/病毒
开始:场景中存在三个白细胞(两个小的白细胞靠近大号的)、六个病毒和抗体标记(附着在病毒上)
过程:大号白细胞出现提示面板(内容:白细胞被吸引到标记抗体处,面板渐显渐隐后,大号白细胞移动至四个病毒区域,二号白细胞移动至两个病毒区域,三号朝病毒区域中心移动轻微移动一小段,稍微停顿后,白细胞恢复初始位置,病毒、抗体标记消失
结束:场景中只存在三个白细胞
⑤ HIV 病毒侵入进入白细胞
开始:场景中存在三个白细胞
过程:出现几个病毒,然后HIV病毒渐显,再然后进入到一号白细胞内部
结束:场景中存在三个白细胞,一个 HIV 病毒,两三个粉色病毒
⑥ HIV 病毒在白细胞内复制,白细胞死亡
开始:场景中存在三个白细胞,一个 HIV 病毒(在一号白细胞内部),两三个粉色病毒
过程:HIV 病毒开始复制(体现在数量增多),然后三个白细胞同时缩小到原来的一半
结束:场景中存在三个白细胞(体积缩小),三个 HIV 病毒
⑦ HIV 病毒跑出,细菌增生免疫系统破坏成功
开始:场景中存在三个白细胞(体积缩小),三个 HIV 病毒
过程:HIV病毒跑出一号白细胞,同时白细胞渐隐直至消失,而后粉色病毒增多
结束:场景中只存在三个 HIV 病毒,多个粉色病毒
动画实现:ht.Default.startAnim 的动画函数,示例代码如下:
ht.Default.startAnim({ frames: 12, // 动画帧数 interval: 10, // 动画帧间隔毫秒数 easing: function(t){ return t * t; }, // 动画缓动函数,默认采用`ht.Default.animEasing` finishFunc: function(){ console.log('Done!') }, // 动画结束后调用的函数。 action: function(v, t){ // action函数必须提供,实现动画过程中的属性变化。 ... } });
除了以上动画外,该模块还新增了两个控制项:控制动画播放速度(修改动画的 duration 参数值)及 3D 场景的视角(修改 eye)。
实现代码:
function getPositionByZoom(arr, zoom) { return [arr[0] * zoom, arr[1] * zoom, arr[2] * zoom]; } this.g2d.dm().mp(function (e) { if (e.property === 'a:stepIndex') { // 做演示动画 this.stepIndex = e.newValue; this['anim' + (e.newValue + 1)](); } else if (e.property === 'a:screenZoom') { let value = e.newValue; if (this._eye) { let newEye = getPositionByZoom(this._eye, value); this.g3d.setEye(newEye); } } else if (e.property === 'a:playSpeed') { this.speed = 1 / e.newValue; } })
3.药物抑制原理演示
该模块主要演示生物酶抑制剂和化学消毒/去污药剂对病毒活性的影响。通过改变试剂的用量来模拟计算出病毒的活性率、复制速度、感染性、突变几率。
动画演示中涉及的 3D 图元的位移方法。通过绘制一条管道轨迹线来实现。
// 偏移动画 let g3d = this.g3d; let params = { frames: 100, // 动画帧数 interval: 30, // 动画帧间隔毫秒数 easing: (t) => { return t }, // 动画缓动函数,默认采用`ht.Default.animEasing` action: (v, t) => { let pipe; this.moveNodes.forEach((i, index) => { if (index < 2) { pipe = this.pipe1; } else { pipe = this.pipe2; } let length = g3d.getLineLength(pipe), offset = g3d.getLineOffset( pipe, length * t ), point = offset.point, px = point.x, py = point.y, pz = point.z, tangent = offset.tangent, tx = tangent.x, ty = tangent.y, tz = tangent.z; i.p3(px, py, pz); i.lookAt([px + tx, py + ty, pz + tz], 'right'); i.a('angle', t * Math.PI * 120); }) }, finishFunc: () => { if (this._continuous) { this.move(); } }, // 动画结束后调用的函数。 } this.anim = ht.Default.startAnim(params);
现在新型冠状病毒愈演愈烈,感染的人越来越多,但是很多人尤其是中老年人还没有意识到严重性,依然坚持过完年要走亲访友的观念,这走走那串串。为了避免感染新型冠状病毒,如何劝说家人不走亲访友呢?今天就来跟大家分享下。
1.告诉家人目前新型冠状病毒疫情的最新情况,告诉他们每天有多少病例增加,让他们意识到疫情的传播速度很快,很容易被感染的,如果出去走亲访友,被传染的概率会增加。
2.单纯的数字可能他们还不以为然,认为全国十几亿人口,自己“中奖几率”很低,没啥概念,这时候我们可以给他们看看更为直观的疫情地图。( http://www.hightopo.com/demo/coronavirus/ )这里面有每天最新的可视化数据,帮助大家更为直观了解当前疫情蔓延的分布趋势。
3.新闻报道!一般中老年人更相信电视上的新闻,让他们了解病毒的严重性,从而打消出门走亲访友的念头。
4.药店的相关预防药物及医用口罩等已经卖空了,让他们知道周围的人都已经在进行自身防护了,建立家人自身防范的意识,从而自觉放弃走亲访友。
5.告知各地封村封路的消息,让他们知道疫情的严重性。
6.给他们看些硬核标语。
- 口罩还是呼吸机,您老看着二选一;
- 发烧不说的人,都是潜伏在人民群众中的阶级敌人;
- 老实在家防感染,丈人来了也得撵;
- 今年过年不串门,来串门的是敌人,敌人来了不开门;
- 串门就是互相残杀,聚会就是自寻短见;
- 现在请吃饭的都是鸿门宴
- ......
这个春节,一场突如其来的疫情防控阻击战,在中华大地骤然打响,这是一场没有硝烟的战争,无论是医护人员,还是基础工作者,他们在疫情爆发的那一刻,就拿起了“武器”奔赴“战场一线”。病毒并不会因为他们是医护人员而“网开一面”,岁月静好,是因为有人在为我们负重前行,感谢那些在疫情中为我们奔赴前行的人,在疫情面前,我们没有一个人能置身事外。“宅”在家,这是对自己负责,对他人负责,更是对社会、对国家最大的支持。中华儿女从不畏惧任何困难,不会退缩,我们坚信这场战争我们肯定能赢,也必须要赢。
基于 HTML5 Canvas 的病毒模拟视觉试验台的更多相关文章
- 基于HTML5 Canvas和jQuery 的绘图工具的实现
简单介绍 HTML5 提供了强大的Canvas元素.使用Canvas并结合Javascript 能够实现一些很强大的功能.本文就介绍一下基于HTML5 Canvas 的绘图工具的实现.废话少说,先看成 ...
- 基于HTML5 Canvas实现的图片马赛克模糊特效
效果请点击下面网址: http://hovertree.com/texiao/html5/1.htm 一.开门见山受美国肖像画家Chuck Close的启发,此脚本通过使用HTML5 canvas元素 ...
- 基于html5 canvas和js实现的水果忍者网页版
今天爱编程小编给大家分享一款基于html5 canvas和js实现的水果忍者网页版. <水果忍者>是一款非常受喜欢的手机游戏,刚看到新闻说<水果忍者>四周年新版要上线了.网页版 ...
- 基于HTML5 Canvas的线性区域图表教程
之前我们看到过很多用jQuery实现的网页图表,有些还是比较实用的.今天我们来介绍一款基于HTML5 Canvas的线性区域图表应用,这个图表应用允许你使用多组数据来同时展示,并且将数据结果以线性图的 ...
- 基于HTML5 Canvas的网页画板实现教程
HTML5的功能非常强大,尤其是Canvas的应用更加广泛,Canvas画布上面不仅可以绘制任意的图形,而且可以实现多种多样的动画,甚至是一些交互式的应用,比如网页网版.这次我们要来看的就是一款基于H ...
- 基于HTML5 Canvas实现用户交互
很多人都有这样的疑问,基于HTML5 Canvas实现的元素怎么和用户进行交互?在这里我们用到HT for Web(http://www.hightopo.com/guide/guide/core/b ...
- 基于html5 Canvas图表库 : ECharts
ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表.创新的拖拽重计算.数据视图.值 ...
- 基于html5 canvas 的客户端异步上传图片的插件,支持客户端压缩图片尺寸
/** * Created by xx on 15-05-28. * 基于html5 canvas 的客户端异步上传画片的插件 * 在实际应用中,常常要用于上传图片的功能.在现在越来越多的手机weba ...
- 基于 HTML5 Canvas 的智能安防 SCADA 巡逻模块
基于 HTML5 Canvas 的智能安防 SCADA 巡逻模块 前言 最近学习了 HT for Web flow 插件,除了正常的 flow 效果,其中还有两个十分好用的两个接口 getPercen ...
随机推荐
- FUTABA舵机参数大全
S9150 Digital servo 尺寸:47.5X27X25.3mm 重量:53g 速度:0.18sec/60"(4.8V) 扭力:5.8kg:cm(4.8V) ——————————— ...
- 关于java php go 中AES加解密秘钥长度问题
今天心血来朝,想用go把php中的一个小功能重写一下,但在解密aes加密的数据时碰到了个坑! php的mcrypt拓展(貌似php7.1版本以上不支持了)提供了aes的加解密: 而且php aes 的 ...
- 0x80070035找不到网络路径
如果这个报错发生:自己的网络正常,其他人可以正常访问服务器,而自己无法访问服务器.原因就是TCP/IP NetBIOS Helper服务被停止. 打开services.msc,启动此服务即可. 该服务 ...
- Spring Boot 入门(十一):集成 WebSocket, 实时显示系统日志
以前面的博客为基础,最近一篇为Spring Boot 入门(十):集成Redis哨兵模式,实现Mybatis二级缓存.本篇博客主要介绍了Spring Boot集成 Web Socket进行日志的推送, ...
- 【Java并发基础】Java内存模型解决有序性和可见性
前言 解决并发编程中的可见性和有序性问题最直接的方法就是禁用CPU缓存和编译器的优化.但是,禁用这两者又会影响程序性能.于是我们要做的是按需禁用CPU缓存和编译器的优化. 如何按需禁用CPU缓存和编译 ...
- ORM 效率补充
1.only defer only: 获取数据表中某列或多列的值,注意获取的是对象,如果查询字段不是括号内的,效率反而变低 defer: 获取除了某列或某几列的数据,注意获取的是对象 User.ob ...
- SSM框架整合中,不报错,数据库只能存ID进去问题解决
嗯,这个错误其实不能算错误,是粗心造成的,在配置文件中对于传递的参数没有写#字符,直接写的的属性名.居然错了两次,哎!!! 嗯,还有一个问题,在动态SQL中,if标签中test属性中判断时,不能用大写 ...
- 安装mysql遇到的问题
想在自己的PC上安装mysql服务器,首先在官网下载mysql的安装文件. MySQL安装文件分两种 .msi和.zip ,.msi需要安装,.zip文件需要配置环境变量. 我首先下载的是不需要安装的 ...
- 解决python爬虫requests.exceptions.SSLError: HTTPSConnectionPool(host='XXX', port=443)问题
爬虫时报错如下: requests.exceptions.SSLError: HTTPSConnectionPool(host='某某某网站', port=443): Max retries exce ...
- 18年第一弹射 和网络有关; 艾曲塞嗯诶系列篇 one
1:当指定接口运行在RIP2组播方式时,以下说法正确的是 2个答案 A 只接收RIPv2组播报文 B 不接收RIPV1 广播报文 2 下面哪条命令是把PPP的认证方式设置为PAP? C ppp au ...