sdk.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. import cover from "./cover/index";
  2. import { createLoadPack, loadLib } from "@/utils";
  3. import {
  4. FuseModelAttrs,
  5. FuseModel,
  6. GuidePath,
  7. MeasureType,
  8. Measure as StoreMeasure,
  9. MeasurePosition,
  10. SceneType,
  11. scenes,
  12. Scene,
  13. } from "@/store";
  14. import type { Emitter } from "mitt";
  15. import {
  16. AnimationModel,
  17. AnimationModelAction,
  18. AnimationModelFrame,
  19. AnimationModelPath,
  20. TaggingPositionType,
  21. } from "@/api";
  22. export enum SettingResourceType {
  23. map = "map",
  24. color = "color",
  25. envImage = "img",
  26. bottomImage = "bimg",
  27. icon = "icon",
  28. }
  29. type SceneModelAttrs = FuseModelAttrs & { select: boolean };
  30. export type SceneModel = ToChangeAPI<SceneModelAttrs> & {
  31. bus: Emitter<
  32. Pick<SceneModelAttrs, "select"> & {
  33. loadError: void;
  34. loadDone: void;
  35. loadProgress: number;
  36. changeSelect: boolean;
  37. transformChanged: {
  38. position?: SceneLocalPos;
  39. scale?: number;
  40. rotation?: SceneLocalPos;
  41. bottom?: number;
  42. };
  43. }
  44. >;
  45. destroy: () => void;
  46. enterScaleMode: () => void;
  47. enterRotateMode: () => void;
  48. enterMoveMode: () => void;
  49. leaveTransform: () => void;
  50. getDefaultRotation: () => SceneLocalPos;
  51. enterAlignment: () => void;
  52. leaveAlignment: () => void;
  53. enterScaleSet: () => ScaleSet;
  54. leaveScaleSet: () => void;
  55. supportPano: () => boolean;
  56. flyInPano: () => void;
  57. flyOutPano: () => void;
  58. };
  59. export interface ScaleSet {
  60. setLength: (length: number) => void;
  61. startMeasure: () => void;
  62. }
  63. export type ModelAttrRange = {
  64. [key in "opacity" | "bottom" | "scale" as `${key}Range`]: {
  65. min: number;
  66. max: number;
  67. step: number;
  68. };
  69. };
  70. export type AddModelProps = Pick<FuseModel, "url" | "id"> &
  71. FuseModelAttrs & {
  72. type: string;
  73. isDynamicAdded: boolean;
  74. mode: "many" | "single";
  75. fromType: any;
  76. } & ModelAttrRange;
  77. export type SceneGuidePath = Pick<GuidePath, "speed" | "time"> & Pose;
  78. export interface SceneGuide {
  79. bus: Emitter<{ changePoint: number; playComplete: void }>;
  80. play: () => void;
  81. pause: () => void;
  82. clear: () => void;
  83. }
  84. export type ScenePos = { localPos: SceneLocalPos; modelId: FuseModel["id"] };
  85. export type ScreenPos = {
  86. trueSide: boolean;
  87. pos: ScreenLocalPos;
  88. modelId: FuseModel["id"];
  89. };
  90. export interface CameraComeToProps {
  91. position: SceneLocalPos;
  92. target?: SceneLocalPos;
  93. dur?: number;
  94. modelId?: FuseModel["id"];
  95. distance?: 1 | 2 | 3;
  96. maxDis?: number;
  97. isFlyToTag?: boolean;
  98. }
  99. export type CalcPathProps = [
  100. [SceneGuidePath, SceneGuidePath],
  101. Partial<Pick<SceneGuidePath, "time" | "speed">>
  102. ];
  103. export interface MeasureBase {
  104. destroy?: () => void;
  105. show: () => void;
  106. hide: () => void;
  107. fly: () => void;
  108. bus: Emitter<{
  109. update: [MeasurePosition["point"][], MeasurePosition["modelId"][]];
  110. highlight: boolean;
  111. }>;
  112. changeSelect: (isHight: boolean) => void;
  113. setPositions: (
  114. points: MeasurePosition["point"][],
  115. modelIds: MeasurePosition["modelId"][]
  116. ) => void;
  117. }
  118. export type Measure<T extends StoreMeasure["type"] = StoreMeasure["type"]> =
  119. MeasureBase &
  120. (T extends MeasureType.area
  121. ? { getArea: () => { value: number } }
  122. : { getDistance: () => { value: number } });
  123. export type StartMeasure<T extends StoreMeasure["type"]> = Measure<T> & {
  124. bus: Emitter<{
  125. submit: [MeasurePosition["point"][], MeasurePosition["modelId"][]];
  126. cancel: void;
  127. invalidPoint: string;
  128. }>;
  129. };
  130. export type Pose =
  131. | {
  132. position: SceneLocalPos;
  133. target: SceneLocalPos;
  134. }
  135. | {
  136. panoId: any;
  137. model: SceneModel;
  138. posInModel: SceneLocalPos;
  139. rotInModel: SceneLocalPos;
  140. position: SceneLocalPos;
  141. target: SceneLocalPos;
  142. };
  143. export interface SDK {
  144. layout: HTMLDivElement;
  145. sceneBus: Emitter<{
  146. cameraChange: SceneLocalPos;
  147. panoModelChange: SceneModel;
  148. modeChange: { mode: "pano" | "fuse"; active: SceneModel };
  149. }>;
  150. setBackdrop: (
  151. drop: string,
  152. type: SettingResourceType,
  153. tb: { scale?: number; rotate?: number }
  154. ) => void;
  155. switchScene: (
  156. scene: { type: SceneType; num: string } | null
  157. ) => Promise<void>;
  158. startAddSth: () => void;
  159. endAddSth: () => void;
  160. addModel: (props: AddModelProps) => SceneModel;
  161. setCameraFov: (fov: number) => void;
  162. enableMap(dom: HTMLDivElement, latlng: number[]): void;
  163. switchMapType: (type: string) => void;
  164. showGrid: () => void;
  165. compassVisibility: (visibility: boolean) => void;
  166. canTurnToPanoMode: () => { model: SceneModel };
  167. hideGrid: () => void;
  168. calcPathInfo: (
  169. paths: CalcPathProps[0],
  170. info: CalcPathProps[1]
  171. ) => Required<CalcPathProps[1]>;
  172. getPositionByScreen: (
  173. screenPos: ScreenLocalPos,
  174. modelId?: FuseModel["id"]
  175. ) =>
  176. | (ScenePos & { worldPos: SceneLocalPos; localNormal: SceneLocalPos })
  177. | null;
  178. getScreenByPosition: (
  179. localPos: SceneLocalPos,
  180. modelId?: FuseModel["id"]
  181. ) => ScreenPos | null;
  182. screenshot: (width: number, height: number) => Promise<string>;
  183. getPose: () => Pose;
  184. comeTo: (pos: CameraComeToProps) => void;
  185. comeToByLatLng: (pos: number[]) => void;
  186. enterSceneGuide: (data: SceneGuidePath[]) => SceneGuide;
  187. drawMeasure<T extends StoreMeasure["type"]>(
  188. type: T,
  189. points: MeasurePosition["point"][],
  190. modelIds: MeasurePosition["modelId"][]
  191. ): Measure<T>;
  192. startMeasure<T extends StoreMeasure["type"]>(type: T): StartMeasure<T>;
  193. createTagging: (props: Tagging3DProps) => Tagging3D;
  194. createPath: (props: PathProps) => Path;
  195. createAnimationGroup: () => AnimationGroup;
  196. }
  197. export type PathProps = {
  198. // 线段名称
  199. name: string;
  200. // 是否显示名称,
  201. showName: boolean;
  202. // 文字大小
  203. fontSize: number;
  204. // 是否显示方向,
  205. showDirection: boolean;
  206. // 方向是否反向
  207. reverseDirection: boolean;
  208. line: {
  209. width: number;
  210. color: string;
  211. altitudeAboveGround: number;
  212. position?: SceneLocalPos;
  213. modelId?: string;
  214. };
  215. points: {
  216. // 点位名称
  217. name: string;
  218. position: SceneLocalPos;
  219. modelId: string;
  220. }[];
  221. };
  222. export type Path = {
  223. bus: Emitter<{
  224. activePoint: number;
  225. // 标注点击事件
  226. click: void;
  227. // 鼠标移入标注事件
  228. enter: void;
  229. // 鼠标移出标注事件
  230. leave: void;
  231. // 线段坐标更改事件
  232. linePositionChange: {
  233. pos: SceneLocalPos;
  234. modelId: string;
  235. };
  236. focus: boolean;
  237. // 路径点位置变更
  238. changePoints: PathProps["points"];
  239. drawed: void;
  240. }>;
  241. changeDirection: (show: boolean, reverse: boolean) => void;
  242. changeFontSize: (fontSize: number) => void;
  243. focus: (f: boolean) => void;
  244. highlight: (f: boolean) => void;
  245. changeVisibilityRange: (range: number) => void;
  246. changePointName: (index: number, name: string) => void;
  247. // 飞向路径
  248. fly: () => void;
  249. // 更改路径点
  250. changePathPoints: (
  251. points: Omit<PathProps["points"][number], "name">[]
  252. ) => void;
  253. // 播放路径,相机沿着路径运动,传入播放完毕回调
  254. play: (playedHandler: () => void) => void;
  255. // 停止播放路径
  256. pause: () => void;
  257. // 是否可编辑
  258. changeCanEdit: (canMove: boolean) => void;
  259. deletePoint: (index: number) => void;
  260. changeEditMode: (editMode: boolean) => void;
  261. // 可见性
  262. visibility: (visibility: boolean) => void;
  263. // 气泡是否可见
  264. visibilityName: (visibility: boolean) => void;
  265. // 更改标题气泡属性
  266. changeLine: (props: Partial<PathProps["line"]>) => void;
  267. // 更改标题气泡属性
  268. changeName: (name: string) => void;
  269. // 线段销毁
  270. destroy: () => void;
  271. };
  272. export type Tagging3DProps = {
  273. lineHeight: number;
  274. fontSize: number;
  275. // 标题
  276. title: string;
  277. // 标注类型 2d | 3d
  278. type: TaggingPositionType;
  279. // 模型id
  280. modelId: string;
  281. // 贴地射线获取的位置
  282. position: SceneLocalPos;
  283. normal: SceneLocalPos;
  284. // 是否可以移动
  285. canMove: boolean;
  286. // 贴地图片url
  287. image: string;
  288. // 贴地图片的变换
  289. mat: {
  290. scale: number;
  291. rotation: number;
  292. };
  293. };
  294. export type Tagging3D = {
  295. bus: Emitter<{
  296. // 标注点击事件
  297. click: void;
  298. // 鼠标移入标注事件
  299. enter: void;
  300. // 鼠标移出标注事件
  301. leave: void;
  302. // 位置变更
  303. changePosition: {
  304. pos: SceneLocalPos;
  305. modelId: string;
  306. normal: SceneLocalPos;
  307. };
  308. }>;
  309. changePosition: (position: {
  310. modelId: string;
  311. // 贴地射线获取的位置
  312. position: SceneLocalPos;
  313. normal: SceneLocalPos;
  314. }) => void;
  315. changeFontSize: (fontSize: number) => void;
  316. changeLineHeight: (lineHeight: number) => void;
  317. // 设置标题
  318. changeTitle: (title: string) => void;
  319. // 标题是否可见
  320. visibilityTitle: (visibility: boolean) => void;
  321. // 更改可拖拽移动
  322. changeCanMove: (canMove: boolean) => void;
  323. // 获取图标中心三维坐标
  324. getImageCenter: () => SceneLocalPos;
  325. // 更改图标
  326. changeImage: (url: string) => void;
  327. // 标注可见性
  328. visibility: (visibility: boolean) => void;
  329. // 标注图片变换,传入变换
  330. changeMat: (props: Tagging3DProps["mat"]) => void;
  331. // 更改热点类型
  332. changeType: (val: TaggingPositionType) => void;
  333. // 距离相机位置
  334. getCameraDisSquared: () => number;
  335. // 标注销毁
  336. destory: () => void;
  337. };
  338. // 动画组对象
  339. export type AnimationGroup = {
  340. // 播放
  341. play: () => void;
  342. // 暂停
  343. pause: () => void;
  344. // 添加动画模型
  345. addAnimationModel: (data: AnimationModel) => Promise<AnimationModel3D>;
  346. // 设置当前时间, 单位为秒
  347. setCurrentTime: (s: number) => void;
  348. bus: Emitter<{
  349. currentTime: number;
  350. }>;
  351. };
  352. export type AnimationModel3D = {
  353. // 销毁动画模型
  354. destroy: () => void;
  355. // 更改动画模型可见性
  356. changeShow: (show: boolean) => void;
  357. // 更改动画可见范围 不传为全局可见
  358. changeVisibilityRange: (range?: number) => void;
  359. // 更改模型名称
  360. changeTitle: (name: string) => void;
  361. // 更改名称字体大小
  362. changeFontSize: (size: number) => void;
  363. // 更改名称可见性
  364. visibilityTitle: (show: boolean) => void;
  365. // 添加模型帧
  366. addFrame: (frame: AnimationModelFrame) => AnimationModelFrame3D;
  367. // 添加模型动作
  368. addAction: (frame: AnimationModelAction) => AnimationModelAction3D;
  369. // 添加模型路径
  370. addPath: (
  371. frame: Omit<AnimationModelPath, "pathId"> & { path: Path }
  372. ) => AnimationModelPath3D;
  373. // 获取当前模型旁白出现的适合位置,传入旁边dom的宽高,返回像素位置
  374. getCurrentSubtitlePixel: (size: { width: number; height: number }) => {
  375. x: number;
  376. y: number;
  377. };
  378. // 获取当前时间改模型的姿态
  379. getCurrentMat: () => {
  380. position?: SceneLocalPos;
  381. scale?: number;
  382. rotation?: SceneLocalPos;
  383. originPosition?: SceneLocalPos;
  384. };
  385. // 进入旋转
  386. enterRotateMode: () => void
  387. enterMoveMode: () => void
  388. enterScaleMode: () => void
  389. leaveTransform: () => void;
  390. // 动画帧姿态修改数据
  391. bus: Emitter<{
  392. transformChanged: {
  393. position?: SceneLocalPos;
  394. scale?: number;
  395. rotation?: SceneLocalPos;
  396. originPosition?: SceneLocalPos;
  397. };
  398. }>;
  399. };
  400. export type AnimationModelFrame3D = {
  401. // 销毁动画模型帧
  402. destroy: () => void;
  403. // 修改帧播放时间 单位为秒
  404. changeTime: (s: number) => void;
  405. setMat: (mat: any) => void
  406. };
  407. export type AnimationModelAction3D = {
  408. // 销毁动画模型动作
  409. destroy: () => void;
  410. // 修改动作播放时间 单位为秒
  411. changeTime: (s: number) => void;
  412. // 修改动作幅度
  413. changeAmplitude: (n: number) => void;
  414. // 修改动作速度
  415. changeSpeed: (n: number) => void;
  416. // 修改动持续时间 单位为秒
  417. changeDuration: (n: number) => void;
  418. };
  419. export type AnimationModelPath3D = {
  420. // 销毁动画模型路径
  421. destroy: () => void;
  422. // 修改路径 传入参数为你之前返回的路径对象
  423. changePath: (path: Path | undefined) => void;
  424. // 修改播放是否要反向
  425. changeReverse: (reverse: boolean) => void;
  426. // 修改路径播放时间 单位为秒
  427. changeTime: (s: number) => void;
  428. // 修改路径续时间 单位为秒
  429. changeDuration: (n: number) => void;
  430. };
  431. export let sdk: SDK;
  432. export type InialSDKProps = {
  433. laserRoot?: string;
  434. ossRoot?: string;
  435. laserOSSRoot?: string;
  436. panoOSSRoot?: string;
  437. layout: HTMLDivElement;
  438. scenes: Scene[];
  439. lonlat?: number[];
  440. };
  441. export let initialed = false;
  442. export const initialSDK = async (props: InialSDKProps) => {
  443. if (initialed) return sdk;
  444. initialed = true;
  445. const libs = [
  446. `./lib/proj4/proj4.js`,
  447. `./lib/jquery/jquery-3.1.1.min.js`,
  448. `./lib/other/BinaryHeap.js`,
  449. `./lib/tween/tween.min.js`,
  450. `./lib/plasio/js/laslaz.js`,
  451. `./lib/plasio/vendor/bluebird.js`,
  452. `./lib/plasio/workers/laz-loader-worker.js`,
  453. `./lib/plasio/workers/laz-perf.js`,
  454. `./lib/Cesium/Cesium.js`,
  455. `./lib/shapefile/shapefile.js`,
  456. ];
  457. await Promise.all(libs.map(loadLib));
  458. await loadLib(`./lib/potree/potree.js`);
  459. console.log(props);
  460. const localSdk = cover({
  461. ...props,
  462. dom: props.layout,
  463. isLocal: false,
  464. scenes: props.scenes,
  465. lonlat: props.lonlat,
  466. mapDom: null,
  467. } as any) as unknown as SDK;
  468. (window as any).sdk = sdk = localSdk;
  469. sdk.layout = props.layout;
  470. return sdk;
  471. };
  472. export default sdk!;