며칠 전 출장을 가다가 비행기에서 머리 위 모니터링 패널을 봤는데, TV 시리즈나 광고를 재생하는 것 외에도 가끔 항공기 내비게이션을 위한 모니터링 시스템으로 전환되기도 했습니다. 시스템이 조금 투박한 느낌이 들어서, 우연히 HT for Web을 사용하여 모니터링 시스템의 업그레이드 버전을 만들어 봤습니다. 데모가 꽤 괜찮아서 서로 배울 수 있도록 공유하고 싶습니다.
데모
구현 프로세스구름 효과를 통해 걷기
구름 사이를 비행하는 비행기의 효과를 얻기 위해 제가 직면한 첫 번째 문제는 일반적으로 원근감 효과로 알려진 비행기 비행의 레이어링이었습니다. 여기서는 구름 채널과 구름 배경을 사용하여 서로 다른 속도로 흐르게 했습니다. 비행 원근감 효과를 만듭니다.
구름을 텍스처 형태로 표현했는데 텍스처만으로는 하늘과 항공기를 가려서 항공기가 날아가는 모습과 느낌에 큰 영향을 미치게 되므로 해당 그래픽 요소의 투명도와 불투명도를 ON으로 하였고, 구름 배경과 구름 채널의 투명도를 다르게 설정해 레이어링 효과를 더할 뿐만 아니라 눈앞에 구름이 떠다니는 듯한 착각을 불러일으킵니다.
클라우드 채널은 ht.Polyline 유형을 사용하여 Y축의 비율을 확대하여 클라우드 채널에 더 큰 수직 공간을 제공합니다. reverse.flip back copy를 설정하면 다음과 같이 텍스처가 클라우드 채널 내부에 표시됩니다. 항공기가 공중에 있는 경우 구름 배경은 ht.Node 유형을 채택하고 하나의 표면만 구름 배경으로 표시되도록 설정됩니다.
전반적인 구름 흐름 효과는 오프셋 오프셋을 사용하여 달성되며, 해당 프리미티브 또는 해당 프리미티브 표면의 텍스처 오프셋을 변경하여 구름을 통과하는 비행기의 효과를 구현하는 코드는 다음과 같습니다.
var i = 1, p = 0;setInterval(() => { i -= 0.1; p += 0.005; clouds.s('shape3d.uv.offset', [i, 0]); cloudBackground.s(' all.uv.offset', [p, 0]);}, 100);
리프팅 범프 효과
비행기가 구름을 뚫고 날아가는 효과를 얻을 수는 있지만 비행기가 직선으로만 비행한다면 비행의 실제 느낌도 줄어들 것입니다. 비행기 비행으로 인한 난기류를 느껴보세요. 실제로 항공기의 경로가 특정 고도에 항상 고정되어 있지 않기 때문에 때로는 오르고 때로는 떨어지기 때문에 ht-animation.js
HT 애니메이션 확장 플러그를 사용했습니다. - 항공기의 울퉁불퉁한 효과를 얻기 위한 코드는 다음과 같습니다.
dm.enableAnimation(20);plane.setAnimation({ back1: { from: 0, to: 160, easing: 'Cubic.easeInOut', 기간: 8000, next: up1, onUpdate: function (value) { value = parsInt( 값); var p3 = this.p3(); this.p3(값, p3[1], p3[2]); }, //...비슷한 시작 생략: [back1]});구 섹터 시야각 제한
비행 효과가 완성된 후에는 더 어려운 문제에 직면했습니다. 비행기가 실제로는 운해를 통과하고 있지만 채널에서만 비행하고 있었고 배경은 실제로는 평평한 텍스처일 뿐이었기 때문입니다. 원근감이 특정 수준에 도달하면 불협화음과 비현실성이 강해지며 특정 범위 내에서 시야각을 조정하려면 시야각 제한이 필요합니다.
시야각 제한은 일반적으로 g3d의 눈과 중심을 제한합니다. 그것에 대해 잘 모르는 친구들은 hightopo 공식 웹사이트에서 3D 매뉴얼을 읽을 수 있습니다. 여기서는 보기 때문에 자세한 지침을 다루지 않겠습니다. 각도 범위, 중심 위치를 고정하기 위해 코드는 다음과 같습니다.
g3d.addPropertyChangeListener(e => { // 중심점 고정 if (e.property === 'center') { e.newValue[0] = center[0]; e.newValue[1] = center[1]; e.newValue[2] = 센터[2] }}
그런 다음 눈을 특정 범위로 제한하면 끝입니다. 그러나 여기서는 그렇게 간단하지 않습니다. 처음에는 눈을 입방체 공간으로 제한했지만 g3d의 기본 상호 작용에서는 상호 작용 효과가 이상적이지 않았습니다. , 마우스 원근감을 변경하기 위해 드래그하고 패닝할 때 눈은 실제로 중심을 중심으로 하는 구면 위에서 움직이기 때문에 구형 섹터인 공에서 눈이 제한된 공간을 파내기로 결정했습니다. 잘 이해가 안가시는 분들은 이 사진을 참고해주세요.
구형 부채꼴 시야각 제한에는 중심 기준 축, 중심 축과 외부 가장자리 사이의 각도, 공의 제한된 반경 등 총 3개의 매개변수가 필요합니다. 초기 눈과 중심을 연결하는 연장선과 볼의 제한 반경이 위치하며 최대 제한과 최소 제한으로 구분됩니다.
functionlimitEye(g3d, eye, center, options) { varlimitMaxL = options.limitMaxL,limitMinL = options.limitMinL,limitA = options.limitA;g3d.addPropertyChangeListener(e => { // 고정 중심점 if (e.property = == 'center') { e.newValue[0] = center[0]; e.newValue[1] = center[1]; e.newValue[2] = center[2]; } // 시야각 제한 if (e.property === 'eye') { var newEyeV = new ht.Math.Vector3(e.newValue), centerV = new ht.Math.Vector3(center), refEyeV = new ht.Math.Vector3(eye), refVector = refEyeV.clone().sub(centerV), newVector = newEyeV.clone().sub(centerV); if (centerV.distanceTo(newEyeV) >limitMaxL) { newVector.setLength(limitMaxL); e.newValue[0] = newVector.x; 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; e.newValue[2] = newVector.z; refVector) >limitA) { var oldLength = newVector.length(), oldAngle = newVector.angleTo(refVector), refLength = oldLength * 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); realEye = realVector.clone() .add(centerV); // 이동 각도가 180도를 초과하지 않도록 하고 원근을 반전시킵니다. if (oldAngle > Math.PI / 2) { realEye.negate() } e.newValue[0] = realEye.x; e.newValue[1] = e.newValue[2] = } } } )}항공기 모니터링 시스템
물론, 모니터링 시스템으로서 모니터링 기능이 있는 것은 당연합니다. 오른쪽 하단에 작은 지도를 추가하고 기체에 초점 맞추기, 비행 궤적에 초점 맞추기, 지도에 초점 맞추기, 흐름 효과 제어 등 세 가지 모드를 제공합니다. 그 중 기체에 포커스를 맞추면 기체의 움직임을 따라가며 기체가 항상 미니맵 중앙에 위치하도록 fitData를 수행하게 됩니다.
var fitFlowP = function (e) { if (e.property === 'position' && e.data === plane) { mapGV.fitData(plane, false) }};buttonP.s({ 'interactive': true, 'onClick': 함수(이벤트, 데이터, 뷰, 포인트, 너비, 높이) { map.a('fitDataTag', 'plane2D') mapGV.fitData(plane, false); mapDM.md(fitFlowP); }});buttonL.s({ 'interactive': true, 'onClick': 함수(이벤트, 데이터, 뷰, 포인트, 너비, 높이) { mapDM.umd(fitFlowP); 지도. a('fitDataTag', 'flyLine'); mapGV.fitData(flyLine, false) }});/...생략됨
이름을 지정하기 위해 마우스를 항공기의 해당 위치로 이동하고, 두 번 클릭하여 항공기의 해당 위치에 대한 정보 패널을 표시하고, 패널의 관점에 초점을 맞추고, 항공기의 아무 곳이나 클릭하여 다시 전환하라는 메시지가 추가되었습니다. 항공기 비행 모드 및 기타 효과.
왼쪽에 모니터링 패널을 추가하면 위에서 언급한 해당 위치의 더블클릭을 대체하여 해당 위치의 정보 패널에 직접 초점을 맞춥니다. 여기에서 버튼을 클릭하면 상호작용이 활성화되고 해당 상호작용 로직이 추가됩니다.
Button_JC.s({ 'interactive': true, 'onClick': 함수(이벤트, 데이터, 뷰, 포인트, 너비, 높이) { event.preventDefault(); let g3d = G.g3d, g3dDM = G.g3d.dm (); g3d.fireInteractorEvent({ 종류: 'doubleClickData', 데이터: g3dDM.getDataByTag(data.getTag()) }) }});//...생략됨하늘 렌더링 효과
모니터링 시스템이기 때문에 24시간 구분 없이 모니터링을 해야 하는데, 한밤중에 푸른 하늘을 날 수는 없다는 것이 문제입니다. 하늘이 빛에서 어둠으로, 그리고 어둠에서 빛으로 변하는 과정을 06:00-06:30과 19:00-19:30의 두 시간으로 잠정 설정했다.
하늘은 Shape3d: 'sphere' 구형 모양을 사용하여 전체 장면을 감싸고 reverse.flip을 사용하여 염료를 혼합한 후 원하는 색상으로 하늘을 렌더링할 수 있습니다. 시간에 따라 하늘의 빛과 그림자, 염료값만 바꿔주면 됩니다.
그러나 낮과 밤의 조명 조건이 다르기 때문에 구름이 반사하는 빛의 강도도 다르며 이로 인해 낮과 밤의 구름의 차이가 발생하므로 구름의 불투명도 투명도 조정도 필요합니다. 밤에 더 투명한 채널 및 구름 배경 텍스처는 다음과 같습니다.
if ((시간 > 6 && 시간 < 19) || (시간 == 6 && 분 >= 30)) { timePane && timePane.a({ 'morning.visible': false, 'day.visible': true, ' dark.visible': false, 'night.visible': false, 'day.opacity': 1 }) skyBox.s({ shape3d.blend: 'rgb(127, 200, 240)', }) cloudBackground.s({ back.opacity: 0.7, }) clouds.s({ shape3d.opacity: 0.7, })} else if ((시간 < 6 || 시간 > 19) || (시간 == 19 && 분 >= 30)) {//...생략} else if (시간 == 6 && 분 < 15 ) {//...생략} else if (시간 == 6 && 분 >= 15 && 분 < 30) {//...생략} else if (시간 == 19 && 분 < 15) { //...생략} else if (시간 == 19 && 분 >= 15 && 분 < 30) {//...생략}
여기에는 시간 패널의 오른쪽 상단에 시간 상태 아이콘에 대한 지원도 추가하고 아이콘 전환 시 페이드 인 및 페이드 아웃 효과를 추가하는 동시에 클릭하여 전환하는 기능도 추가했습니다. 시간 패널 상태 아이콘의 다음 시간 상태 아이콘 위치로 이동합니다.
효과를 보여주기 위해 시간을 두 배로 늘리는 버튼을 추가했습니다. 다음 그림은 시간 흐름 속도가 500배일 때의 변화를 보여줍니다.
요약이 데모를 통해 인생에는 사람들이 눈치 채지 못한 많은 세부 사항이 있으며 데이터 시각화의 가능성이 있다는 것을 알게 되었습니다. 빅 데이터 시대에는 더 많은 가능성을 탐색할 가치가 있습니다. 세부 사항을 시각화하면 웹용 HT의 잠재력을 더 잘 활용할 수 있을 뿐만 아니라 프로그래머로서 전반적인 품질도 강화할 수 있습니다.