프런트엔드 구성 요소 통합

2026-10-16

기본 소개

프런트엔드 구성 요소 소개

DJI FlightHub 2 프런트엔드 구성 요소에는 비행 경로 생성, 비행 경로 편집기, 가상 조종석, 그리고 프로젝트/지도가 포함됩니다. 이러한 구성 요소는 사용자 지정 테마 및 스타일을 지원합니다. 이 수동은 이러한 구성 요소를 처음부터 자체 시스템에 통합하는 방법을 소개할 것입니다.

시작 전 준비

  • 기술 스택: React, Vue, HTML + CSS 모두 지원됩니다.
  • 하드웨어 요구 사항: FlightHub 2 온프레미스 버전을 배포하려면 DJI FlightHub 2 온프레미스 버전 배포 매뉴얼을 참조하십시오.

퀵 스타트

현재 버전은 주로 다음 구성 요소와 해당 기능 모음을 제공합니다. 데모를 다운로드하고 이 설명서를 참조하여 구성 및 디버깅을 할 수 있습니다.

릴리스된 구성 요소는 다음과 같습니다:

구성 요소기능 모음기능 스크린샷
비행경로 생성비행경로 유형:
- 웨이포인트 경로
- 영역 경로
- 경사 경로
- 기하학적 경로
- 스마트 3D 캡처 경로

스타일 사용자 지정
비행경로 편집기비행경로 유형:
- 웨이포인트 경로
- 영역 경로
- 경사 경로
- 기하학적 경로
- 스마트 3D 캡처 경로

비행경로 기능:
- 비행경로 편집 및 저장
- 지도 주석
- Cesium 열기
- 점, 선, 영역 주석
- 모델 로딩

스타일 사용자 지정
가상 조종석원격 제어 기능:
- 원클릭 이륙
- 라이브 스트림
- WASD 키를 눌러 수동 비행 및 궤적 표시
- 원클릭 RTH

스타일 사용자 지정
프로젝트/지도프로젝트 지도 데이터:
- 점, 선, 영역 주석
- 비행 경로 및 궤적 계획
- 사용자 지정 임무 영역, 사용자 지정 제한 구역
- 프로젝트 장치 목록
- 도크 기체
- 수동 비행 기체

튜토리얼

필수 스타일 및 종속성 추가

FlightHub 2 온프레미스 버전 배포를 완료한 후, 비공개 IP를 받게 됩니다. 이 비공개 IP 또는 도메인 이름과 포트를 코드 블록의 HEAD 섹션에 입력하십시오.

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="http://Private IP or domain name/paas.js" fh2></script>
    <title>Demo</title>
  </head>
  <body>
  </body>
</html>

프런트엔드 구성 요소 호환성 정보

프런트엔드 구성 요소는 FlightHub 2 온프레미스 버전에서 제공하는 기능에 따라 달라지므로, FlightHub 2 온프레미스 버전의 projectToken 및 prjId를 얻어야 합니다. 정보를 얻는 방법은 다음과 같습니다:

  • projectToken: FlightHub 2 온프레미스 버전에 액세스하여 내 조직(배포된 FlightHub 2 도메인 이름/user-center#/my-organization) > 조직 설정 > FlightHub Sync로 이동하여 조직 키를 얻습니다. 이 조직 키 값은 projectToken입니다.

  • prjId: FlightHub 2 온프레미스 버전에 액세스하여 프로젝트 목록을 클릭하고 프로젝트를 선택한 다음 URL에서 프로젝트 ID를 찾습니다. 예시: https://deployed FlightHub 2 domain name/organization/4bf0039f-6434-44a8-b891-8d7b6b7ff132/project/aa9c7a78-4e97-4ced-8953-2cea96c07c00, 여기서 4bf0039f-6434-44a8-b891-8d7b6b7ff132는 orgId이고 aa9c7a78-4e97-4ced-8953-2cea96c07c00는 prjId입니다.

예시:

window.FH2.initConfig({
    serverUrl: 'http://Enter the domain name and backend service port here. Default port number is 30812',
    wssUrl: 'ws://Enter the domain name and backend service port here. Default port number is 30812/duplex/web',
    hostUrl: 'http://Enter the IP or domain name of the web page and the port number here',
 
    // Copy prjId value and paste here
    prjId: 'cdca2736-8096-4729-9bc7-497ad5b60d5e',
    // Copy projectToken value and paste here
    projectToken: 'MTczMDg4NDI1NHx1NUR3RWxNajc5VnF4QWJuY1BvZmxUenlwYzdnRnBUazFSQnRhMXZOODlPSlVrdFhQekdFTjJKb0I1UkNNUlhtaFR0M3k2WllBdWNJTFVGNDZ4eHp3aWJnSnZ0TjVhNDdNMDUtcUlNQmZRUEtKYjNHeWIyLVZNTm80Qzd6TnMyTUNNSmFsWjZVQ0tkVWtEOU1tWVB5cDNSeWhLQW1NUXJrSzhnQkJhVl9saW5Bazhwbl9KQzg2b2FmWUVULWJoMWowbWh2aEV5X1BtZW9pZm1sRGJmajNoa1QxN280emluNDk1eUFaTUw4ZEJMRmljczIxY0twVmZBNVhiMU81b3Y2UmlNY3dZazFHLTY4Q3ljdFJVdWZuUmVxUUo1VGxEcnJrYkFZNGlpTGVjdC1jNnprYU5nSkFpLWdRbXJ5M2JraEVGUlJJY3YwUUk1TUlDMzZDd2tRc2dlOHNIblFVaHNwb1ozVFJ2MmtoenhZa1pMN0RCbVk4QkVNOVNvaVN1NmszVGRBTE1MMWVLRE5wMFY5VmFrN0FJSzgtcjZaaUstaThwNU9yd0E0V05iNE15eWswc1lXRnFVUzJGZm1wdG0xR0k5WXB0TzRZZUpMeHhCNGVBNEZKZkdaTC1NUV9iRGtXR3EwNXBpOUlBSUd2WFBnYl8tbEJ0NV9qRTRtZG45SDJBZkdpUFZJSktrOFhhSkdqNHEtOUxaUXdvT2NSV0FhUklnQXdINFdFRHR3TGhrPXwr7HTdhghvb4TN9rYRlDyCE9Mzc4Q89m4H3_B24WRKVg=='
})

유의 사항

window.FH2 호출이 페이지가 완전히 로드된(load) 후에 실행되는지 확인하십시오. 예를 들어, addEventListener('load', cb)를 사용하여 콜백 함수 cb를 정의하고 이 콜백 내에서 window.FH2 메서드를 호출할 수 있습니다.

구성 요소용 컨테이너 추가

예를 들어, 경로 편집기를 추가하려면 경로 편집기를 표시하려는 코드 섹션에 다음 코드를 삽입합니다.

<div class="fh2-container">
    <div id="wayline-header"></div>
    <div class="project-details">
        <div id="project-app-container"></div>
        <div id="project-middle-container"></div>
        <div id="project-right-micro-app" class="right-micro-app">
            <div class="maps-micro-app">
                <div id="project-map-app-placeholder" class="map-app-placeholder">
                    <div id="map-app-global" class="map-app-container"></div>
                </div>
            </div>
            <div id="wayline-app-container"></div>
        </div>
    </div>
</div>

구성 요소 컨테이너 스타일 추가

아래는 권장 컨테이너 스타일이며, 대상 코드 영역에서 직접 사용할 수 있습니다. 다른 맞춤 설정 요구 사항이 있는 경우 스타일 코드를 직접 수정할 수 있습니다.

<!DOCTYPE html>
<html>
  <head>
    <!-- start -->
    <style>
        .fh2-container {
            display: flex;
            flex-direction: column;
            /* Set the width and height of the container where you want to load the component */
            height: 100vh;
            width: 100vw;
        }
 
        #project-app-container>div, .map-app-container>div {
            width: 100%;
            height: 100%;
        }
 
        .project-details {
            position: relative;
            width: 100%;
            display: flex;
            flex: 1;
            overflow: auto;
        }
 
        .project-details .right-micro-app {
            position: relative;
            display: flex;
            flex: 1;
        }
 
        .project-details .right-micro-app .maps-micro-app {
            display: flex;
            flex: 1;
        }
 
        .project-details .right-micro-app .map-app-placeholder {
            flex: 1;
            position: relative;
            display: flex;
            flex-direction: column;
        }
 
        .project-details .right-micro-app .map-app-container {
            height: 100%;
        }
 
        .project-details .right-micro-app #wayline-app-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
        }
    </style>
    <title>Demo</title>
  </head>
  <body>
  </body>
</html>

프런트엔드 구성 요소 로드

비행 경로 편집기를 예로 들어, id와 해당 wayline_id를 메서드에 전달하여 구성 요소를 로드할 수 있습니다. 자세한 내용은 설명서의 Interface Tutorial을 참조하십시오.

window.FH2.loadWayline("wayline-app-container", {
      wayline_id: 'bded3cf1-c924-4cd0-95d0-4bd642ddda09',
})

지도 요소 맞춤 설정 (선택 사항)

맞춤 지도 텍스트를 예로 들어, wayline.html 상단의 Customize Map을 클릭하고 지도를 축소하여 효과를 확인할 수 있습니다.

<!DOCTYPE html>
<html>
  <head>
    <link href="./custom-style.css" rel="stylesheet">
  </head>
  <body>
    <div class="btn-bar">
        <button id="CesiumMapBtn" onclick="addCustomCesiumData()">Customize Map</button>
    </div>
    <script>
        const CesiumMapBtn = document.getElementById('CesiumMapBtn')
        CesiumMapBtn.style.display = 'none'
        window.addEventListener('load', function () {
            // Wait until the map instance is ready, and then display the map customization button
            window.FH2.subscribe('cesium-viewer-change', (key) => {
                if (window.FH2.cesiumViewer.global) {
                    CesiumMapBtn.style.display = 'inline-block'
                }
            })
        })
        
        // Example: Customize the map, adding custom text to the map
        function addCustomCesiumData () {
            for (const key in window.FH2.cesiumViewer) {
                if (Object.prototype.hasOwnProperty.call(window.FH2.cesiumViewer, key)) {
                    const ins = window.FH2.cesiumViewer[key].entities.add({
                        position: window.Cesium.Cartesian3.fromDegrees(113.93,  22.57, 50),
                        label: {
                            text: "User custom text",
                        },
                    })
                }
            }
        }
    </script>
  </body>
</html>

테마 맞춤 설정 (선택 사항)

데모 파일은 스타일을 맞춤 설정하는 기능을 보여줍니다. custom-style.css에서 해당 테마 스타일을 수정하고 wayline.html을 포함한 4개의 HTML 파일 전체에서 즉시 효과를 확인할 수 있습니다. custom-style.css는 CSS를 사용하여 작성되었으므로, 프로젝트에서도 CSS를 사용하는 경우 프로젝트 내에서 custom-style 스타일 변수를 직접 조정할 수 있습니다.

<!DOCTYPE html>
<html>
  <head>
    <link href="./custom-style.css" rel="stylesheet">
  </head>
  <body>
    <div class="btn-bar">
        <button onclick="changeTheme()">Customize Style</button>
    </div>
    <script>
        function changeTheme () {
            document.body.className = document.body.className ? '' : 'set-change-color'
        }
    </script>
  </body>
</html>

이벤트 리스너 추가 (선택 사항)

비행 경로 편집기를 예로 들어, 저장 버튼을 구독하여 비행 경로를 저장하거나 취소할 때 해당 알림 메시지를 받을 수 있습니다.

window.FH2.subscribe('wayline-cancel', () => {
    console.log('Canceled saving flight route')
})
window.FH2.subscribe('wayline-save', () => {
    console.log('Flight route saved')
})

인터페이스 튜토리얼

인스턴스: window.FH2

메서드: validateToken

매개변수유형필수설명
토큰문자열true반환값: 토큰 유효성 검사 결과: true/false

메서드: initConfig

매개변수유형필수설명
서버 URL문자열true백엔드 HTTP 서비스 주소
WSS URL문자열true백엔드 양방향 서비스 주소
호스트 URL문자열true프런트엔드 웹 진입 주소
프로젝트 ID문자열true프로젝트 ID
프로젝트 토큰문자열trueOpenAPI 인증 토큰

메서드: loadWaylineCreation

매개변수유형필수설명
domId문자열true타사 프런트엔드에서 DOM 노드 ID를 제공합니다.
props객체<WaylineCreationConfig>false자세한 매개변수 설명은 아래 표를 참조하십시오: WaylineCreationConfig

WaylineCreationConfig 매개변수 설명:

매개변수유형필수설명
folder_id문자열false생성된 비행 경로가 저장되는 폴더입니다. 값은 폴더 ID입니다. 제공되지 않을 경우, 기본 폴더로 설정됩니다.

메서드: destroyWaylineCreation

매개변수유형필수설명
---비행 경로 생성 컴포넌트 인스턴스를 제거합니다.

메서드: loadWayline

매개변수유형필수설명
domId문자열true타사 프런트엔드에서 DOM 노드 ID를 제공합니다.
props객체<WaylineConfig>true자세한 매개변수 설명은 아래 표를 참조하십시오: WaylineConfig.

WaylineConfig 매개변수 설명:

매개변수유형필수설명
wayline_id문자열trueWayline ID

메서드: destroyWayline

매개변수유형필수설명
isEffect부울false비행 경로 편집기 인스턴스를 제거합니다. 현재 페이지에 여러 컴포넌트가 있는 경우, 인스턴스 제거를 위해 true를 전달해도 다른 로드된 컴포넌트에는 영향을 주지 않습니다. 매개변수가 전달되지 않으면 기본값은 false입니다.

메서드: loadCockpit

매개변수유형필수설명
domId문자열true타사 프런트엔드에서 DOM 노드 ID를 제공합니다.
props객체<CockpitConfig>true자세한 매개변수 설명은 아래 표를 참조하십시오: CockpitConfig

CockpitConfig 매개변수 설명:

매개변수유형필수설명
gatewaySn문자열true게이트웨이 SN
droneSn문자열true기체 SN
지도부울false지도를 로드할지 여부. 기본값은 true입니다. 메서드 매개변수를 false로 설정하면 지도가 로드되지 않습니다.

메서드: destroyCockpit

매개변수유형필수설명
isEffect부울false가상 조종석 인스턴스를 파괴합니다. 현재 페이지에 여러 컴포넌트가 있는 경우, 인스턴스 제거를 위해 true를 전달해도 다른 로드된 컴포넌트에는 영향을 주지 않습니다. 매개변수가 전달되지 않으면 기본값은 false입니다.

메서드: loadProject

매개변수유형필수설명
domId부울true프로젝트 지도 로드

메서드: destroyProject

매개변수유형필수설명
---프로젝트 맵 파괴

메서드: loadFlightPath

매개변수유형필수설명
domIdstringtrue타사 프론트엔드에서 제공하는 DOM 노드 ID
paramsIFlightPathParamstrue자세한 매개변수 설명은 아래 표 참조: IFlightPathParams

IFlightPathParams 매개변수 설명:

매개변수유형필수설명
flight_path_idstringtrue비행 경로 ID

메서드: destroyFlightPath

매개변수유형필수설명
---비행 기록 언로드

메서드: 구독

매개변수유형필수설명
eventName문자열true이벤트 구독:
- wayline-save: 비행 경로 저장 시 트리거되며, 콜백 매개변수는 성공적으로 저장된 비행 경로의 ID입니다.
- wayline-cancel: 비행 경로 저장 취소 시 트리거되며, 콜백 매개변수는 해당 비행 경로의 ID입니다.
- wayline-back: 비행 경로 편집기 구성 요소에서 뒤로가기 버튼 클릭 시 트리거되며, 콜백 매개변수는 해당 비행 경로의 ID입니다.
- wayline-creation-saved: 비행 경로 생성 구성 요소 저장 시 트리거되며, 콜백 매개변수는 성공적으로 저장된 비행 경로의 ID입니다.
- wayline-creation-cancel: 비행 경로 생성 구성 요소 저장 취소 시 트리거됩니다.
- cesium-viewer-change: 각 Cesium 맵 로딩 변경 사항 감지 시 트리거됩니다.
- flight-path-back: 비행 기록에서 돌아갈 때 트리거됩니다.
콜백문자열false현재 비행 경로 ID 전달

메서드: cesiumViewer

유형설명
{ [key: string]: CesiumViewer }이 메서드는 현재 페이지의 모든 Cesium Viewer 인스턴스에 접근할 수 있도록 합니다. 현재 주요 값은 다음과 같습니다:
- global: 메인 지도
- wayline_editor_support: 비행 경로 편집기 구성 요소의 보조 지도.

인스턴스: window.Cesium

네이티브 Cesium 물체는 window 물체를 통해 직접 접근할 수 있으므로, 사용자는 cesium.js를 직접 가져올 필요가 없습니다.

자주 묻는 질문

  • FH2를 호출하면 왜 '속성 정의되지 않음' 오류가 발생하나요?

페이지가 로드된(load) 후에 window.FH2 메서드를 호출해야 합니다. 또한 콜백 함수를 정의하고 이 콜백 내에서 window.FH2를 호출하는 데 사용할 수 있습니다.

  • FlightHub 2 구성 요소를 로드한 후에 웹 페이지의 본문 배경색이 왜 흰색으로 변하나요?

현재, FlightHub 2 구성 요소를 로드하면 본문 배경색에 전역 스타일이 적용되며, 이는 원래 웹사이트 스타일을 덮어쓸 수 있습니다. 이 경우, 웹사이트의 배경색에 대해 !important 스타일을 사용하는 것과 같이 더 높은 우선순위 스타일을 설정해야 합니다.

  • FlightHub 2 구성 요소를 사용하면 일부 인터페이스 매의 위치가 부정확해지는 이유는 무엇입니까?

예를 들어, 비행 경로 편집기에서 웨이포인트, 주석 및 메시지 프롬프트를 추가할 때 일부 매의 위치가 부정확합니다. 해결책: 구성 요소 컨테이너와 해당 상위 컨테이너에 다음 스타일 속성이 없는지 확인하십시오. 1. transform 또는 perspective가 none이 아님; 2. filter가 none이 아님; 3. will-change가 transform 또는 perspective임; 4. contain이 paint임

  • TypeScript 추론을 수행하는 방법은 무엇입니까?

다음 코드를 참조하십시오:

export type eventName = 'wayline-save' | 'wayline-cancel' | 'cesium-viewer-change'
export interface IWaylineParams {
  wayline_id: string;
}
 
export interface ICockpitParams {
  gateway_sn: string;
  drone_sn: string;
}
 
export interface IFH2Config {
  userId: string;
  orgId: string;
  prjId: string;
  serverUrl: string;
  wssUrl: string;
  hostUrl: string;
  token?: string;
}
export interface FH2 extends Record<string, any> {
  validateToken: (token: string) => boolean;
  initConfig: (config: IFH2Config) => void;
  subscribe: (eventName: eventName, callback: (...args: any[]) => void) => void;
  unsubscribe: (eventName: eventName) => void;
  destroyWayline: () => void;
  loadWayline: (domId: string, routerName: string, params?: IWaylineParams) => void;
  updateWayline: (routerName: string, params?: IWaylineParams) => void;
}
Last Updated: