Saya sedang dalam perjalanan bisnis beberapa hari yang lalu dan melihat panel pemantauan di atas kepala di pesawat. Selain memutar serial TV dan iklan, juga akan beralih ke sistem pemantauan untuk navigasi pesawat dari waktu ke waktu sistemnya terasa agak kasar, jadi saya ingin membuat versi upgrade dari sistem pemantauan menggunakan HT untuk Web. Demonya cukup bagus, jadi saya ingin membagikannya kepada Anda agar kita bisa saling belajar.
demo
Proses implementasiBerjalan melalui efek awan
Untuk mendapatkan efek pesawat terbang menembus awan, masalah pertama yang saya temui adalah pelapisan penerbangan pesawat, yang biasa disebut efek perspektif. Di sini saya menggunakan saluran awan dan latar belakang awan untuk mengalir dengan kecepatan berbeda untuk menciptakan efek perspektif terbang.
Saya menampilkan awan dalam bentuk tekstur, tetapi tekstur tersebut saja yang akan menghalangi langit dan pesawat, yang akan sangat mempengaruhi tampilan dan nuansa pesawat terbang, jadi saya mengaktifkan transparansi dan opacity dari elemen grafis yang sesuai, dan mengatur tingkat transparansi yang berbeda untuk latar belakang awan dan saluran awan. Tidak hanya menambah kesan berlapis, namun juga memberikan ilusi awan yang melayang di depan mata mereka.
Saluran cloud menggunakan tipe ht.Polyline. Penskalaan saluran memperbesar proporsi sumbu Y, memberikan saluran cloud ruang vertikal yang lebih besar. Menyetel salinan terbalik.flip memungkinkan tekstur ditampilkan di dalam saluran cloud, seperti jika pesawat berada di udara. Bepergian melalui lautan awan; latar belakang awan mengadopsi tipe ht.Node, dan hanya satu permukaan yang diatur untuk ditampilkan sebagai latar belakang awan.
Efek aliran awan keseluruhan dicapai dengan menggunakan offset offset, dan offset tekstur dari permukaan primitif atau primitif yang sesuai diubah untuk mencapai efek pesawat terbang melalui awan.
var i = 1, p = 0;setInterval(() => { i -= 0,1; p += 0,005; cloud.s('shape3d.uv.offset', [i, 0]); cloudBackground.s(' semua.uv.offset', [p, 0]);}, 100);Efek mengangkat benjolan
Walaupun memberikan efek seperti pesawat terbang menembus awan, namun jika pesawat hanya terbang lurus juga akan mengurangi sensasi terbang yang sebenarnya. Saya yakin teman-teman yang pernah terbang dengan pesawat pasti pernah mengalami turbulensi yang disebabkan oleh aliran udara, dan sering kali merasakan turbulensi akibat penerbangan pesawat. Naik turunnya perjalanan sebenarnya karena jalur pesawat tidak selalu tetap pada ketinggian tertentu, kadang naik dan kadang turun, jadi saya menggunakan ekstensi animasi HT ht-animation.js -in untuk mendapatkan efek bergelombang pada pesawat. Kodenya adalah sebagai berikut :
dm.enableAnimation(20);plane.setAnimation({ back1: { dari: 0, ke: 160, easing: 'Cubic.easeInOut', durasi: 8000, selanjutnya: up1, onUpdate: function (value) { value = parseInt( nilai); var p3 = ini.p3(); ini.p3(nilai, p3[1], p3[2] } }, //...Hilangkan permulaan serupa: [back1]}); Pembatasan sudut pandang sektor bolaSetelah efek penerbangannya disempurnakan, saya menemui masalah yang lebih sulit, karena meskipun pesawat sebenarnya terbang melintasi lautan awan, ia hanya terbang di saluran, dan latar belakangnya sebenarnya hanya tekstur datar, jadi ketika perspektif mencapai titik tertentu Ketika level ini tercapai, akan ada rasa disonansi dan ketidaknyataan yang kuat, dan diperlukan batasan sudut pandang untuk melakukan penyesuaian sudut pandang dalam rentang tertentu.
Batasan sudut pandang umumnya membatasi mata dan bagian tengah g3d. Teman-teman yang belum tahu banyak tentangnya dapat membaca manual 3D di situs resmi hightopo, yang memiliki petunjuk detailnya di sini; rentang sudut, saya memutuskan Untuk memperbaiki posisi tengah, kodenya adalah sebagai berikut:
g3d.addPropertyChangeListener(e => { // Memperbaiki titik pusat if (e.property === 'center') { e.newValue[0] = center[0]; e.newValue[1] = center[1]; e.newValue[2] = tengah[2]; }}Kemudian batasi mata pada rentang tertentu dan selesai. Namun, tidak sesederhana itu di sini. Awalnya saya membatasi mata pada ruang kubik, tetapi efek interaksinya tidak ideal, mengingat dalam interaksi default g3d , mouse Saat menyeret dan menggeser untuk mengubah perspektif, mata sebenarnya bergerak pada permukaan bola dengan pusat sebagai pusatnya, jadi saya memutuskan untuk menggali ruang terbatas untuk mata dari bola, yang merupakan sektor bola. Bagi yang belum paham bisa lihat gambar ini :
Batas sudut pandang berbentuk kipas bola memerlukan total tiga parameter yaitu sumbu acuan pusat, sudut antara sumbu tengah dengan tepi luar, dan radius terbatas bola Garis perpanjangan yang menghubungkan mata awal dan pusat, serta letak radius terbatas bola dibagi menjadi batas maksimum dan batas minimum.
function limitEye(g3d, eye, center, options) { var limitMaxL = options.limitMaxL, limitMinL = options.limitMinL, limitA = options.limitA; == 'pusat') { e.newValue[0] = pusat[0]; e.newValue[1] = pusat[1]; e.newValue[2] = center[2]; } // Batasi sudut pandang if (e.property === 'eye') { var newEyeV = new ht.Math.Vector3(e.newValue), centerV = new ht.Math.Vector3(tengah), refEyeV = baru ht.Math.Vector3(mata), refVector = refEyeV.clone().sub(centerV), newVector = newEyeV.clone().sub(centerV); if (centerV.distanceTo(newEyeV) > limitMaxL) { newVector.setLength(limitMaxL); e.newValue[0] = e.newValue[1] = newVector.y; e.newValue[2] = newVector.z; } if (centerV.distanceTo(newEyeV) < limitMinL) { newVector.setLength(limitMinL); e.newValue[0] = newVector.x; e.newValue[1] = newVector.y; refVector) > limitA) { var oldLength = newVector.length(), oldAngle = newVector.angleTo(refVector), refLength = panjang lama * Math.cos(oldAngle), vertVector, realVector, realEye; refVector.setLength(refLength); newEyeV = newVector.clone().add(centerV); vertVector = newEyeV.clone().sub(refEyeV); vertLength = refLength * Math.tan(limitA); vertVector.setLength(vertLength); realVector = vertVector.clone().add(refEyeV).sub(centerV); realVector.setLength(oldLength); .add(centerV); // Cegah sudut pergerakan lebih dari 180 derajat dan balikkan perspektif jika (oldAngle > Matematika.PI / 2) { realEye.negate(); } e.newValue[0] = realEye.x; e.newValue[1] = realEye.y; )} sistem pemantauan pesawatTentu saja, sebagai sistem pemantauan, wajar jika ada pemantauan. Tambahkan peta kecil di pojok kanan bawah dan sediakan tiga mode: fokus pada pesawat, fokus pada lintasan penerbangan dan fokus pada peta, serta mengontrol efek aliran. lintasan penerbangan sesuai dengan arah terbang pesawat. Diantaranya Fokus pada pesawat akan mengikuti pergerakan pesawat dan melakukan fitData agar pesawat selalu berada di tengah mini map.
var fitFlowP = function (e) { if (e.property === 'position' && e.data === plane) { mapGV.fitData(plane, false }};buttonP.s({ 'interaktif': benar, 'onClick': fungsi (peristiwa, data, tampilan, titik, lebar, tinggi) { map.a('fitDataTag', 'plane2D'); mapDM.md(fitFlowP); }});buttonL.s({ 'interaktif': true, 'onClick': fungsi (peristiwa, data, tampilan, titik, lebar, tinggi) { mapDM.umd(fitFlowP); peta. a('fitDataTag', 'flyLine'); mapGV.fitData(flyLine, false }});// ...dihilangkanMenambahkan perintah untuk menggerakkan mouse ke posisi pesawat yang sesuai untuk menamainya, klik dua kali untuk menampilkan panel informasi dari posisi pesawat yang sesuai dan memfokuskan perspektif pada panel, mengklik di mana saja pada pesawat untuk beralih kembali ke mode penerbangan pesawat, dan efek lainnya.
Menambahkan panel pemantauan di sebelah kiri menggantikan klik dua kali pada posisi terkait, yang secara langsung berfokus pada panel informasi di posisi terkait. Tombol di sini mengaktifkan interaksi dan menambahkan logika interaksi yang sesuai. Kodenya adalah sebagai berikut:
button_JC.s({ 'interaktif': true, 'onClick': fungsi (peristiwa, data, tampilan, titik, lebar, tinggi) { event.preventDefault(); misalkan g3d = G.g3d, g3dDM = G.g3d.dm (); g3d.fireInteractorEvent({ jenis: 'doubleClickData', data: g3dDM.getDataByTag(data.getTag()) }) }});//...dihilangkan Efek rendering langitKarena ini adalah sistem pemantauan, maka harus dipantau 24 jam sehari tanpa membeda-bedakan. Hal ini menimbulkan masalah. Tidak mungkin saya terbang di atas langit biru di tengah malam. Ini kurang keasliannya, jadi pasti ada Proses langit dari terang ke gelap dan kemudian dari gelap ke terang, sementara proses ini saya atur ke dua periode waktu yaitu 06:00-06:30 dan 19:00-19:30.
Langit menggunakan bentuk bola shape3d: 'sphere' untuk membungkus seluruh pemandangan, dan kemudian menggunakan reverse.flip untuk menyalin kembali dan memadukan pewarna. Setelah itu, langit dapat dirender ke dalam warna yang saya inginkan cahaya dan bayangan langit menurut waktu, saya hanya perlu mengubah nilai pewarna.
Namun karena kondisi pencahayaan yang berbeda antara siang dan malam, maka intensitas cahaya yang dipantulkan awan juga berbeda, sehingga menyebabkan perbedaan antara awan pada siang dan malam hari. Oleh karena itu, transparansi opasitas awan juga perlu diatur tekstur latar belakang saluran dan awan, yang lebih transparan di malam hari. Kodenya adalah sebagai berikut:
if ((jam > 6 && jam < 19) || (jam == 6 && menit >= 30)) { timePane && timePane.a({ 'pagi.terlihat': salah, 'hari.terlihat': benar, ' senja.terlihat': salah, 'malam.terlihat': salah, 'siang.opacity': 1 }) skyBox.s({ shape3d.blend: 'rgb(127, 200, 240)', }) cloudBackground.s({ back.opacity: 0.7, }) cloud.s({ shape3d.opacity: 0.7, })} else if ((jam < 6 || jam > 19) || (jam == 19 && menit >= 30)) {//...dihilangkan} else if (jam == 6 && menit < 15 ) {//...dihilangkan} else if (jam == 6 && menit >= 15 && menit < 30) {//...dihilangkan} else if (jam == 19 && menit < 15) { //...Dihilangkan} else if (jam == 19 && menit >= 15 && menit < 30) {//...Dihilangkan}Di sini saya juga menambahkan dukungan untuk ikon status waktu di sudut kanan atas panel waktu, dan menambahkan efek fade-in dan fade-out ketika ikon dialihkan ke posisi ikon status waktu berikutnya untuk ikon status panel waktu.
Untuk mendemonstrasikan efeknya, saya menambahkan tombol penggandaan waktu. Gambar berikut menunjukkan perubahan 500 kali laju aliran waktu:
MeringkaskanMelalui demo ini, saya menemukan bahwa ada banyak detail dalam kehidupan yang belum diperhatikan oleh orang-orang, dan ada kemungkinan visualisasi data. Di era big data ini, ada lebih banyak kemungkinan yang perlu ditelusuri Memvisualisasikan detail tidak hanya dapat memanfaatkan potensi HT untuk Web dengan lebih baik, tetapi juga memperkuat kualitas seseorang secara keseluruhan sebagai seorang programmer.