import cover from "./cover/index"; import { createLoadPack, loadLib } from "@/utils"; import { FuseModelAttrs, FuseModel, GuidePath, MeasureType, Measure as StoreMeasure, MeasurePosition, SceneType, scenes, Scene, } from "@/store"; import type { Emitter } from "mitt"; import { AnimationModel, AnimationModelAction, AnimationModelFrame, AnimationModelPath, TaggingPositionType, } from "@/api"; export enum SettingResourceType { map = "map", color = "color", envImage = "img", bottomImage = "bimg", icon = "icon", } type SceneModelAttrs = FuseModelAttrs & { select: boolean }; export type SceneModel = ToChangeAPI & { bus: Emitter< Pick & { loadError: void; loadDone: void; loadProgress: number; changeSelect: boolean; transformChanged: { position?: SceneLocalPos; scale?: number; rotation?: SceneLocalPos; bottom?: number; }; } >; destroy: () => void; enterScaleMode: () => void; enterRotateMode: () => void; enterMoveMode: () => void; leaveTransform: () => void; getDefaultRotation: () => SceneLocalPos; enterAlignment: () => void; leaveAlignment: () => void; enterScaleSet: () => ScaleSet; leaveScaleSet: () => void; supportPano: () => boolean; flyInPano: () => void; flyOutPano: () => void; }; export interface ScaleSet { setLength: (length: number) => void; startMeasure: () => void; } export type ModelAttrRange = { [key in "opacity" | "bottom" | "scale" as `${key}Range`]: { min: number; max: number; step: number; }; }; export type AddModelProps = Pick & FuseModelAttrs & { type: string; isDynamicAdded: boolean; mode: "many" | "single"; fromType: any; } & ModelAttrRange; export type SceneGuidePath = Pick & Pose; export interface SceneGuide { bus: Emitter<{ changePoint: number; playComplete: void }>; play: () => void; pause: () => void; clear: () => void; } export type ScenePos = { localPos: SceneLocalPos; modelId: FuseModel["id"] }; export type ScreenPos = { trueSide: boolean; pos: ScreenLocalPos; modelId: FuseModel["id"]; }; export interface CameraComeToProps { position: SceneLocalPos; target?: SceneLocalPos; dur?: number; modelId?: FuseModel["id"]; distance?: 1 | 2 | 3; maxDis?: number; isFlyToTag?: boolean; } export type CalcPathProps = [ [SceneGuidePath, SceneGuidePath], Partial> ]; export interface MeasureBase { destroy?: () => void; show: () => void; hide: () => void; fly: () => void; bus: Emitter<{ update: [MeasurePosition["point"][], MeasurePosition["modelId"][]]; highlight: boolean; }>; changeSelect: (isHight: boolean) => void; setPositions: ( points: MeasurePosition["point"][], modelIds: MeasurePosition["modelId"][] ) => void; } export type Measure = MeasureBase & (T extends MeasureType.area ? { getArea: () => { value: number } } : { getDistance: () => { value: number } }); export type StartMeasure = Measure & { bus: Emitter<{ submit: [MeasurePosition["point"][], MeasurePosition["modelId"][]]; cancel: void; invalidPoint: string; }>; }; export type Pose = | { position: SceneLocalPos; target: SceneLocalPos; } | { panoId: any; model: SceneModel; posInModel: SceneLocalPos; rotInModel: SceneLocalPos; position: SceneLocalPos; target: SceneLocalPos; }; export interface SDK { layout: HTMLDivElement; sceneBus: Emitter<{ cameraChange: SceneLocalPos; panoModelChange: SceneModel; modeChange: { mode: "pano" | "fuse"; active: SceneModel }; }>; setBackdrop: ( drop: string, type: SettingResourceType, tb: { scale?: number; rotate?: number } ) => void; switchScene: ( scene: { type: SceneType; num: string } | null ) => Promise; startAddSth: () => void; endAddSth: () => void; addModel: (props: AddModelProps) => SceneModel; setCameraFov: (fov: number) => void; enableMap(dom: HTMLDivElement, latlng: number[]): void; switchMapType: (type: string) => void; showGrid: () => void; compassVisibility: (visibility: boolean) => void; canTurnToPanoMode: () => { model: SceneModel }; hideGrid: () => void; calcPathInfo: ( paths: CalcPathProps[0], info: CalcPathProps[1] ) => Required; getPositionByScreen: ( screenPos: ScreenLocalPos, modelId?: FuseModel["id"] ) => | (ScenePos & { worldPos: SceneLocalPos; localNormal: SceneLocalPos }) | null; getScreenByPosition: ( localPos: SceneLocalPos, modelId?: FuseModel["id"] ) => ScreenPos | null; screenshot: (width: number, height: number) => Promise; getPose: () => Pose; comeTo: (pos: CameraComeToProps) => void; comeToByLatLng: (pos: number[]) => void; enterSceneGuide: (data: SceneGuidePath[]) => SceneGuide; drawMeasure( type: T, points: MeasurePosition["point"][], modelIds: MeasurePosition["modelId"][] ): Measure; startMeasure(type: T): StartMeasure; createTagging: (props: Tagging3DProps) => Tagging3D; createPath: (props: PathProps) => Path; createAnimationGroup: () => AnimationGroup; } export type PathProps = { // 线段名称 name: string; // 是否显示名称, showName: boolean; // 文字大小 fontSize: number; // 是否显示方向, showDirection: boolean; // 方向是否反向 reverseDirection: boolean; line: { width: number; color: string; altitudeAboveGround: number; position?: SceneLocalPos; modelId?: string; }; points: { // 点位名称 name: string; position: SceneLocalPos; modelId: string; }[]; }; export type Path = { bus: Emitter<{ activePoint: number; // 标注点击事件 click: void; // 鼠标移入标注事件 enter: void; // 鼠标移出标注事件 leave: void; // 线段坐标更改事件 linePositionChange: { pos: SceneLocalPos; modelId: string; }; focus: boolean; // 路径点位置变更 changePoints: PathProps["points"]; drawed: void; }>; changeDirection: (show: boolean, reverse: boolean) => void; changeFontSize: (fontSize: number) => void; focus: (f: boolean) => void; highlight: (f: boolean) => void; changeVisibilityRange: (range: number) => void; changePointName: (index: number, name: string) => void; // 飞向路径 fly: () => void; // 更改路径点 changePathPoints: ( points: Omit[] ) => void; // 播放路径,相机沿着路径运动,传入播放完毕回调 play: (playedHandler: () => void) => void; // 停止播放路径 pause: () => void; // 是否可编辑 changeCanEdit: (canMove: boolean) => void; deletePoint: (index: number) => void; changeEditMode: (editMode: boolean) => void; // 可见性 visibility: (visibility: boolean) => void; // 气泡是否可见 visibilityName: (visibility: boolean) => void; // 更改标题气泡属性 changeLine: (props: Partial) => void; // 更改标题气泡属性 changeName: (name: string) => void; // 线段销毁 destroy: () => void; }; export type Tagging3DProps = { lineHeight: number; fontSize: number; // 标题 title: string; // 标注类型 2d | 3d type: TaggingPositionType; // 模型id modelId: string; // 贴地射线获取的位置 position: SceneLocalPos; normal: SceneLocalPos; // 是否可以移动 canMove: boolean; // 贴地图片url image: string; // 贴地图片的变换 mat: { scale: number; rotation: number; }; }; export type Tagging3D = { bus: Emitter<{ // 标注点击事件 click: void; // 鼠标移入标注事件 enter: void; // 鼠标移出标注事件 leave: void; // 位置变更 changePosition: { pos: SceneLocalPos; modelId: string; normal: SceneLocalPos; }; }>; changePosition: (position: { modelId: string; // 贴地射线获取的位置 position: SceneLocalPos; normal: SceneLocalPos; }) => void; changeFontSize: (fontSize: number) => void; changeLineHeight: (lineHeight: number) => void; // 设置标题 changeTitle: (title: string) => void; // 标题是否可见 visibilityTitle: (visibility: boolean) => void; // 更改可拖拽移动 changeCanMove: (canMove: boolean) => void; // 获取图标中心三维坐标 getImageCenter: () => SceneLocalPos; // 更改图标 changeImage: (url: string) => void; // 标注可见性 visibility: (visibility: boolean) => void; // 标注图片变换,传入变换 changeMat: (props: Tagging3DProps["mat"]) => void; // 更改热点类型 changeType: (val: TaggingPositionType) => void; // 距离相机位置 getCameraDisSquared: () => number; // 标注销毁 destory: () => void; }; // 动画组对象 export type AnimationGroup = { // 播放 play: () => void; // 暂停 pause: () => void; // 添加动画模型 addAnimationModel: (data: AnimationModel) => Promise; // 设置当前时间, 单位为秒 setCurrentTime: (s: number) => void; bus: Emitter<{ currentTime: number; }>; }; export type AnimationModel3D = { // 销毁动画模型 destroy: () => void; // 更改动画模型可见性 changeShow: (show: boolean) => void; // 更改动画可见范围 不传为全局可见 changeVisibilityRange: (range?: number) => void; // 更改模型名称 changeTitle: (name: string) => void; // 更改名称字体大小 changeFontSize: (size: number) => void; // 更改名称可见性 visibilityTitle: (show: boolean) => void; // 添加模型帧 addFrame: (frame: AnimationModelFrame) => AnimationModelFrame3D; // 添加模型动作 addAction: (frame: AnimationModelAction) => AnimationModelAction3D; // 添加模型路径 addPath: ( frame: Omit & { path: Path } ) => AnimationModelPath3D; // 获取当前模型旁白出现的适合位置,传入旁边dom的宽高,返回像素位置 getCurrentSubtitlePixel: (size: { width: number; height: number }) => { x: number; y: number; }; // 获取当前时间改模型的姿态 getCurrentMat: () => { position?: SceneLocalPos; scale?: number; rotation?: SceneLocalPos; originPosition?: SceneLocalPos; }; // 进入旋转 enterRotateMode: () => void enterMoveMode: () => void enterScaleMode: () => void leaveTransform: () => void; // 动画帧姿态修改数据 bus: Emitter<{ transformChanged: { position?: SceneLocalPos; scale?: number; rotation?: SceneLocalPos; originPosition?: SceneLocalPos; }; }>; }; export type AnimationModelFrame3D = { // 销毁动画模型帧 destroy: () => void; // 修改帧播放时间 单位为秒 changeTime: (s: number) => void; setMat: (mat: any) => void }; export type AnimationModelAction3D = { // 销毁动画模型动作 destroy: () => void; // 修改动作播放时间 单位为秒 changeTime: (s: number) => void; // 修改动作幅度 changeAmplitude: (n: number) => void; // 修改动作速度 changeSpeed: (n: number) => void; // 修改动持续时间 单位为秒 changeDuration: (n: number) => void; }; export type AnimationModelPath3D = { // 销毁动画模型路径 destroy: () => void; // 修改路径 传入参数为你之前返回的路径对象 changePath: (path: Path | undefined) => void; // 修改播放是否要反向 changeReverse: (reverse: boolean) => void; // 修改路径播放时间 单位为秒 changeTime: (s: number) => void; // 修改路径续时间 单位为秒 changeDuration: (n: number) => void; }; export let sdk: SDK; export type InialSDKProps = { laserRoot?: string; ossRoot?: string; laserOSSRoot?: string; panoOSSRoot?: string; layout: HTMLDivElement; scenes: Scene[]; lonlat?: number[]; }; export let initialed = false; export const initialSDK = async (props: InialSDKProps) => { if (initialed) return sdk; initialed = true; const libs = [ `./lib/proj4/proj4.js`, `./lib/jquery/jquery-3.1.1.min.js`, `./lib/other/BinaryHeap.js`, `./lib/tween/tween.min.js`, `./lib/plasio/js/laslaz.js`, `./lib/plasio/vendor/bluebird.js`, `./lib/plasio/workers/laz-loader-worker.js`, `./lib/plasio/workers/laz-perf.js`, `./lib/Cesium/Cesium.js`, `./lib/shapefile/shapefile.js`, ]; await Promise.all(libs.map(loadLib)); await loadLib(`./lib/potree/potree.js`); console.log(props); const localSdk = cover({ ...props, dom: props.layout, isLocal: false, scenes: props.scenes, lonlat: props.lonlat, mapDom: null, } as any) as unknown as SDK; (window as any).sdk = sdk = localSdk; sdk.layout = props.layout; return sdk; }; export default sdk!;