HTML5 WebGLを用いた医療用物流システム
前置き
IoT(Internet of Things)とは、簡単に言うと、インターネットを介してモノとモノがつながることです。世の中のあらゆるものが、データの変化によってインテリジェントに管理できるようになります。IoTの台頭は、医療業界において命を救う可能性を持っています。
IoTは、ユーザーの情報を収集し、リアルタイムで診断していくため、間違いなく医療に包括的な未来をもたらすでしょう。ここでは、私が最近構築した医療用物流システムを見てみましょう。
htのオフィシャルサイトにリンクします。 http://www.hightopo.com/cn-index.html
デモへのリンクです。
https://www.hightopo.com/demo/pivas/
実装プロセス
光源の追加
実は元のシーンは全体的にとても暗いので、ライティング効果で全体を照らし、現実のシーンに近づける必要がありました。
比較して見ましょう。
光のいくつかの属性。
typeは光の種類を表します
colorは光の色を表します。
intensityは光の強さ(1が最大)
range は範囲を表します。
addLight() {
const skyBox = this.dm.getDataByTag('skyBox')
// Limit the view to the sky ball
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. ノード(対応する要素)
2.fn(アニメーション実行後のコールバックを行う関数)。
3.コンフィグ(アニメーションの設定)
4.coord(方向軸)
// Walk animation
walkAnim(node, fn, config, coord) {
const { duration, space } = config
const positionArray = node.p3()
let isShadow = false
let ShadowNode = null
// If the moving element is an icu cart or supply cart, get its shadow to follow the element
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 (coordinate === '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 adsorption法(吸着:ノードがホストを指定し、ホストがノードに影響を与える変更を行う)を使用しています。
これが非常に適切なシナリオはたくさんあります。エレベーターに医療キットと周波数表を載せて上下させる必要があるのですが、キットをコンベヤーに乗せるとキットは動かなければならず、本当にコンベヤーがキットを動かしているように感じられるのです。
ここで説明するパラメータは
1. ノード(操作するエレベータ要素)
2. medicalKit(医療キット)
3. fn(アニメーション実行後にコールバックを行う関数)。
4.status(エレベーターが上下している状態)
5.コンフィグ(アニメーション設定)
// Elevator lift animation
elevatorAnim(node, medicalKit, fn, status, config) {
const self = this
// Get the index of the elevator so that the corresponding frequency table moves with it
const elevatorIndex = node.getTag().replace(/[^0-9]/ig, '') - 0
// Get the index of the medical kit to control the distance of the elevator lift
const medicalKitIndex = medicalKit.getTag().replace(/[^0-9]/ig, '') - 0
const positionArray = node.p3()
const station = self.dm.getDataByTag(`station${elevatorIndex}`)
//Absorb hosts
station.setHost(node)
medicalKit.setHost(node)
// Set the elevator state
if (elevatorIndex === 3) self.elevatorRunning = true
// the lifting distance is down when the status is 0 the distance to the lowest part is fixed so you only need to control the rising distance
const medicalKitLevel = self.returnMedicalKitLevel(medicalKitIndex)
// Properties of the elevator
// the position of the lowest point Lowest
// If there is a track, go to the position of the track, otherwise follow the number of levels orbitalP
// position of the first floor 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
}
// The medical kit does not do anything when it is down
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();
}
});
イベントリスニング(Publish、Subscribe)
なぜなら、現在の何らかのアニメーションの終了をリッスンし、カメラシフトを実行する必要があるからです。
このように、1つ目の3Dシーンのキューテキストアニメーションの終了をリッスンして、2つ目の3Dシーンの表示を実行する必要があるのです。この2つは別のシーンなので、コールバックではリスニングできないので、ここではイベントバスのeventBusを使用しています。
ここでは、eventBusの使い方を説明します。第1引数にリッスンする登録関数名、第2引数にコールバック関数を指定します。
// eventbus Listening for events
eventbus.on('animation1', _ => {
const medical = dm.getDataByTag('medicalKit1')
renderView(medical, dm, gv)
})
ここでは、eventBusの発火を利用しています。最初のパラメータはトリガーする関数名、2番目はその関数に発火させるパラメータを表します。
// Trigger the event
eventbus.emit("animation1", null);
概要
このデモをやってみて、HT for Webを使いこなせるようになっただけでなく、Internet of Thingsについても理解が深まりました。
自分の技術によって、人々の暮らしに役立つもの、より良いものを作ることができる時代に、フロントエンドに携わる者として、とても誇らしい気持ちになりました。
私のデモを見て、インスピレーションを得るとともに、不可能を可能にし、社会に貢献できることを信じてほしいです。
関連
-
キャンバスをベースにしたHTML5で電子署名を実現、PDF文書も生成可能
-
HTML5 Blobオブジェクトの使用方法
-
html5 コロンセパレータのアライメント実装
-
キャンバスの描画は、contain または cover モードで適応され、中央に配置されます。
-
Canvasシリーズのフィルター効果
-
画像リソースが同一ドメイン下にないために、キャンバスがクロスドメインで汚染される場合の解決策
-
HTML5 postMessage使用マニュアル
-
キャンバスで簡単なポスターを描くお手本
-
html2 canvasで印刷用の鮮明な画像を生成
-
ベッセル曲線の軌跡アニメーションのためのCanvasサンプルコード
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
キャンバスが折り畳みパスを描くアニメーション
-
画像アップロードとキャンバス圧縮処理の解析
-
携帯電話のHtml5を達成するためにカメラのメソッドを呼び出すには
-
4種類のプログラムの画面適応に応じたモバイルh5ページを説明する。
-
キャンバスのマウスがアニメーションの背景に従うことを達成するために5分
-
キャンバスを使ってWeChatアバターなしの招待状ポスターを生成する
-
HTML表示 pdf, word, xls, ppt方式例
-
高さ調整可能なテキストエリアを作成するサンプルコード
-
H5では、ダイナミックなグラフィックス機能を実現するために、キャンバスの最も強力なインタフェース
-
ivxプラットフォーム開発:9箱の抽選機能をコードレスで実装する。