@realsee/dnalogel 4.0.0-webgpu.3 → 4.0.0-webgpu.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/floorplan.js +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +270 -35
  5. package/dist/index.js.map +1 -0
  6. package/dist/internal/{BasePlugin-CT5K8m36.js → BasePlugin-DC5m72La.js} +3 -3
  7. package/dist/internal/{BasePlugin-CT5K8m36.js.map → BasePlugin-DC5m72La.js.map} +1 -1
  8. package/dist/internal/BasePluginWithData-D_0W46_q.js +7 -0
  9. package/dist/internal/{BasePluginWithData-9z4tpAT4.js.map → BasePluginWithData-D_0W46_q.js.map} +1 -1
  10. package/dist/internal/{BetterTween-BX0aTvP1.js → BetterTween-DmptqE8m.js} +2 -2
  11. package/dist/internal/{BetterTween-BX0aTvP1.js.map → BetterTween-DmptqE8m.js.map} +1 -1
  12. package/dist/internal/{CSS3DRenderPlugin-ccSpcvwd.js → CSS3DRenderPlugin-CEatgl0m.js} +3 -3
  13. package/dist/internal/CSS3DRenderPlugin-CEatgl0m.js.map +1 -0
  14. package/dist/internal/{Controller-Csut_kcH.js → Controller-D6o4OGWJ.js} +8 -8
  15. package/dist/internal/{Controller-Csut_kcH.js.map → Controller-D6o4OGWJ.js.map} +1 -1
  16. package/dist/internal/{FiveDomEvents-3H9NvDOz.js → FiveDomEvents-BUBLFzti.js} +2 -2
  17. package/dist/internal/{FiveDomEvents-3H9NvDOz.js.map → FiveDomEvents-BUBLFzti.js.map} +1 -1
  18. package/dist/internal/FivePuppet-C6QmVY70.js +67 -0
  19. package/dist/internal/FivePuppet-C6QmVY70.js.map +1 -0
  20. package/dist/internal/{PointHelper-D565h9b_.js → PointHelper-DIhgdjY2.js} +48 -48
  21. package/dist/internal/{PointHelper-D565h9b_.js.map → PointHelper-DIhgdjY2.js.map} +1 -1
  22. package/dist/internal/{Polygon-CBGvYUfJ.js → Polygon-D3xIL1Pl.js} +30 -30
  23. package/dist/internal/{Polygon-CBGvYUfJ.js.map → Polygon-D3xIL1Pl.js.map} +1 -1
  24. package/dist/internal/{Prism-Dm5ESkgg.js → Prism-CJlyAEAU.js} +13 -13
  25. package/dist/internal/{Prism-Dm5ESkgg.js.map → Prism-CJlyAEAU.js.map} +1 -1
  26. package/dist/internal/{Rectangle-D-zkDycu.js → Rectangle-BpL9lNKU.js} +118 -129
  27. package/dist/internal/Rectangle-BpL9lNKU.js.map +1 -0
  28. package/dist/internal/{Work-DF8j5GnL.js → Work-BE4AgdwH.js} +9 -9
  29. package/dist/internal/{Work-DF8j5GnL.js.map → Work-BE4AgdwH.js.map} +1 -1
  30. package/dist/internal/{animationFrame-XGKHIeQK.js → animationFrame-CacKXN8l.js} +14 -3
  31. package/dist/internal/animationFrame-CacKXN8l.js.map +1 -0
  32. package/dist/internal/{area-maker-Bd9l2pIp.js → area-maker-Bnhx4SkH.js} +4 -4
  33. package/dist/internal/{area-maker-Bd9l2pIp.js.map → area-maker-Bnhx4SkH.js.map} +1 -1
  34. package/dist/internal/{boundingBox-DvCor5Hd.js → boundingBox-CIqXgNXW.js} +2 -2
  35. package/dist/internal/{boundingBox-DvCor5Hd.js.map → boundingBox-CIqXgNXW.js.map} +1 -1
  36. package/dist/internal/{camera-movement-CwI7UqUk.js → camera-movement-C1pwfMk_.js} +2 -2
  37. package/dist/internal/camera-movement-C1pwfMk_.js.map +1 -0
  38. package/dist/internal/{changeMode-BVGYCoqu.js → changeMode-D_I2AOjH.js} +2 -2
  39. package/dist/internal/{changeMode-BVGYCoqu.js.map → changeMode-D_I2AOjH.js.map} +1 -1
  40. package/dist/internal/{controller-BWkZT0l1.js → controller-DIDtFrBE.js} +1991 -2050
  41. package/dist/internal/controller-DIDtFrBE.js.map +1 -0
  42. package/dist/internal/{cruise-C3F0eNQ-.js → cruise-B50Tcq66.js} +2 -2
  43. package/dist/internal/{cruise-C3F0eNQ-.js.map → cruise-B50Tcq66.js.map} +1 -1
  44. package/dist/internal/{current-pano-image-DKUWluR-.js → current-pano-image-BCFr6njt.js} +4 -4
  45. package/dist/internal/{current-pano-image-DKUWluR-.js.map → current-pano-image-BCFr6njt.js.map} +1 -1
  46. package/dist/internal/{defaultUrls-CjKkS9k9.js → defaultUrls-CfMtGzqM.js} +14 -3
  47. package/dist/internal/defaultUrls-CfMtGzqM.js.map +1 -0
  48. package/dist/internal/{fire-scene-CczaBz2_.js → fire-scene-BzZGvyh_.js} +9 -4
  49. package/dist/internal/fire-scene-BzZGvyh_.js.map +1 -0
  50. package/dist/internal/{fiveModelLoad-mg-TnpnM.js → fiveModelLoad-BUIBYxzp.js} +2 -2
  51. package/dist/internal/{fiveModelLoad-mg-TnpnM.js.map → fiveModelLoad-BUIBYxzp.js.map} +1 -1
  52. package/dist/internal/{floorplan-KWlIsTvO.js → floorplan-C8BGw87S.js} +5 -5
  53. package/dist/internal/{floorplan-KWlIsTvO.js.map → floorplan-C8BGw87S.js.map} +1 -1
  54. package/dist/internal/{generatePolygonGeometry-B_5JFq8y.js → generatePolygonGeometry-BOnzdCaG.js} +181 -178
  55. package/dist/internal/generatePolygonGeometry-BOnzdCaG.js.map +1 -0
  56. package/dist/internal/{lookObject-wesf8xt6.js → lookObject-DuRab5wf.js} +2 -2
  57. package/dist/internal/{lookObject-wesf8xt6.js.map → lookObject-DuRab5wf.js.map} +1 -1
  58. package/dist/internal/{measure-BX6boAC7.js → measure-B4jFwdQ6.js} +5 -5
  59. package/dist/internal/{measure-BX6boAC7.js.map → measure-B4jFwdQ6.js.map} +1 -1
  60. package/dist/internal/{model-chassis-compass-InVNmOAQ.js → model-chassis-compass-C6NTVMLo.js} +2 -2
  61. package/dist/internal/{model-chassis-compass-InVNmOAQ.js.map → model-chassis-compass-C6NTVMLo.js.map} +1 -1
  62. package/dist/internal/{model-entry-door-guide-wZbyY77a.js → model-entry-door-guide-DnGTLY2s.js} +2 -2
  63. package/dist/internal/{model-entry-door-guide-wZbyY77a.js.map → model-entry-door-guide-DnGTLY2s.js.map} +1 -1
  64. package/dist/internal/{model-maker-uO8xlTuO.js → model-maker-B1mnDdKY.js} +15 -15
  65. package/dist/internal/{model-maker-uO8xlTuO.js.map → model-maker-B1mnDdKY.js.map} +1 -1
  66. package/dist/internal/{model-tv-video-DzXb2JRf.js → model-tv-video-BP-7HoDC.js} +2 -2
  67. package/dist/internal/{model-tv-video-DzXb2JRf.js.map → model-tv-video-BP-7HoDC.js.map} +1 -1
  68. package/dist/internal/{model-view-CBeeMM98.js → model-view-BWUU0-uq.js} +2 -2
  69. package/dist/internal/{model-view-CBeeMM98.js.map → model-view-BWUU0-uq.js.map} +1 -1
  70. package/dist/internal/object3d-helper-CbRRhnLV.js +7 -0
  71. package/dist/internal/{object3d-helper-DDYsVPN6.js.map → object3d-helper-CbRRhnLV.js.map} +1 -1
  72. package/dist/internal/{pano-compass-jSr629BP.js → pano-compass-BRTM0dCc.js} +7 -7
  73. package/dist/internal/{pano-compass-jSr629BP.js.map → pano-compass-BRTM0dCc.js.map} +1 -1
  74. package/dist/internal/{pano-door-label-DKoYIKLa.js → pano-door-label-BLjYGZrr.js} +3 -3
  75. package/dist/internal/{pano-door-label-DKoYIKLa.js.map → pano-door-label-BLjYGZrr.js.map} +1 -1
  76. package/dist/internal/{pano-measure-DW9mdx1O.js → pano-measure-BIgCWkVJ.js} +14 -14
  77. package/dist/internal/{pano-measure-DW9mdx1O.js.map → pano-measure-BIgCWkVJ.js.map} +1 -1
  78. package/dist/internal/{pano-ruler-pro-D7q0Ob21.js → pano-ruler-pro-D9yTbHJz.js} +2 -2
  79. package/dist/internal/{pano-ruler-pro-D7q0Ob21.js.map → pano-ruler-pro-D9yTbHJz.js.map} +1 -1
  80. package/dist/internal/{pano-spatial-tag-D0qn-__S.js → pano-spatial-tag-B7Gxn3BS.js} +3 -3
  81. package/dist/internal/{pano-spatial-tag-D0qn-__S.js.map → pano-spatial-tag-B7Gxn3BS.js.map} +1 -1
  82. package/dist/internal/{pano-tag-BW5MXXws.js → pano-tag-Bchz-jED.js} +2 -2
  83. package/dist/internal/{pano-tag-BW5MXXws.js.map → pano-tag-Bchz-jED.js.map} +1 -1
  84. package/dist/internal/{pano-video-Bmud_CAn.js → pano-video-BufYQMqo.js} +3 -3
  85. package/dist/internal/{pano-video-Bmud_CAn.js.map → pano-video-BufYQMqo.js.map} +1 -1
  86. package/dist/internal/{pipeline-DDqgb1gw.js → pipeline-t_3IMXKB.js} +4 -4
  87. package/dist/internal/{pipeline-DDqgb1gw.js.map → pipeline-t_3IMXKB.js.map} +1 -1
  88. package/dist/internal/{sculpt-BNkLJR6p.js → sculpt-BCK4PMwL.js} +64 -63
  89. package/dist/internal/{sculpt-BNkLJR6p.js.map → sculpt-BCK4PMwL.js.map} +1 -1
  90. package/dist/internal/tagPosition-DA9YguT8.js +176 -0
  91. package/dist/internal/tagPosition-DA9YguT8.js.map +1 -0
  92. package/dist/internal/withResolvers-DVr4bnnk.js +15 -0
  93. package/dist/internal/withResolvers-DVr4bnnk.js.map +1 -0
  94. package/dist/plugins/area-maker.js +1 -1
  95. package/dist/plugins/camera-movement.js +1 -1
  96. package/dist/plugins/cruise.js +2 -2
  97. package/dist/plugins/css3d-render.js +1 -1
  98. package/dist/plugins/current-pano-image.js +1 -1
  99. package/dist/plugins/digital-performance.d.ts +1 -1
  100. package/dist/plugins/digital-performance.js +1 -1
  101. package/dist/plugins/fire-scene.d.ts +1 -1
  102. package/dist/plugins/fire-scene.js +1 -1
  103. package/dist/plugins/guide-line.js +1 -1
  104. package/dist/plugins/measure.js +1 -1
  105. package/dist/plugins/model-chassis-compass.js +1 -1
  106. package/dist/plugins/model-entry-door-guide.js +1 -1
  107. package/dist/plugins/model-maker.d.ts +1 -1
  108. package/dist/plugins/model-maker.js +1 -1
  109. package/dist/plugins/model-tv-video.js +1 -1
  110. package/dist/plugins/model-view.js +1 -1
  111. package/dist/plugins/object3d-helper.d.ts +1 -1
  112. package/dist/plugins/object3d-helper.js +3 -1
  113. package/dist/plugins/pano-compass.js +1 -1
  114. package/dist/plugins/pano-door-label.js +1 -1
  115. package/dist/plugins/pano-measure.js +1 -1
  116. package/dist/plugins/pano-ruler-pro.js +1 -1
  117. package/dist/plugins/pano-spatial-tag.js +1 -1
  118. package/dist/plugins/pano-tag.d.ts +1 -1
  119. package/dist/plugins/pano-tag.js +4 -1
  120. package/dist/plugins/pano-video.js +1 -1
  121. package/dist/plugins/pipeline.js +1 -1
  122. package/dist/plugins/sculpt.d.ts +1 -1
  123. package/dist/plugins/sculpt.js +7 -1
  124. package/dist/types/public/index.d.ts +2 -0
  125. package/dist/types/public/plugins/digital-performance.d.ts +1 -0
  126. package/dist/types/public/plugins/fire-scene.d.ts +1 -0
  127. package/dist/types/public/plugins/model-maker.d.ts +1 -0
  128. package/dist/types/public/plugins/object3d-helper.d.ts +1 -0
  129. package/dist/types/public/plugins/pano-tag.d.ts +2 -0
  130. package/dist/types/public/plugins/sculpt.d.ts +8 -0
  131. package/dist/types/public/utils.d.ts +5 -0
  132. package/dist/utils.d.ts +1 -1
  133. package/dist/utils.js +16 -50
  134. package/package.json +1 -1
  135. package/dist/internal/BasePluginWithData-9z4tpAT4.js +0 -7
  136. package/dist/internal/CSS3DRenderPlugin-ccSpcvwd.js.map +0 -1
  137. package/dist/internal/Rectangle-D-zkDycu.js.map +0 -1
  138. package/dist/internal/animationFrame-XGKHIeQK.js.map +0 -1
  139. package/dist/internal/blink-DD_0mH-m.js +0 -113
  140. package/dist/internal/blink-DD_0mH-m.js.map +0 -1
  141. package/dist/internal/camera-movement-CwI7UqUk.js.map +0 -1
  142. package/dist/internal/controller-BWkZT0l1.js.map +0 -1
  143. package/dist/internal/defaultUrls-CjKkS9k9.js.map +0 -1
  144. package/dist/internal/fire-scene-CczaBz2_.js.map +0 -1
  145. package/dist/internal/generatePolygonGeometry-B_5JFq8y.js.map +0 -1
  146. package/dist/internal/object3d-helper-DDYsVPN6.js +0 -7
  147. package/dist/utils.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pano-measure-DW9mdx1O.js","names":["image","deleteBg","deleteSvg","deleteHoverBg","disableFiveEvent","Subscribe","htmlString","TWEEN.Tween","root","$.from_html","root_1","root_2","root_3","$.mutable_source","$.prop","$.get","$.sibling","$.child","$.set_style","$.index","$.untrack","$.mutate","$.set_class","$.set","$.pop","root","$.from_html","$.prop","root","$.from_html","root_1","$.prop","$.mutable_source","$.child","$.deep_read_state","$.untrack","$.sibling","$.set_class","$.get","$.set_style","$.derived_safe_equal","root","$.from_html","root_1","root_2","$.mutable_source","$.prop","$.get","$.deep_read_state","$.child","$.sibling","$.index","$.set_style","$.untrack","$.mutate","$.set_class","$.set","root","$.from_html","root_1","$.mutable_source","$.prop","$.deep_read_state","$.child","$.only_child","$.set_text","$.set_style","$.get","root","$.from_html","$.prop","$.mutable_source","$.get","$.child","$.deep_read_state","$.untrack","$.sibling","$.derived_safe_equal","$.set_class","$.set_style","mobileHTMLString","htmlString","$.from_html","$.prop","$.mutable_source","$.get","$.deep_read_state","$.comment","$.first_child","$.child","$.only_child","$.set","$.set_text","objectAssignDeep","BasePlugin.Controller","MeasureController","__toESM","isTouchDevice","PointSelector","html_default","Magnifier","calculateThreeMouse","getGeometryInfo","isIntersecting","generatePolygonGeometry","getFiveModel","centerPoint","IObject3D","throttle","notNil","isNil","uuid","Tween","Easing","requestAnimationFrameInterval","Controller","if_block","template_effect","only_child","child","event","append","comment","onDestroy","from_html","set","deep_read_state","key","legacy_pre_effect","untrack","legacy_pre_effect_reset","mutable_source","sibling","mutate","transition","each","bind_prop","derived_safe_equal","push","set_text","onMount","bind_this","set_class","prop","init","set_style","first_child","pop","reset","mountComponent","index","get","require_objectAssignDeep","safeObj","FiveLine","fade","omit","THREE","lineWidth","lightLineWidth","lineColor","Color","lightLineColor","pointColor","lightPointColor","pointSize","lightPointSize","pointImage","pointTexture","getPointTexture","TextureLoader","normalLineOpts","lightLineOpts","createLine","opts","lineRenderOrder","pointsRenderOrder","line","start","end","pointMaterial","createLineMesh","point","anotherPoint","type","fiveLine","isNDCPointInScreen","ndcPoint","x","y","z","isNDCPointInFront","createContentDom","contentDom","params","createContainerDom","containerDom","ItemDom","canSelect","container","fiveElement","five","screenWidth","screenHeight","ndcDomPosition","left","top","DistanceItem","style","startPoint","endPoint","distance","customDefaultText","customDistanceText","halfScreenWidth","halfScreenHeight","p","ndcStartPosition","ndcEndPosition","screenStartPosition","Vector2","screenEndPosition","lineScreenLength","cameraDistance","fov","sseDenominator","scaleFactor","deg","offsetY","content","\"five\"","Line","model","Subscribe","modelPolyline","polyline","id","text","Point","Vector3","position","preventDefault","BaseController","area","intersection","mesh","positionVector","lookAtVector","Polyline","pointsSet","config","lastPoint","lastLine","lines","item","_id","data","createPointCache","pointData","anotherPointData","getPoint","pointMap","cachePoint","getAllPoints","blankGeometry","PolygonMesh","materialFront","materialBackground","meshFront","meshBackground","points","newGeometry","AreaItem","geometry","_geometry","geometryInfo","center","fix","unit","Area","lineStart","lineEnd","svg","image$1","image","DeleteDom","deleteSvgDom","element","target","ndcPoints","xArray","yArray","centerX","maxY","wrapper","centerScreenX","maxScreenY","k","centerScreenY","closestPointOnLine","tA","linePoints","tB","tC","tD","tParam","tXx","tYy","samePointAt","point1","point2","disableFiveEvent$1","EditController","isArea","isLine","_polyline","revokedLine","noPolygon","currentPosition","nowPoint","getAdherePoints","pointHelper","pointSelectorInstance","normal","intersectPoint","offset","xLine","yLine","autoEndLineLength","autoEndAreaLength","dashedStart","dashedEnd","mousePosition","perpendicularDashedStart","perpendicularDashedEnd","segments","intersected0","intersected2","newPoints","intersections","raycaster","a","b","intersectionObject","camera","ndcTarget","targetScreenPosition","screenLines","ndcStartPoint","ndcEndPoint","startScreenPosition","endScreenPosition","closestScreenLine","closestPoint","closestLine","highlightLines","clickPosition","firstLine","ViewController","mode","panoIndex","ndc2Screen","ndcPosition","containerSize","findClosestPoint","tapPoint","maxDistance","getPointFromHammerEvent","clientX","clientY","clientRect","clientWidth","clientHeight","disableFiveEvent","WatchController","m","Hammer","hammer","_area","_lines","mouse","editPointState","Raycaster","Model","Subscribe$1","polylineData","polylines","noop","mobileTextureUrl","pcTextureUrl","getMouseGroup","isMobile","useNormalVector","ballColor","group","Group","planGeometry","PlaneGeometry","planTextureUrl","planTexture","SRGBColorSpace","LinearFilter","planMaterial","MeshBasicMaterial","planMesh","Mesh","zPath","CurvePath","LineCurve3","zGeometry","TubeGeometry","colors","uv","i","BufferAttribute","zMaterial","zMesh","ballGeometry","SphereGeometry","ballMaterial","DoubleSide","ballMesh","RangePieceController","RingGeometry","newState","aimRef","width","height","mouseXY","face","matrix","scale","vector","cameraPos","firstEasing","from","to","stop","firstTween","opacity","time","value","MixedController","disposer","startIconImage","endIconImage","mobileHTML_default","HTML_default","uiWrapperStyle","operatingSpaceStyle","controllerBackgroundStyle","mainItemStyle","exitItemStyle","mainIconStyle","exitIconStyle","textStyle","MainBtnController","measureController","revokeTextDom","exitTextDom","mainTextDom","mainItem","mainIcon","MobileMainBtnController","Revoke","revokeIcon","revokeItem","root$6","root_1$4","root_2$2","root_3$1","Switcher0","$$props","activeButton","setIndex","activeIndex","options","onChange","elementList","activeButtonWidth","activeButtonLeft","$$exports","div","node","consequent","div_1","styles","$$anchor","$$render","div_2","classes","div_3","classes_1","div_4","node_1","consequent_1","span","styles_1","option","$$value","root$5","Exit","onClick","$$args","IconUndo","IconOk","IconLine","IconArea","root$4","root_1$3","Controller0","showExit","i18n","canRevoke","setSwitcherActiveIndex","handleModeChange","showController","complete","handlePointsChange","handleComplete","div_5","div_6","div_7","text_1","$0","$1","div_8","node_2","root$3","root_1$2","root_2$1","Switcher1","defaultKey","setAnimeResult","newActiveButtonLeft","styles_2","root$2","root_1$1","CircleButton","bgImage","color","root$1","root_1","root_2","root_3","Controller1","buttonTextMap","buttonColorMap","showButton","allowAddPoint","buttonState","lastButtonState","currentMeasureType","changeButtonState","addPoint","state","onAllowAddPointStateChange","readyComplete","notReadyComplete","setStartState","onMeasureTypeChange","measureType","onRevoke","node_3","consequent_2","node_5","consequent_3","div_9","UIController","useNewUI","textDoms","bgDom","operatingSpaceDom","exitIcon","exitItem","onMouseEnter","onMouseLeave","handleClick","import_objectAssignDeep","root","Tip","tips","tipStyle","visible","textDom","getTip","currentType","tip","setTip","clear","pointsChange","fragment","pcTip","mobileTip","GuideController","ShortcutKeyController","PanoMeasureController","pointSelectorMode","openParams","uiControllerParams","guideControllerParams","transformedData","controllerMap","controllerParams","lineID","areas","editParams","PanoMeasurePlugin"],"sources":["../../src/PanoMeasurePlugin/utils/constants.ts","../../src/PanoMeasurePlugin/utils/line.ts","../../src/PanoMeasurePlugin/utils/isNDCPointInScreen.ts","../../src/PanoMeasurePlugin/utils/dom/base.ts","../../src/PanoMeasurePlugin/utils/dom/distanceItem.ts","../../src/PanoMeasurePlugin/Model/line.ts","../../src/PanoMeasurePlugin/Model/point.ts","../../src/PanoMeasurePlugin/utils/ironbox.ts","../../src/PanoMeasurePlugin/Controller/BaseController.ts","../../src/PanoMeasurePlugin/Model/polyline.ts","../../src/PanoMeasurePlugin/Model/polygon.ts","../../src/PanoMeasurePlugin/utils/dom/areaDom.ts","../../src/PanoMeasurePlugin/Model/area.ts","../../src/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete.svg.ts","../../src/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete_bg.png.ts","../../src/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete_hover_bg.png.ts","../../src/PanoMeasurePlugin/Modules/DeleteDom/index.ts","../../src/PanoMeasurePlugin/utils/math.ts","../../src/PanoMeasurePlugin/Controller/EditController.ts","../../src/PanoMeasurePlugin/Controller/ViewController.ts","../../src/PanoMeasurePlugin/utils/ndc2Screen.ts","../../src/PanoMeasurePlugin/utils/findClosestPoint.ts","../../src/shared-utils/getPointFromHammerEvent.ts","../../src/PanoMeasurePlugin/Controller/WatchController.ts","../../src/PanoMeasurePlugin/Model/index.ts","../../src/shared-utils/noop.ts","../../src/PanoMeasurePlugin/utils/mouseGroup.ts","../../src/PanoMeasurePlugin/Modules/rangePiece/index.ts","../../src/PanoMeasurePlugin/Controller/MixedController.ts","../../src/PanoMeasurePlugin/Modules/UIController/mobileHTML.ts","../../src/PanoMeasurePlugin/Modules/UIController/HTML.ts","../../src/PanoMeasurePlugin/Modules/UIController/style.ts","../../src/PanoMeasurePlugin/Modules/UIController/MainBtnController.ts","../../src/PanoMeasurePlugin/Modules/UIController/mobileMainBtnController.ts","../../src/PanoMeasurePlugin/Modules/UIController/Revoke/index.ts","../../src/PanoMeasurePlugin/Components/Common/Switcher0.svelte","../../src/PanoMeasurePlugin/Components/Common/Exit.svelte","../../src/PanoMeasurePlugin/Components/Common/icons/index.ts","../../src/PanoMeasurePlugin/Components/Controller0.svelte","../../src/PanoMeasurePlugin/Components/Common/Switcher1.svelte","../../src/PanoMeasurePlugin/Components/Common/CircleButton.svelte","../../src/PanoMeasurePlugin/Components/Controller1.svelte","../../src/PanoMeasurePlugin/Modules/UIController/index.ts","../../src/PanoMeasurePlugin/Components/Tip.svelte","../../src/PanoMeasurePlugin/Components/Tip.svelte","../../src/PanoMeasurePlugin/Modules/GuideController.ts","../../src/PanoMeasurePlugin/Controller/ShortcutKeyController.ts","../../src/PanoMeasurePlugin/Controller/index.ts","../../src/PanoMeasurePlugin/index.ts"],"sourcesContent":["import type { ICreateLineOpts } from './line'\nimport { TextureLoader, Color } from 'three/webgpu'\n\nconst lineWidth = 1\nconst lightLineWidth = 3\nconst lineColor = new Color(0xffffff)\nconst lightLineColor = new Color(0x6386ff)\nconst pointColor = new Color(0xffffff)\nconst lightPointColor = new Color(0x6386ff)\nconst pointSize = 6\nconst lightPointSize = 8\nconst pointImage =\n 'data:image/png;base64,' +\n 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAIVBMVEUAAAD////////////////////////////////////////PIev5AAAACnRSTlMAG/Py2baba05un7UgfgAAAHJJREFUKM9joBpgLHVSCRdA4metAoJlCJHmVWBgAeNzroKCCVCBLpjACqgJVjCBxRBT2FbBQQJYQAohsBAsUIUQWA4WiEIILAULeCEEloAFtBACizAEMLRgGIphLabDMJ2O6TlM72MGECIIMQIZIxqoBQCPvpJ/e9FaAAAAAABJRU5ErkJggg=='\nlet pointTexture: ReturnType<TextureLoader['load']> | undefined\n\nexport function getPointTexture() {\n return (pointTexture ??= new TextureLoader().load(pointImage))\n}\n\nexport const normalLineOpts: ICreateLineOpts = {\n pointSize,\n lineWidth,\n lineColor,\n pointColor,\n lineRenderOrder: 20,\n pointsRenderOrder: 20,\n}\n\nexport const dashLineOpts: ICreateLineOpts = { ...normalLineOpts, dashed: true }\n\nexport const lightLineOpts: ICreateLineOpts = {\n pointSize: lightPointSize,\n lineWidth: lightLineWidth,\n lineColor: lightLineColor,\n pointColor: lightPointColor,\n lineRenderOrder: 10,\n pointsRenderOrder: 10,\n}\n","import { FiveLine } from '../../shared-utils/five/FiveLine'\nimport type Line from '../Model/line'\nimport { getPointTexture, lightLineOpts, normalLineOpts } from './constants'\nimport type { PointsMaterial, Texture, Vector3 } from 'three/webgpu'\nimport { Color } from 'three/webgpu'\n\ntype ISetMaterialOpts = Parameters<FiveLine['setMaterial']>[0]\n\nexport interface ICreateLineOpts extends ISetMaterialOpts {\n hasPoint?: boolean\n pointSize?: number\n lineWidth?: number\n pointTexture?: Texture\n lineRenderOrder?: number\n pointsRenderOrder?: number\n lineColor?: Color | string | number\n pointColor?: Color | string | number\n}\n\nexport function createLine(start: Vector3, end: Vector3, opts?: ICreateLineOpts) {\n const lineWidth = opts?.lineWidth ?? 2\n const lineColor = opts?.lineColor ?? (new Color(0xffffff) as any)\n const pointSize = opts?.pointSize ?? 5\n const lineRenderOrder = opts?.lineRenderOrder ?? 10\n const pointsRenderOrder = opts?.lineRenderOrder ?? 20\n const line = new FiveLine(start, end)\n // set line\n line.setMaterial({ linewidth: lineWidth, color: lineColor })\n line.line.material.depthTest = false\n line.line.material.transparent = true\n line.line.renderOrder = lineRenderOrder\n // set point\n line.points.renderOrder = pointsRenderOrder\n const pointMaterial = line.points.material as PointsMaterial\n pointMaterial.depthTest = false\n pointMaterial.size = pointSize\n if (opts?.pointColor !== undefined) pointMaterial.color.set(opts.pointColor)\n if (opts?.pointTexture) pointMaterial.map = opts.pointTexture\n return line\n}\n\nexport function createLineMesh(line: Line, type: 'normal' | 'light') {\n const [point, anotherPoint] = line.points\n const opts = type === 'light' ? lightLineOpts : normalLineOpts\n const fiveLine = createLine(point.position, anotherPoint.position, { ...opts, pointTexture: getPointTexture() })\n fiveLine.name = 'normalLine_' + line.id\n return fiveLine\n}\n","import type { Vector3 } from 'three/webgpu'\n\nexport default function isNDCPointInScreen(ndcPoint: Vector3) {\n const { x, y, z } = ndcPoint\n if (Math.abs(x) > 1 || Math.abs(y) > 1 || Math.abs(z) > 1) return false\n return true\n}\n\nexport function isNDCPointInFront(ndcPoint: Vector3) {\n const { z } = ndcPoint\n if (Math.abs(z) > 1) return false\n return true\n}\n","import type { Vector3 } from 'three/webgpu'\nimport { isNDCPointInFront } from '../isNDCPointInScreen'\nimport type { Five } from '@realsee/five-webgpu'\n\nexport interface ItemDomParams {\n clickCallback?: (event: MouseEvent, item: ItemDom) => unknown\n containerStyle?: Partial<CSSStyleDeclaration>\n contentStyle?: Partial<CSSStyleDeclaration>\n}\n\nfunction createContentDom(params?: { style?: Partial<CSSStyleDeclaration> }) {\n const contentDom = document.createElement('div')\n contentDom.setAttribute(\n 'style',\n `backdrop-filter: blur(4px);-webkit-backdrop-filter: blur(4px);-webkit-tap-highlight-color: rgba(0,0,0,0);`,\n )\n contentDom.style.width = 'max-content'\n contentDom.style.padding = '3px 6px'\n contentDom.style.lineHeight = '1'\n contentDom.style.textAlign = 'center'\n contentDom.style.transform = 'translate(-50%, -50%)'\n contentDom.style.fontSize = '14px'\n contentDom.style.color = '#fff'\n contentDom.style.cursor = 'pointer'\n contentDom.style.userSelect = 'none'\n if (params?.style) Object.assign(contentDom.style, params?.style)\n\n return contentDom\n}\n\nfunction createContainerDom(params?: { id?: string; style?: Partial<CSSStyleDeclaration> }) {\n const containerDom = document.createElement('div')\n if (params?.id) containerDom.id = params?.id\n containerDom.classList.add('five-plugin-measure__distance')\n containerDom.style.position = 'absolute'\n containerDom.style.left = '0'\n containerDom.style.top = '0'\n containerDom.style.width = '0'\n containerDom.style.height = '0'\n containerDom.style.transform = 'translate(-10px, -10px)' // 狗屎代码\n containerDom.style.transformOrigin = 'left top'\n if (params?.style) Object.assign(containerDom.style, params.style)\n return containerDom\n}\n\nexport abstract class ItemDom {\n public ndcPosition: Vector3 | null\n\n protected contentDom: HTMLElement\n protected containerDom: HTMLElement\n protected params: ItemDomParams\n protected canSelected: boolean\n\n public constructor(params: ItemDomParams) {\n this.params = params\n this.contentDom = createContentDom({ style: params.contentStyle })\n this.containerDom = createContainerDom({ style: params.containerStyle })\n this.setCanSelect(true)\n }\n\n public handleClick = (e: MouseEvent) => {\n this.params.clickCallback?.(e, this)\n }\n\n public setCanSelect(canSelect: boolean) {\n this.canSelected = canSelect\n this.containerDom.style.pointerEvents = canSelect ? 'all' : 'none'\n }\n\n public highlight() {\n this.contentDom.style.border = '0.5px solid #95AEFF'\n this.contentDom.style.background = 'linear-gradient(90deg, #95AEFF 0%, #6386FF 100%)'\n }\n\n public unHighlight() {\n this.contentDom.style.border = '0.5px solid rgba(255,255,255,0.6)'\n this.contentDom.style.background = 'rgba(195,195,195,0.70)'\n }\n\n public appendTo(container: Element) {\n container.appendChild(this.containerDom)\n this.containerDom.addEventListener('click', this.handleClick)\n return this\n }\n\n public remove() {\n this.contentDom.removeEventListener('click', this.handleClick)\n this.containerDom.remove()\n }\n\n public show() {\n this.containerDom.style.visibility = 'visible'\n }\n\n public hide() {\n this.containerDom.style.visibility = 'hidden'\n }\n\n public tempHide() {\n this.containerDom.style.opacity = '0'\n }\n\n public tempShow() {\n this.containerDom.style.opacity = '1'\n }\n\n /**\n * @description: camera update 的时候,更新dom的位置\n */\n public updateDomPosition(five: Five) {\n if (!this.ndcPosition) {\n this.tempHide()\n return\n }\n\n const fiveElement = five.getElement()\n if (!fiveElement) return\n\n const screenWidth = fiveElement.clientWidth\n const screenHeight = fiveElement.clientHeight\n\n const ndcDomPosition = this.ndcPosition.clone().project(five.camera)\n if (!isNDCPointInFront(ndcDomPosition)) {\n this.tempHide()\n return\n }\n\n const left = ((ndcDomPosition.x + 1) / 2) * screenWidth\n const top = (-(ndcDomPosition.y - 1) / 2) * screenHeight\n\n this.containerDom.style.transform = `translate(${left}px, ${top}px)`\n this.tempShow()\n }\n}\n","import type { ItemDomParams } from './base'\nimport { ItemDom } from './base'\nimport type Line from '../../Model/line'\nimport type { Five } from '@realsee/five-webgpu'\nimport { Vector2 } from 'three/webgpu'\nimport { isNDCPointInFront } from '../isNDCPointInScreen'\nimport type { Polyline } from '../../Model/polyline'\nimport { centerPoint } from '../../../shared-utils/three/centerPoint'\n\nexport interface UserDistanceItem {\n element: Element\n highlight: () => void\n unHighlight: () => void\n update: (params: { line: Line; polyline: Polyline }) => void\n}\n\ninterface DistanceItemParams extends ItemDomParams {\n line: Line\n userDistanceItem?: UserDistanceItem\n}\n\nexport class DistanceItem extends ItemDom {\n protected declare params: DistanceItemParams\n private line: Line\n private lastFOV: number | undefined\n private cameraUpdateHandler: (() => void) | null = null\n\n public constructor(params: DistanceItemParams) {\n params.contentStyle = {\n ...params.contentStyle,\n ...{\n background: '#FFFFFF',\n color: '#041066',\n fontFamily: 'Arial-BoldMT',\n fontWeight: 'BoldMT',\n letterSpacing: '0',\n lineHeight: '20px',\n padding: '2px 8px',\n borderRadius: '12px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n '--distance-scale': '1' /* Default scale if not provided */,\n transition: 'font-size 0.5s ease' /* Smooth transition for font size */,\n },\n }\n super(params)\n this.line = params.line\n this.params.userDistanceItem?.element\n ? this.containerDom.appendChild(this.params.userDistanceItem.element)\n : this.containerDom.appendChild(this.contentDom)\n\n if (!document.getElementById('PanoMeasurePluginFontSizes')) {\n const style = document.createElement('style')\n style.id = 'PanoMeasurePluginFontSizes'\n document.head.appendChild(style)\n style.innerHTML = `\n .pano-measure-item-content {\n transition: font-size 0.5s ease; /* Smooth transition for font size */\n }\n \n /* sm screen */\n @media screen and (max-width: 499px) {\n .pano-measure-item-content {\n font-size: calc(12px + (14px - 12px) * var(--distance-scale));\n }\n }\n \n /* md screen */\n @media screen and (min-width: 500px) and (max-width: 929px) {\n .pano-measure-item-content {\n font-size: calc(12px + (14px - 12px) * var(--distance-scale));\n }\n }\n \n /* lg screen */\n @media screen and (min-width: 930px) and (max-width: 1365px) {\n .pano-measure-item-content {\n font-size: calc(14px + (16px - 14px) * var(--distance-scale));\n }\n }\n \n /* xl screen */\n @media screen and (min-width: 1366px) and (max-width: 2549px) {\n .pano-measure-item-content {\n font-size: calc(14px + (16px - 14px) * var(--distance-scale));\n }\n }\n \n /* xxl screen */\n @media screen and (min-width: 2550px) {\n .pano-measure-item-content {\n font-size: calc(0.875rem + (1rem - 0.875rem) * var(--distance-scale));\n }\n }\n `\n }\n\n this.contentDom.classList.add('pano-measure-item-content')\n }\n\n public appendTo(container: Element) {\n super.appendTo(container)\n // Register camera update handler when added to DOM\n if (!this.cameraUpdateHandler) {\n this.cameraUpdateHandler = () => this.onCameraUpdate()\n // Find the Five instance through the model\n const five = this.getFiveInstance()\n if (five) {\n five.on('cameraUpdate', this.cameraUpdateHandler)\n five.on('cameraFovUpdate', this.cameraUpdateHandler)\n five.on('panoArrived', this.onPanoChange)\n }\n }\n return this\n }\n\n public remove() {\n // Clean up camera update handler when removed\n if (this.cameraUpdateHandler) {\n const five = this.getFiveInstance()\n if (five) {\n five.off('cameraUpdate', this.cameraUpdateHandler)\n five.off('cameraFovUpdate', this.cameraUpdateHandler)\n five.off('panoArrived', this.onPanoChange)\n }\n this.cameraUpdateHandler = null\n }\n super.remove()\n }\n\n /** 获取内容文本 */\n public getCurrentContent() {\n if (this.line.points.length < 2) return ''\n const [startPoint, endPoint] = this.line.points\n const distance = startPoint.position.clone().distanceTo(endPoint.position)\n const customDefaultText = this.line.text ?? this.line.model.config?.defaultText\n const customDistanceText = this.line.model.config?.getDistanceText?.(distance)\n const customText = customDefaultText ?? customDistanceText\n // 优先级:用户自定义默认文本 > 用户自定义距离文本 > 默认文本\n return customText ?? distance.toFixed(2) + 'm'\n }\n\n public update(five: Five) {\n if (this.line.mesh.visible === false) {\n this.hide()\n return\n }\n const fiveElement = five.getElement()\n if (!fiveElement) return\n const screenWidth = fiveElement.clientWidth\n const screenHeight = fiveElement.clientHeight\n const halfScreenWidth = screenWidth / 2\n const halfScreenHeight = screenHeight / 2\n if (this.line.points.length < 2) return\n const [startPoint, endPoint] = this.line.points.map((p) => p.position.clone().applyMatrix4(this.line.mesh.matrixWorld))\n const ndcStartPosition = startPoint.clone().project(five.camera)\n const ndcEndPosition = endPoint.clone().project(five.camera)\n const ndcDomPosition = centerPoint(startPoint, endPoint).clone().project(five.camera)\n const screenStartPosition = new Vector2(ndcStartPosition.x * halfScreenWidth, ndcStartPosition.y * halfScreenHeight)\n const screenEndPosition = new Vector2(ndcEndPosition.x * halfScreenWidth, ndcEndPosition.y * halfScreenHeight)\n const lineScreenLength = screenStartPosition.distanceTo(screenEndPosition)\n const visible = (() => {\n // 对于超过近平面和远平面的点,计算会有问题\n if (Math.abs(ndcStartPosition.z) > 1 || Math.abs(ndcEndPosition.z) > 1) return false\n if (!isNDCPointInFront(ndcStartPosition) && !isNDCPointInFront(ndcEndPosition)) return false\n if (!isNDCPointInFront(ndcDomPosition)) return false\n if (lineScreenLength === 0) return false\n return true\n })()\n if (visible === false) {\n this.hide()\n return\n }\n\n // Calculate distance-based scale factor\n const centerPosition = centerPoint(startPoint, endPoint)\n const cameraDistance = centerPosition.distanceTo(five.camera.position)\n\n // Include FOV in scale calculation\n const fov = five.camera.fov || 60\n const sseDenominator = 2.0 * Math.tan(((0.5 * fov) / 180) * Math.PI)\n const scaleFactor = Math.max(Math.min(1 - (sseDenominator * cameraDistance) / 40, 1), 0)\n\n // Set the CSS variable for distance scaling\n this.contentDom.style.setProperty('--distance-scale', scaleFactor.toString())\n\n // 更新 UI\n const left = ((ndcDomPosition.x + 1) / 2) * screenWidth\n const top = (-(ndcDomPosition.y - 1) / 2) * screenHeight\n const rad = Math.atan((screenStartPosition.y - screenEndPosition.y) / (screenStartPosition.x - screenEndPosition.x))\n const deg = -(rad * 180) / Math.PI\n const offsetY = this.containerDom.parentElement && this.contentDom.clientWidth > lineScreenLength ? -20 : 0\n this.containerDom.style.transform = `translate(${left}px, ${top}px) rotate(${deg}deg) translateY(${offsetY}px)`\n this.show()\n\n this.params.userDistanceItem?.update({ line: this.line, polyline: this.line.getPolyline() })\n\n const content = this.getCurrentContent()\n this.contentDom.innerText = content\n }\n\n private getFiveInstance(): Five | undefined {\n // Try to get Five through the model's hierarchy\n return this.line.model?.config?.['five'] as Five | undefined\n }\n\n private onCameraUpdate() {\n const five = this.getFiveInstance()\n if (five?.camera && this.lastFOV !== five.camera.fov) {\n this.lastFOV = five.camera.fov\n this.update(five)\n }\n }\n\n private onPanoChange = () => {\n const five = this.getFiveInstance()\n if (five) {\n // Add slight delay to ensure the camera position is updated\n setTimeout(() => this.update(five), 100)\n }\n }\n}\n","import type * as THREE from 'three/webgpu'\nimport type { Model } from '.'\nimport type Point from './point'\nimport type { LineJson } from '../typings/data'\nimport type { Polyline } from './polyline'\nimport uuid from '../../shared-utils/uuid'\nimport { createLineMesh } from '../utils/line'\nimport { Subscribe, type SubscribeEventMap } from '@realsee/five-webgpu'\nimport { DistanceItem } from '../utils/dom/distanceItem'\nimport type { FiveLine } from '../../shared-utils/five/FiveLine'\n\nexport interface ILineHook extends SubscribeEventMap {\n selected: (line: Line) => void\n\n textChanged: (text: string | undefined) => void\n}\n\nexport default class Line {\n public id: string\n public selected = false\n public text?: string\n public readonly type = 'line'\n public readonly model: Model\n public readonly mesh: FiveLine\n public readonly points: Point[]\n public readonly lightMesh: FiveLine\n public readonly hook: Subscribe<ILineHook>\n public readonly distanceItem: DistanceItem\n\n private polyline?: Polyline\n private visible?: boolean\n\n public constructor(point: Point, anotherPoint: Point, model: Model) {\n this.id = uuid()\n this.model = model\n if (point.id === anotherPoint.id) throw new Error('无效的线段, 一个点无法构成线段')\n if (typeof model.config.defaultText === 'string') this.text = model.config.defaultText\n this.hook = new Subscribe<ILineHook>()\n this.points = [point, anotherPoint]\n this.mesh = createLineMesh(this, 'normal')\n this.lightMesh = createLineMesh(this, 'light')\n this.distanceItem = new DistanceItem({\n line: this,\n clickCallback: () => this.hook.emit('selected', this),\n userDistanceItem: this.model.config?.userDistanceItemCreator ? this.model.config.userDistanceItemCreator() : undefined,\n })\n }\n\n public hide() {\n if (!this.visible) return\n this.visible = false\n this.mesh.visible = false\n this.distanceItem.hide()\n }\n\n public show() {\n if (this.visible) return\n this.visible = true\n this.mesh.visible = true\n this.distanceItem.show()\n }\n\n public setPoints(startPoint: THREE.Vector3, endPoint: THREE.Vector3) {\n this.points[0].position.copy(startPoint)\n this.points[1].position.copy(endPoint)\n this.mesh.setPoints(startPoint, endPoint)\n }\n\n public remove(): void {\n if (this.mesh.parent) this.mesh.parent.remove(this.mesh)\n this.distanceItem.remove()\n }\n\n public clear(): void {\n this.selected = false\n this.polyline = undefined\n }\n\n public isEmpty() {\n return this.points.length === 0\n }\n\n public getPolyline(): Polyline {\n if (this.polyline) return this.polyline\n const modelPolyline = this.model.polylines.find((polyline) => polyline.lines.includes(this))\n if (modelPolyline) {\n this.polyline = modelPolyline\n return modelPolyline\n }\n }\n\n public findAnotherPoint(point: Point) {\n return this.points.find(({ id }) => id !== point.id)\n }\n\n public setText(text: string | null) {\n this.text = text\n this.hook.emit('textChanged', text)\n }\n\n public toJSON() {\n return this.toJson()\n }\n\n public toJson(): LineJson {\n return { id: this.id, points: this.points.map((point) => point.toJson()), text: this.text }\n }\n\n public clone() {\n const line = new Line(this.points[0].clone(), this.points[1].clone(), this.model)\n line.text = this.text\n return line\n }\n}\n","import type { PointJson } from '../typings/data'\nimport { Vector3 } from 'three/webgpu'\nimport uuid from '../../shared-utils/uuid'\n\nexport default class Point {\n public id: string\n public position: Vector3\n public readonly type = 'point'\n\n public constructor(position: Vector3 | number[]) {\n this.id = uuid()\n this.position = new Vector3()\n if (Array.isArray(position)) {\n this.position.fromArray(position)\n } else if (position instanceof Vector3) {\n this.position.copy(position)\n } else {\n throw new Error('position must be Vector3 or number[]')\n }\n }\n\n public toJson(): PointJson {\n return { id: this.id, position: this.position.toArray() }\n }\n\n public clone() {\n const point = new Point(this.position)\n return point\n }\n}\n","export const preventDefault = (e: Event) => e.preventDefault()\n","import { Color, type Group } from 'three/webgpu'\nimport type { Model } from '../Model'\nimport type { Config } from '../typings'\nimport type { PanoMeasurePluginEvent } from '../typings/event.type'\nimport type { UserDistanceItem } from '../utils/dom/distanceItem'\nimport type { Five, Intersection, IntersectMeshInterface } from '@realsee/five-webgpu'\nimport type { Subscribe } from '../../shared-utils/Subscribe'\nimport type { OpenParameter, EditParameter, MeasureType } from '../typings/data'\nimport Line from '../Model/line'\nimport Point from '../Model/point'\nimport { preventDefault } from '../utils/ironbox'\nimport type { Magnifier } from '../../shared-utils'\nimport type { WorkUtil } from '../../shared-utils/Utils/WorkUtil'\nimport type { PointSelectorConfig } from '../../shared-utils/three/PointSelector'\n\nexport interface ControllerParams {\n five: Five\n group: Group\n model: Model\n config: Config\n mouseGroup: Group\n container: Element\n workUtil: WorkUtil\n pointSelectorConfig?: PointSelectorConfig\n magnifier: Magnifier\n openParams: OpenParameter\n editParams: EditParameter\n getMeasureType: () => MeasureType\n hook: Subscribe<PanoMeasurePluginEvent>\n userDistanceItemCreator?: () => UserDistanceItem\n}\n\nexport default class BaseController {\n public model: Model\n protected five: Five\n protected group: Group\n protected config: Config\n protected dashed: Line\n protected perpendicularDashed: Line\n protected disposed = false\n protected isMobile: boolean\n protected editParams: EditParameter\n protected magnifierParams: ConstructorParameters<typeof Magnifier>[1]\n protected mouseGroup: Group\n protected container: Element\n protected hook: ControllerParams['hook']\n protected magnifier: ControllerParams['magnifier']\n protected userDistanceItemCreator: ControllerParams['userDistanceItemCreator']\n protected pointSelectorConfig: PointSelectorConfig\n protected workUtil: WorkUtil\n protected get currentMeasureType() {\n return this.getMeasureType()\n }\n private getMeasureType: ControllerParams['getMeasureType']\n\n public constructor(params: ControllerParams) {\n // ==================== Params ====================\n this.five = params.five\n this.hook = params.hook\n this.model = params.model\n this.getMeasureType = params.getMeasureType\n this.config = params.config\n this.editParams = params.editParams\n this.magnifierParams = params.pointSelectorConfig?.helper?.magnifierParams\n this.magnifier = params.magnifier\n this.pointSelectorConfig = {\n ...params.pointSelectorConfig,\n helper: { ...params.pointSelectorConfig?.helper },\n }\n this.container = params.container\n this.isMobile = params.openParams?.isMobile ?? false\n this.workUtil = params.workUtil\n this.userDistanceItemCreator = params.userDistanceItemCreator\n // ==================== Groups ====================\n this.group = params.group\n this.mouseGroup = params.mouseGroup\n // ==================== 虚线 ====================\n this.dashed = new Line(new Point([0, 0, 0]), new Point([0, 0, 0]), this.model)\n this.dashed.distanceItem.setCanSelect(false)\n this.dashed.mesh.setMaterial({ dashed: true, dashScale: 100 })\n this.dashed.mesh.name = 'dashLine'\n // ==================== 鼠标位置与面的垂线 ====================\n this.perpendicularDashed = new Line(new Point([0, 0, 0]), new Point([0, 0, 0]), this.model)\n this.perpendicularDashed.distanceItem.setCanSelect(false)\n this.perpendicularDashed.mesh.setMaterial({ dashed: true, dashScale: 40, color: new Color(0x9bea69) as any })\n this.perpendicularDashed.mesh.name = 'perpendicularDashLine'\n\n const fiveElement = this.five.getElement()\n if (fiveElement) {\n fiveElement.addEventListener('touchstart', preventDefault)\n fiveElement.addEventListener('contextmenu', preventDefault)\n }\n }\n\n public updateDistanceUI = () => {\n this.dashed.distanceItem.update(this.five)\n this.model.getAllLines().forEach((line) => line.distanceItem.update(this.five))\n }\n\n public updateAreaUI = () => {\n this.dashed.distanceItem.update(this.five)\n this.model.getAllAreas().forEach((area) => {\n area.areaItem.updateArea(this.five)\n area.polyline.lines.forEach((line) => {\n line.distanceItem.update(this.five)\n })\n })\n }\n\n protected removeLine(line: Line) {\n this.group.remove(line.mesh, line.lightMesh)\n line.distanceItem.remove()\n this.five.needsRender = true\n }\n\n protected updateMouseGroup(intersection: Intersection, mesh?: IntersectMeshInterface) {\n if (!intersection) return this.mouseGroup\n // ============ update mouseGroup position ============\n this.mouseGroup.position.copy(intersection.point)\n // ============ update mouseGroup quaternion ============\n if (mesh) {\n this.mouseGroup.quaternion.copy(mesh.quaternion)\n } else if (intersection.face) {\n const normal = intersection.face.normal\n const positionVector = normal.clone().multiplyScalar(0.05)\n const position = intersection.point.clone().add(positionVector)\n const lookAtVector = position.clone().add(positionVector)\n this.mouseGroup.lookAt(lookAtVector)\n }\n return this.mouseGroup\n }\n\n protected dispose() {\n this.disposed = true\n this.magnifier?.disable()\n this.model.getAllLines().forEach((line) => this.removeLine(line))\n this.model.areas.forEach((area) => area.remove())\n\n const fiveElement = this.five.getElement()\n if (fiveElement) {\n fiveElement.removeEventListener('touchstart', preventDefault)\n fiveElement.removeEventListener('contextmenu', preventDefault)\n }\n }\n}\n","import type { PointJson, PolylineJson } from '../typings/data'\nimport Line from './line'\nimport Point from './point'\nimport uuid from '../../shared-utils/uuid'\nimport { Subscribe, type Mode as FiveMode } from '@realsee/five-webgpu'\nimport type { Model } from '.'\n\nexport type PolylineEventMap = {\n /** 新增线条\n * @param line 被创建的线条\n */\n lineAdded: (line: Line) => void\n\n /** 删除线条\n * @param lines 被删除的线条数组\n */\n lineRemoved: (lines: Line) => void\n}\n\nexport class Polyline {\n public id = uuid()\n public lines: Line[] = []\n public visiblePanoIndexes?: number[]\n public visibleFiveMode?: FiveMode[]\n public readonly model: Model\n public readonly type = 'polyline'\n public readonly hook = new Subscribe<PolylineEventMap>()\n\n public get points(): Point[] {\n const pointsSet = new Set<Point>()\n this.lines.forEach((line) => {\n pointsSet.add(line.points[0])\n pointsSet.add(line.points[1])\n })\n return Array.from(pointsSet)\n }\n\n public constructor(config: { model: Model }) {\n this.model = config.model\n }\n\n public addLine(line: Line) {\n if (this.includes(line)) {\n console.error(new Error('不能重复添加线段'))\n return\n }\n const lastPoint = this.getLastPoint()\n const anotherPoint = lastPoint && line.findAnotherPoint(lastPoint)\n\n if (lastPoint && !anotherPoint) {\n console.error(new Error('传入线段无法与当前折线进行连接'))\n return\n }\n\n this.lines.push(line)\n this.hook.emit('lineAdded', line)\n }\n\n public removeLine(line: Line) {\n if (this.lines.length === 0) return\n if (!this.isLastLine(line)) {\n console.error(new Error('传入线段不是当前折线的最后一段'))\n return\n }\n // remove last line\n const removedLine = this.lines.pop()\n if (!removedLine) return\n this.hook.emit('lineRemoved', line)\n }\n\n public isLastLine(line: Line) {\n const lastLine = this.getLastLine()\n if (!lastLine) return false\n return line.id === lastLine.id\n }\n\n public getLastLine() {\n return this.lines.slice(-1)[0]\n }\n\n /**\n * @description: 获取连续线段的顶点数量\n */\n public getPointLength() {\n return this.lines.length + 1 // TODO:先这么算吧\n }\n\n public clear() {\n const lines = this.lines.slice()\n this.lines.length = 0\n lines.reduceRight((_: void, line) => this.hook.emit('lineRemoved', line), undefined)\n }\n\n /** 是否产生重叠 */\n public overlapWith(item: Point | Line | Polyline) {\n if (item.type === 'point') {\n return this.includes(item)\n } else if (item.type === 'line') {\n return item.points.some((point) => this.includes(point))\n } else if (item.type === 'polyline') {\n return item.points.some((point) => this.includes(point))\n } else {\n return true\n }\n }\n\n public includes(item: Point | Line) {\n if (item.type === 'point') {\n return this.points.find(({ id }) => id === item.id) !== undefined\n } else if (item.type === 'line') {\n return this.lines.find(({ id }) => id === item.id) !== undefined\n } else {\n return false\n }\n }\n\n public isEmpty() {\n return this.lines.length === 0\n }\n\n public getLastPoint() {\n return this.points.slice(-1)[0]\n }\n\n public toJSON() {\n return this.toJson()\n }\n\n public toJson(): PolylineJson {\n return {\n id: this.id,\n lines: this.lines.map((line) => line.toJson()),\n visiblePanoIndexes: this.visiblePanoIndexes,\n visibleFiveMode: this.visibleFiveMode,\n }\n }\n\n public getPointByID(id: string) {\n return this.points.find(({ id: _id }) => _id === id)\n }\n\n public fromJson(data: PolylineJson) {\n this.clear()\n this.id = data.id\n const { getPoint } = createPointCache()\n const lines = data.lines.map((data) => {\n const [pointData, anotherPointData] = data.points\n const point = getPoint(pointData)\n const anotherPoint = getPoint(anotherPointData)\n if (!point || !anotherPoint) throw new Error('线上的点不存在')\n const line = new Line(point, anotherPoint, this.model)\n line.id = data.id\n line.text = data.text\n return line\n })\n this.lines.push(...lines)\n this.visiblePanoIndexes = data.visiblePanoIndexes\n this.visibleFiveMode = data.visibleFiveMode\n\n function createPointCache() {\n const pointMap = new Map<string, Point>()\n function getPoint(pointData: PointJson) {\n const cachePoint = pointMap.get(pointData.id)\n if (cachePoint) return cachePoint\n const point = new Point(pointData.position)\n point.id = pointData.id\n pointMap.set(pointData.id, point)\n return point\n }\n\n function getAllPoints() {\n return Array.from(pointMap.values())\n }\n return { getPoint, getAllPoints }\n }\n\n return this\n }\n\n public replace(polyline: Polyline) {\n this.id = polyline.id\n this.clear()\n this.lines.push(...polyline.lines)\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { IObject3D } from '../../shared-utils/three/IObject3D'\nimport generatePolygonGeometry from '../../shared-utils/three/generatePolygonGeometry'\n\nexport const blankGeometry = new THREE.BufferGeometry()\n\nexport class PolygonMesh extends IObject3D {\n public readonly isPolygonMesh = true\n\n public geometry: THREE.BufferGeometry = new THREE.BufferGeometry()\n public isBlank = true\n public points: THREE.Vector3[] = []\n\n public constructor(points?: THREE.Vector3[]) {\n super()\n\n // 蓝的\n const materialFront = new THREE.MeshBasicMaterial({\n color: 0x3e69ff,\n transparent: true,\n side: THREE.DoubleSide,\n depthTest: true,\n opacity: 0.5,\n })\n\n // 白的\n const materialBackground = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n transparent: true,\n side: THREE.DoubleSide,\n depthTest: false,\n depthWrite: false,\n opacity: 0.3,\n })\n\n const meshFront = new THREE.Mesh(this.geometry, materialFront)\n const meshBackground = new THREE.Mesh(this.geometry, materialBackground)\n\n // 让蓝色的在白色的上面\n meshFront.renderOrder = 1\n meshBackground.renderOrder = 0\n\n if (points) this.updatePoints(points)\n\n this.add(meshFront, meshBackground)\n }\n\n /**\n * @description: 按照新的端点来更新多边形的geometry\n */\n public updatePoints(points: THREE.Vector3[]): void {\n this.points = points\n const newGeometry = generatePolygonGeometry(points)\n if (newGeometry) {\n this.geometry.copy(newGeometry)\n this.isBlank = false\n } else {\n this.geometry.copy(blankGeometry)\n this.isBlank = true\n }\n }\n}\n","import type { ItemDomParams } from './base'\nimport { ItemDom } from './base'\nimport type { Five } from '@realsee/five-webgpu'\nimport type { BufferGeometry } from 'three/webgpu'\nimport type Area from '../../Model/area'\nimport { getGeometryInfo } from '../../../shared-utils/three/geometryUtil'\nimport { isNil } from '../../../shared-utils'\n\ninterface AreaItemParams extends ItemDomParams {\n area: Area\n}\n\nexport class AreaItem extends ItemDom {\n protected declare params: AreaItemParams\n private area: Area\n\n public constructor(params: AreaItemParams) {\n params.containerStyle = {\n ...params.containerStyle,\n ...{ zIndex: '1' },\n }\n params.contentStyle = {\n ...params.contentStyle,\n ...{\n background: '#6386FF',\n borderRadius: '2px',\n },\n }\n super(params)\n this.area = params.area\n this.containerDom.appendChild(this.contentDom)\n }\n\n /**\n * @description: dom 依赖的多边形的顶点的位置更新时,更新 dom 的位置和面积\n */\n public updateArea(five: Five, _geometry?: BufferGeometry) {\n const geometry = _geometry ?? this.area.polygon.geometry\n\n const geometryInfo = getGeometryInfo(geometry)\n\n if (!geometryInfo) {\n this.ndcPosition = null\n this.updateDomPosition(five)\n return\n }\n\n const { area, center } = geometryInfo\n\n this.ndcPosition = center.clone()\n this.updateDomPosition(five)\n\n if (this.area.model?.config?.getAreaText) {\n this.contentDom.innerText = this.area.model.config.getAreaText(area)\n } else {\n this.updateAreaText(area, { fix: 2 })\n }\n }\n\n public updateAreaText(area: number, config?: { unit?: string; fix?: number }) {\n const { unit = 'm²', fix } = config ?? {}\n this.contentDom.innerText = `${isNil(fix) ? area : area.toFixed(fix)}${unit}`\n }\n}\n","import * as THREE from 'three/webgpu'\nimport uuid from '../../shared-utils/uuid'\nimport { Subscribe, type Five, type SubscribeEventMap } from '@realsee/five-webgpu'\nimport Line from './line'\nimport { PolygonMesh } from './polygon'\nimport { Polyline } from './polyline'\nimport type { Model } from '.'\nimport Point from './point'\nimport { AreaItem } from '../utils/dom/areaDom'\nimport type { FiveLine } from '../../shared-utils/five/FiveLine'\n\nexport interface AreaHook extends SubscribeEventMap {\n selected: (area: Area, position: { left: string; top: string }) => void\n}\n\n/**\n * @description: 多边形类\n */\nexport default class Area {\n public id = uuid()\n public selected = false\n public text?: string\n public readonly type = 'area'\n public readonly lightMesh: FiveLine\n public readonly areaItem: AreaItem\n public readonly hook: Subscribe<AreaHook> = new Subscribe<AreaHook>()\n public model?: Model\n\n /**\n * @description: 多边形的端点是否闭合\n */\n public get isClosed() {\n return this.points.length >= 4 && this.points.at(0)?.equals(this.points.at(-1))\n }\n\n /** 多边形mesh */\n public polygon: PolygonMesh\n /** 多边形顶点 */\n public points: THREE.Vector3[] = []\n /** 多边形前三个点组成的平面,用来使得后面加的点也落在这个平面上 */\n public planeHelper: THREE.Plane | null\n /** 多边形边框 */\n public polyline: Polyline\n /** 多边形mesh容器 */\n private meshContainer: THREE.Object3D | null\n /** 多边形dom容器 */\n private domContainer: Element | null\n private five: Five | null\n\n public constructor(\n points: THREE.Vector3[] | undefined,\n config: {\n /** @todo: 这个model整的真的太恶心了 */\n model: Model\n meshContainer?: THREE.Object3D\n domContainer?: Element\n five?: Five\n },\n ) {\n if (points) this.points = points\n this.model = config.model\n this.polygon = new PolygonMesh(points)\n this.polyline = new Polyline({ model: config.model })\n this.areaItem = new AreaItem({\n area: this,\n clickCallback: (e, item) => {\n const left = e.clientX + 'px'\n const top = e.clientY + 'px'\n this.hook.emit('selected', this, { left, top })\n },\n })\n\n this.domContainer = config.domContainer || null\n this.meshContainer = config.meshContainer || null\n this.five = config.five || null\n\n this.areaItem.appendTo(this.domContainer)\n\n this.five?.on('cameraUpdate', this.updateDom)\n }\n\n public addPoints(point: THREE.Vector3) {\n this.points = this.points.concat(point)\n\n // 添加线\n const lineStart = this.points.at(-2)\n const lineEnd = this.points.at(-1)\n if (lineStart && lineEnd) {\n const line = new Line(new Point(lineStart), new Point(lineEnd), this.polyline.model)\n this.polyline.addLine(line)\n this.meshContainer.add(line.mesh)\n if (this.five) {\n line.distanceItem.setCanSelect(false)\n line.distanceItem.appendTo(this.domContainer)\n line.distanceItem.update(this.five)\n }\n }\n\n if (!this.meshContainer?.children.includes(this.polygon)) this.meshContainer.add(this.polygon)\n\n // 更新面积\n this.polygon.updatePoints(this.points)\n this.areaItem.updateArea(this.five)\n\n // 更新plane\n if (this.points.length === 3) {\n this.planeHelper = new THREE.Plane().setFromCoplanarPoints(this.points[0], this.points[1], this.points[2])\n } else if (this.points.length < 3) {\n this.planeHelper = null\n }\n }\n\n /**\n * @description: 移除最后一个添加的点\n */\n public popPoint() {\n this.points.pop()\n\n // 移除边\n const line = this.polyline.lines.pop()\n line?.remove()\n\n // 更新面\n this.polygon.updatePoints(this.points)\n this.areaItem.updateArea(this.five)\n\n if (this.points.length < 3) this.planeHelper = null\n }\n\n /**\n * @description: 自动补全多边形的各个边\n */\n public complete() {\n if (!this.points.at(-1).equals(this.points[0]) /** 先检查是否已经闭合 */) {\n // 闭合\n this.addPoints(this.points[0])\n }\n }\n\n public hideArea() {\n this.polygon.visible = false\n this.areaItem.hide()\n }\n\n public showArea() {\n this.polygon.visible = true\n this.areaItem.show()\n }\n\n /**\n * @description: five camera update 时,更新Dom的位置\n */\n public updateDom = () => {\n if (this.five) {\n this.polyline.lines.forEach((line) => line.distanceItem.update(this.five))\n this.areaItem.updateDomPosition(this.five)\n }\n }\n\n /**\n * @description: 获取一个点投影在当前平面上的点\n */\n public projectPoint(point: THREE.Vector3) {\n if (!point) return point\n return this.planeHelper ? this.planeHelper.projectPoint(point, new THREE.Vector3()) : point\n }\n\n public remove() {\n this.polygon.removeFromParent()\n this.areaItem.remove()\n this.polyline.lines.forEach((line) => line.remove())\n }\n\n /**\n * @todo: 没写完\n */\n public dispose(): void {\n this.remove()\n this.model.areas.splice(this.model.areas.indexOf(this), 1)\n this.planeHelper = null\n this.five.off('cameraUpdate', this.updateDom)\n this.five.needsRender = true\n }\n\n public toJSON(): any {\n return {\n id: this.id,\n points: this.points.map((point) => point.toArray()),\n text: this.text,\n }\n }\n}\n","const svg = `\n<svg class=\"fpm__delete-icon\" width=\"16px\" height=\"17px\" viewBox=\"0 0 16 17\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <defs>\n <linearGradient x1=\"22.185491%\" y1=\"100%\" x2=\"66.8316686%\" y2=\"6.67239121%\" id=\"linearGradient-1\">\n <stop stop-color=\"#FFFCFC\" stop-opacity=\"0.6\" offset=\"0%\"></stop>\n <stop stop-color=\"#FFFFFF\" offset=\"100%\"></stop>\n </linearGradient>\n </defs> \n <path fill=\"url(#linearGradient-1)\" fill-rule=\"nonzero\" transform=\"translate(2.16 2.16)\" d=\"M11.2979686,2.71818182 C11.611378,2.71818182 11.8654465,2.97561809 11.8654465,3.29318182 C11.8654465,3.58428191 11.6519584,3.82485822 11.374972,3.86293275 L11.2979686,3.86818182 L10.464,3.868 L9.7236795,10.6246222 C9.64153248,11.3737453 9.04854423,11.9512142 8.32013277,12.0165596 L8.18206028,12.0227273 L3.68338622,12.0227273 C2.89302127,12.0227273 2.22904821,11.4205655 2.141767,10.6246222 L2.141767,10.6246222 L1.4,3.868 L0.567477876,3.86818182 C0.254068499,3.86818182 0,3.61074555 0,3.29318182 C0,3.00208173 0.213488114,2.76150541 0.49047449,2.72343089 L0.567477876,2.71818182 L11.2979686,2.71818182 Z M9.322,3.868 L2.542,3.868 L3.26978106,10.4976259 C3.28762252,10.6603274 3.39528004,10.7928487 3.53932022,10.8467307 L3.61412483,10.866894 L3.68338622,10.8727273 L8.18206028,10.8727273 C8.39410941,10.8727273 8.57224853,10.7111717 8.59566544,10.4976259 L8.59566544,10.4976259 L9.322,3.868 Z M8.16824216,0 C8.48165153,0 8.73572003,0.257436269 8.73572003,0.575 C8.73572003,0.866100087 8.52223192,1.1066764 8.24524554,1.14475093 L8.16824216,1.15 L3.69720434,1.15 C3.38379497,1.15 3.12972647,0.892563731 3.12972647,0.575 C3.12972647,0.283899913 3.34321458,0.0433235966 3.62020096,0.00524907226 L3.69720434,0 L8.16824216,0 Z\"></path> \n</svg>\n`\n\nexport default svg\n","const image = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTciIGhlaWdodD0iMjUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IHgxPSIxMC43MDYlIiB5MT0iNDIuNzQ0JSIgeDI9Ijg5LjA2NCUiIHkyPSI1Ny4yMDglIiBpZD0icHJlZml4X19hIj48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9Ii4zMDgiIG9mZnNldD0iNDkuNTY5JSIvPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iMCIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iLS4yNSIgeT0iLS4yNSIgd2lkdGg9IjU3LjUiIGhlaWdodD0iMjMuNSIgcng9IjExLjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIiBmaWxsPSIjMkMyQzJDIiBzdHJva2U9InVybCgjcHJlZml4X19hKSIgc3Ryb2tlLXdpZHRoPSIuNSIgZmlsbC1ydWxlPSJldmVub2RkIiBmaWxsLW9wYWNpdHk9Ii4zMDMiLz48L3N2Zz4=`\nexport default image\n","const image = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMMAAABUCAYAAAA/HINRAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAw6ADAAQAAAABAAAAVAAAAAA6J+OeAAA2+UlEQVR4Ac2de8y16VXW9/vNodM50hqjHMIfQqESi4SDJk1opCaUiolGzBRoQ9KoQIsW5C9ixUxCWxsIhzQRpB4wSIkdIVZ7mkC0pgQSEAzhYApF/8AKakIK05lOp3N4vX7Xva611/Ps/X7fN22neLf7ude61nVda93P3nve4/d9F4f/D9YP//Tln3n66cOLLm49fOHhUo/D4QWXl4fna7/n6cvD3RcXh7uF355RVfNiV+0gzoH4WsVgWXsueLDJwRIZu1cFyd1LBXLH+x4UNgZ2aT80oTAvVObMLNTiG8xne7p4y85X84qfntakP3uteHVdeLDQoQYrmQBFNZ95ygvy/aYW/QW1FGsn7/q1w8eVP8JDGPsfXF4cPnjtcPitpy8Ov3Xx9OHX3/zai//Rvf+YAub9tK8feeflZ18+cfhq3a2X6sb8pcPTh8/xndMkyn2z9eboJyOvKO4zsXdiLWKeDK+6+6TGa19FYeEVQI8LPSOX9NLavzhtF42Svf5cbg/5WYZBnYPzpY+biaAXxCKy14qn99RTY8cYr8wVjD043uS7NTWuc4lmhUs3xGg4E+usHtzV44U3OwtZv/G5z3iB6+KH4mj1PHxIz+N/FuF9T996+Jnv/TsXH1L507rqmM9+z594z+W9j378cP9Tl4dXqelLdJMuuDm8ILlhTz91OKh2dm2eBHH8gtPeOKcgR82l8uzGqWn5CVGd/Yb6JdnwWlNeRfE2a8F7pgL2szRvFgJqP9EDnDlv9646ed+nkmBrXvQ2X8Xopy63MRrn0cQLUy3DurBH5wK1oQnmHVxvklv14KP6LbxhtGvuS/3v/Yp/4q57Dw8+8KqLhze6Zylh7md1/dN3XH6RzvxdavR1Tz19uJNmTz6pF37913Nzo+qmeeMi0awT5wnO0CVZqRLnA+wwtQhr3/inVlxujuu7OUJj/4T0GWrnu/GC4wFWN0t2mPuvsq8n+qtqwrFmbTQL2mB5dZ/jebycBa8zenQnz1mI43xI4fKmuHbL4XDbrUun9KMa9qf1RnnzP/7Wi/9WLZ6VjXGelfWj77z8Un1a8Ho9/roOeY3/6j+lNwEfBbgXvknsdPdFu6YB76V4psHhbPCRWJ9TneNVj02fGGtvfD9L1bCmXfMq75ZzFtV60J3fRl+akxfN1A8rPEebnsWzUahhZg9bpYY+Mb7EWVfhqk/eJo62OG6f817ht9Gnf2lqfH8KexsfOXhj6KWjyzuke+P3/d2L/zpafsrC9P2UGf6Td1/+6VueOvyQRn8FnwLxEeAJvQlYuS++EXQWsMEgCc+NYs8LJFhyqKxw8rlpsPhUm/a0aFzsWz3hsvYYM6b/Iuha5ODszMbaY+R49CKBO/Bo5vmMhRcD5eDVajNr/F0vXveJfrUNvAYLtww2+oGd+AOUb88KVPMF8x5x6md6mlK4tj4bPW67bX20gKN79HZt3/F933bxv8k/VYuen5L14IOXt/zB7YfXadAHNPy9vAGe1NcB+xtBs2DcRx+6JgheqbeJNZ9Aq/OVtm8Xi1Nl1/cvtk0OcWfq/nWXiK8375x19uxYgfVj/tTYp77HKK7rId+Mvg0iKv9xgD7bGb85SxwmZsmux0ldQrC6fb61eLU2xrXfSA/Nbwp9GqX1sHwf+Io/dXjL/fdf6JX2ya/M+Uk5/ei/u/y8i1sOb9dHgi/jo8ETGo2d5ZuhLjlo9ryqnDOF7pBvkkKnJEOnzOusPrXaF3El8UQ3X/ihtp+AnqXiGstU68GdrcvUgnQ+5x7n6HNBnhxyrdYnHgN03wTRVx7YRtEnSV4abFnW6NJagirOWcwtUrjQ4CSH00n1aWzk8c1zcVY/rOy506N97nPW1xeq/4rSV3zf6y7+u/t9Ehf5fHLrrf/h8n4d8K163JePBtMxh1+v8OP9yo3b3AwJm18mJ3nMS7jRK3HOpU429Zu4KBPDuvUkWq5f4ZUndDHX9cTPhqrJY9aIr9KP8bea0ch65bF3SQl5vMH2Pc0D14NjbepVjDepP/284vx5TkvW9y7erSc4c/7r6dsTMy3PukJfmfFWfYS4Qz990rdl/0jgt+jTJj59+oRXHfOZ6x+8vLzlD999eMvlU4fXcsM+/sT6aMATzMpN9l4nyU1KzTyzERyfIONF3nCF7V9A5/xbv2xJj/6aZe9ZZXPsD51etc8ncmLWMaeWNy4QtK7Sr6Kvm3DORMG5my3u9G9vE3UR76x+SX3t+p475z/HrzO1XhzH+3Oi3Z3fkLCzzxlFrUimv/HRt2/DwCyuy536KEEPfXbyw3/hTx5e94l+2lRHmtY3jn/sfZd3PPHI4af0naKv5esCvlXKnKz9oc5huZnh+rBlEJ/o9jcyeO/cBCXxOtFTM1kXEcMzFLINQEZ9x82zdla/pFs9XsEVEHebSqYX1LN5ic7q+VSUutZeu8dar2DGFs+zUmRNTCn+eS5O9NTRsDoYobDWQFESL2umbOqHaMBn9bfrC+zb9V0n/dzi3XffefibD7z64mPxvtm9buXN0g8HvRE+Q2+Ed+u7RS/Op0UZ9NwhcZ5PlGO6RpR63fwupV44PqzptZDCpr60bPar4Jx2eu5niz6fKpzoReifIme2OgBaFmm+02UspmjN0KWw+J/Dy7ZFzUGuZL644mN7CfnJ96yDn+jLZ/8mMHf4o+tZKGq5f+1X6U0Ml5nGACfzh1z7CRefwYk+nzYp/4Wnnjp87Q/9/Ys/HLQbhpzrple9Ed6vH5u/6PGP10+MNdUcDLP98LNBcwnqrhpL4cyN2uiHDnyjLWKsKHacWgFs1b5JGwy+gD5L3ank7PMFhpZlzyTKw3eRvIITfRWmJ9QTPby6R3P++Ja9t2hLchazTpfr6lVkLlZ7Ftb5Kq9rmXnThb1nLR66nDU8lwYRPP4Nl1lwNDPmDcEX1/L+9SfuOrzkh15982+IOqLHuO6lPjX6j3ojvHj/RuhBd4PlwBgT1znW8CXyQcYUzncH7pvWBmtU0qPpDqsSaOaz96L5us8BJ2b/8JV0TiDTyW1a8dyzeK4Vnrj1k6MinvbN0AgqDs7e5ejZtdjMc3a8uDw40dtLSWvEKdpRvPOcGrjxsmDqU7yeXhw/vxbXHNGxszJf4e4vmHTOAhWMX+/gDaH1C/fcc/jLN/spk2Q3Xnyx/NSjh5/ijcAXymd/h8iTrYPFkUOycqMrXWCuAo1Ln0MuYHlRix7c3NLOuNqvCgW4RaCWFYy8Y/FaXxrXI6JYuLcZF4cZPadqVT76jwGm3tIit55W5dHzRV/c2qrz2qA0DX09QmoNeEDtMzZc9cwAxmw9C5qIimtdBogesHjWm7Qu6DNrOHkCkHRvJ3VfkZYfYetJxoLypD4tfEyfuYj/4o/oa1t+BjYoV4Y39Wb4yHv0XSN9seyvEfj8EztNk4G8C0yebnmC++YhE8m59vC956DZi9scBZTQ56Z0XDVVejbPF3HpWg9Ry3oHR91o3/NhGm4syRNjkTNu9BB4oIek1T4BFnzUl4GlgxPdxo86fO37vp7vKv2SjKF2eurSRs7Zur9qLOdFYMv5XaM+AuvJ5yptjX8cgF7ibfRDR9/Zq2fb3ID1TZ3HH/ecX/tL/+fwlmFxZTgtzpL+2XsuX6Gf7/0b3gg8WL4RQ9k3hoPUIRezDmVRkPMcHxLvI83R3g9wj6G5kd71mvlELwM8KHf/CpJP/+kliXsHO/GGoDVxcwGrIT1mnVJW8MwB3nriIoZXaW/Bve/OP88b3lGoSITg2alPL/M1RGMMVLqr/NtrEBqz4fFcOWDOSXnPPYeF/xx9l4mH/hv+9T/w967/cwjGuXL964cuP//xJw+/rF+vvu9j+vSIwdLkGAysnOawHdfBnScW3yGmmaR6wOt3ffmytR9x8ATxLY9Kw9poAecsTSocy56NopLZG2ifg7HAM1IH0bfx4CxZa+OxBjgW7Vn6Te80Gz0CHdXbec95+bwSTG/i/Jd4g3vI5Z5eV+lh5bmM34kXHD3wco0g59nV4iXYq73KwPPUUGx33eEf0P2Rvpb48jd/28XvlOxku/LTJL5O0NcHb9d09/EFs6ekmZY3BlXMo+D1Iqgh4LFyI000cNSTmo6BAg4VeXTZ4WY1BplHDWB95YZ0qZKl0WU3OPXYTT3WMRDesYWnl+6Prh49AHok8csOpjW15PTa8MEo1Oq45mXz7JVDy7xArOQYTX3weCSHQ+zZpp5Yj6zEOUNy6vHybCNvHAyimm/0ZTJ50Ka3ZdKFE4/mKCD+qD5d0re379PXEm+/3tcPV74ZHn3X4dvl86V+I5Q7wxJy01gZYuZFXQRdfROiRxNsHgK2CtSK2k1yE6G4vwjB3D8C7Q65ZCDtCXOj4sOe+Y8kQD2GLvPjk74KvVrfgAIPse0LZn14lUz9jKHRC1pms4TLOJ9bVb/WV26pDUqiOPNnb41qkYGlbjk1ilNfY7W+xsLEeprXwmvygMHcA37xwqlWhS5eOL4XSjIfpNYVadOfPpB0+Zj+g643xJf+0v/16xr0ZHWfWdGnR5+pnyx/QI97/VV5inY+NtjBTuegAJ3TaejBGyocoPkWt4SsF5xIDI7E+pzqHK96bPq08+i/n0UcNFjTburJuyVJLYfJd34bfXH8RIYvj40+Od4qDFrP4tko1DCzh2WpoU+MHXHWVbjqk7eJoy2O2+e8V/ht9Olfmhr/yvNPLa1nPqw2OLzn6tOl2245PHz77YcXvulbLn4fbK6zHxn0W6c/qHfRvXyd4MHokC6oiSkwfIWp550q2MN0LmJbKGgc/Th9x+hHjQPPQ1d7k9DE2/pKrJcHy/rayeF1r70eQi36sNLb1rpMPZzU29OiY4/UgRnWeidbzl6/eWG7ueW5/e1VtjI7zmL7OkD3lwc23admqVFO9VVovXJi68vbG6Za4A658CDXflaPQGs/i/UUoq8QKCsaU2oOapkF3D41D/0/tn5B4159lPjB+Mx92Cz4X73r8sueujj88hN6I/DdIx8iLLtXE5opp1Tw5sBpMm/CHkP3TPTNr4adl/Gm1+DMvn6yUtO+ySHuTOf5b3TeTf8zM7V1+mewm+BCKVkHnZ/Td7Mqot9hJ/mResPn0r3P+WWW7OLsXj7rHDYYDRXO+5cy2Ik+xa18q4cjYfSW6PIc/TDuOfwO0+Xhy7//2y9+ZVqcfmS4dni9frjW30bF0MPYbTsweMHT8/hOLzTvYtI+cPl2Poxmv2nsfuFNPVjwKRixb4o03U+1+UYwFQ83H3bJVSO8QRvbQITX3MqtD0hyvSVeqNA6ThA9uR7zXG0bLhRi5hhYDgRkeNbaZAXRhdvtBQRrSYoCHNK3ivZRktdEtKm3RwVn9fhWD/z6sRdPU2Jp/LMHwlsOr9/Ty3LB//I9l1+kqX9d30W6dvZnCsPch5La+3C9MqcTg4dbQeeFX6lP/Xr6+GNaJ5t+m7goE8Pa84yhXL/C6+TNhH5o7Zd8d6/gXaVHUi03frGKL5yJ5f7GOzx21pwtPfZYeOnvXzKsZMNtA1v74ll0SQnQegJ5PBM9ElY0+7MGX6x1DeZ9N7P1HlAfGfRnIO64zaO96Ptfd/xLBjYfGfSXOf0D2V7j17JPVh0SfDabPHCe4Lxru1Yn6ZtUQ3WdAH/0Cnlsn2WAY31Tixd6cayvfud4mc097LouaNPfT9yoEfrM2jNbfEKLfg2wZknNfhCyFMenIWGzB/FO0kDmdL1Ik89szocBuRe1CrOTztj6wjwn8SA4rkJg71yET70QYyd6cPFbT1CJrVNY8lUq7JzXxPzc7Py6LnO+Q6ofwl3T/3i996ojHQ78vUb6MuH39VHhTn7/yM9WmkMnhq294L5BBcNqzEldepCZSxTc+tlr8PLEnvOzXuLr6iW0NZfRE7/0z7n2WNdd0OUqPfVaU5P7lHvmOeGdmcVwC5ZZznelXs+oZ8dyp937VUvzZuxO81zxmVj557k40VO30Qy2WGt2XieyNqoz1U0bsM+QWVo/CN2rsFHyUOT8gSD9GYiP3n15+MwHXrf+Xqb+yPDxi8PX6/eP7tTvga81HRJrT0jAnDWrNTwhfleWxbltPsGtx1RJbUtW/nuP+aTTy/33enIeWalPTDXrbbCIPRtpcTf+ez08CLWmPtTYZ+9DhoB2xpVOiHijhxOw4nnfqbmumu+rcuvRLGi1BNQDLmFmg9b6ivG3r3K4tiIALyyB9cKyzFViXJd4dR2MpIjmkRtsGKRnPTufGZAWzyke5Wu8OI/rP/iC7/zItcPXF8TfZ7aWPkV6FRo+x/PKIDMvrLYethRn3whz6Om7iWtg+8acXY8TPcJwFGY8goZLy+Z6FTYvGHy0Wk8inqlcKqa/MaAEij0XeRmkTyjsLk+9sJjBbz8Rc06waF3f64cHvKTRO8cjRTcqXrCVZpQ1Z4y0e4Yd12V8S9v3u+ajTYpwJm+UjnPBCUl7z68YOKXgyb0nwbgWvMA9vwDru7DIpPwVRvylFfpLy14VD9P0KdLn6Luov6t3y4U/RUoD7fHBlAOTd4OJRQNpxDnwlfqYDk0auY9wPKwPt3p4uwqTrmhrZvIAs1fF2SZnQ1fSOUHNFF12z7nKx/tE8Sp9eW30wdhZvuk1f/UtaA3VyUrnGZbBwnOAaQ8399dc5WkbLfv0nJrpdaJP8Xp6cdzf4uoTHTurzuzBduefs0C1pHSxOYeD8ZcJ6Adwl7deHj73e1938SF/ZHjy4vAymV7wKVJevJC5xyzfCCXJj8GqLxLEnb4E1qvc+iEDNC6tD0atiMxCGH1zS180ZxychxcFtEVoHHiIOhbW+llfbqtYuLcZF4cZPadqVT72GgNMvaVFbn3NCNzzRV/c2qrz2nr+6EVqPVjY4IknHqzqaMNjto1XCoPTN7AwU4pnffzpKTxHOjZRgT5Vbz3ckA0uo0ArO16nLjNvuMOD75jqxwgXT99yeBkOfjPoa4WXIuBDx1xgPGxajs4hKSho7QwNPlae4AxFqW/sGb2lY1jry8+60ucGgjnWHpl3cPzZa230A3MYffbUa8c8XrEkTwwtZ8wcYNZAQg+g1T4BFnzUlwHlcKfORvErb7B9X883erRXYd5S177RV++UOVvra17nRWDL+T0r+hFYTz5XaenrMAPQK1gFKSGn7+zVs21IZSAuFi5VMPX+rqlwfbr0Urz9ZtBf6voS3ggZOs3ij08WmG+EAnjh0tX6QXZNnAFtOHjxYHnI2g3o0t4jNlaGxNbrAkTsEoEeUy/kBLMerpb1ilsvrEquc0meG7rRS0jue1MK948oLsUBtr7w6LKnHlk33+ldB2ti+Qpz/4HbY3B7voFBz1wn+vLyjNLEj7Cxug9Q259krJwxZ0LfB0AfbgcBlmfrC3afcQO6r/R7C2rRE/On4vSr3S/B6uJfvefy81T8Hb5W4G/CY4W8iXFVw+7ZwcAQaF1Xj254OQxm8fLDYw5OibXxXtBxgPhKG0v2rKkFc16acIK3PgbindVPYcXwIusg+jYenOGRHudms2fpw7M0zUaPQMN6M/85r9yK6U3sF5eMNjjG1SS9rtJDzXMZvxMvOGXpGqY5z64WL8Fe7VUGnufcbMLKNqP7D/7wtYM+Knz+NRl/Meb+c82Q9SDP6jguKrisC9CAre3BymCjB5MuelL0BhSgdQ5k0nGHlpXafgDrMRg9ysbS6LIbLD4xoeePXnlzVewY8pnV/VWjr3tnAPRokmcH05pacnpt+GAUanVc8/fslUPLvECs5BhNffB4JIdD7NmmnliPrMQ5Q3Lq8aI288bhUFB9oy+TybOey1howolH91eQ2O2TZBfIp0rX9E64vHb44mvKXwjRfzcqYj0yOD1nM8dgFLQyxMzTZzHKq0B4hPZXEr25KlArajc5N0sw6yMo/WpgR3tkttwoKhu9geKz4SdRdOYKI48OGmszvwFAgqPewuhXqcy2+r0XvTxDDdL9az6s3Kr6tb5y6pnXEvziVXtrlEcG1jyb1JxTj7cerSeGq4v1xLXwmjxgMPeAX7xwyPHOsr4TBSJYW1jrymjTnz5LYna8Wi8N/0iOSU8dXsib4gu6CF6TpImbYyVh9SNbBuJusIJdn5eaqLkK3KZ6OSlOIBt3ssx6purTZYIk7DTqZopZyg0Xzjlz1kUoSfn0TS1+eldqbfRp7Vr0Mg1OEL17iUit9UqIJ2fGaOyd5mjrQQ2t9U64bL02uTywscaFrVdm7f7Vs3O80VXPCj2PY86hIPySdw4ntYgyP0LOZT1ErdbPxJXjpfWC0LPSY+qNBSgifwkcnxXpF/e+gH9E5AVLvq4xgcvD2iQhpqBiwkwRPVQ/QaM5XC8Fk9fxDrd36eeB8QB2qTRwWfaqxPoF95OPDwte91W80S/K4lUcnXm6TD1zpN6e6IrnMA0G7vmVR4NHYmjHm1v+5cGG1vqhcVlgZsFikQYmkvVpPvThb/QGh155z1kemQMq83sOLm60+NOz9Qi0+sw1i/UUoq8QKCsaU3IWFTMLuH1qHvc3sBxaL6xme8E1fWh4fv76eGgu4CiSNwwIeGRV7EMJcw9h5GVspm+Mi0s4LRBRAjMFPbGT4pcnmYffGJS+dO6F3uQVQI9dDp8dmucvUrjuP7EyiI5S7sW5Wc9hQxKpB8tsrtt4zUROzT1n/+LUdjxruAi10M1zBFvFHr+aCFWPeIY7zxHMel3sT+IhF9qzlpfHrjnwnv4kV/rfjJ7WbnD0df81St+33Af33gywRve5mWX9SOH512Sq31VaiwYYbHTJi5QhUMCLdjms6xwMZOatL9/Oh5H7jzze7hd86sGCh7zbc7bup3puVlPxcPNhl1w192/ydQIRNyNVbn3mJLneEi9UaB0niJ5cj3mutg0XCjFzDCwHAjI8a22ygujC7fYCgrUkRQEO6VtF+yjJayLa1NujgrN6fKsHfv3Yi6cpMXMU1r7K13vhcPc1TXk3f5iH5ReH9ggMquZyNYfjELAw80gr3+iFOw+XnUf1bA9hrVe5ceK5zukLY/PKbA0s7zlX2kfCnv7M1tIiUpsavJpfJp2Xfnq0HhCv6+jpA7/1S7K6TD1I5ZMf754HGryaC5l7EGiVRTe0vnBiVrzCNa4kOXsG3ujB6WvC2omvq0dTi/bxA0Lb+pEbh6AV755HGPWcv0Koi7Lmu5t/XPGuemd0UwtNHRcJGIzVzVbaVw9dwzZIUN3RE7YRcRb+elC/ipP6Rt9DLVvruYCnRo+Kczb3AK9lui7GdZlSKD6zdtfh7QyizwE2evwmgN6mXNaiHg415ymSE5cHNXN2WJX7xRI/07rYNrGjvIk5G3QenpM4+sRVCOy9BFMvuk1O9ODit56gElunsOSrVNg5r4n5udn5db3ORnsWNP9y6uXhrmucNk+sD6GqhXXY1BB2XLU0qPTsk2BNHSI8vOhbcN9w6mDGqSvonkg2Bqvu+VVjnegLc5G4PJNn/nh0vfpmDvh4u55Ee+tHPQfILD1UcZB7MUti7fuzOYeAUa1wDKXBqIfHHm5j4rUndQoZYHqA6dH6UZtY9KO8TKPHX+uk54Lbv/UEnRx13dNmJYZa3OzHyjpWcGg+ZvydrFZ5/sLlzfBobsrmxVciN0msPaFvGEOlGbuKMbbuzMUDlKjnw1RJbUuF11X6wukFJ56tJ+CRVQXzgmm33gYLjI+z0m/8pyd6iL5Y0XOQhRr77H3IECZ52ZiyL2/0+EOo3sTzvpO7jp84rkdTMvujH/XMRq31FeNv33P6wjZ6YVnupSS+8eq6CoxiQnjkBhsGOTlLY8xnBqTFc4pHCuDFYc/zb4reB/wE+pE0pdir4r4p5IU1rYOl2ujLqPUxnprE7JrO6cQUn+jxCWfJQI56Yup6sPnwxZ/zzZuCxKs0G33mEmGjx6AbHPtUq1j0k4e/a0WwfJBzTnoA+8Fl9seEBX7cnEZvXPWeNXPCLx0cVlJ2aAE8Q4rgtTKb08xV+0YvQstdOOZzho5F7vkVo40+eHLvSWouNniBe34B1ndhCZK2fAGP3Kp/k+2RW0Y1zbk7nCMDgzuvxu48sXJuffFuqI9pzWB9YfHCw/3DZcc/F7R77Ahl1OMNV82S0mDD2mMuA7KUNF1BZlrFpTWteO11Iz2m4mzuU2Hd0GbqXzh7QWso9NS02HLfDOiy4RYnmL2SIJBBWZF57c8aDTtc5L2mvoq2J6610Qu3f5lQa1NqaHSZuPVFm15Q3caXo83EPQtALfT6RVVaPMKnSR9eHVc1TwqZB9HuQZQkPwZL4ysD6LHRl8B6lVs/ZIDGpfXBqBURL8Lom1v6ojmr9qtCAW0RqGUFI+9YvNaXxvWIKBbubcbFYUbPqVqVj/5jgKm3tMitp1V59HzRF7e26rw2KE1DX4+QWgMeUPuMDVc9M4AxW8+CJqLiWpcBogcsnvUmrQv6zBpOngAk3dtJ3Vek5UfYepKxTCld5txwh0dkxfswv47xQb6lxPKTucKVg+lhcjk6p6qgoLXLIzllVp7gDBUsfuF7z5DZo0eklRvqGee8xDKIzDuGeszzbPQYanU9+uyrfDyPTMPFmkWemDxnzBzhmIQeQKt9Aiz4qC8DyuFO3cYPEnzt+76eb/Ror8K8pa59o6/eKXO21jOMlvMisOX8rlEfgfXkc5W2xj8OQC/xNvqho+/s1bOdHGCZ4ONSBVPvWHW//i/1PhDzt0kQZOg0i78HU50F5huBph4u1JCuGVh1BBs9eQEK7Qc9g6UGljlmbCx6+ru4ehC7VMZTDw3yxIiToyNu/aKj6oUty7OWtvUSWm+DxXMtogWJVHrl1FPOubODx9vSELW7/6yDmbQu9hW20VPCY3Bd32GmoYXK5czyjKWDSNhY3Qdk7b/zyBkthEc9B0AffgcBlmfrC3af6IV1X+n3FtSiJ9a/IX24Rf+uj8Lf5ifQH6AIyEIcsgGa8KCg5Z4mVWJAcdU9CMSsvX7vBU9YDlA22xniBTX9lmzNgx6OLt6Vmze4uQkbPTx0Wunb+gUvgkjWF5Yz4hW/YNnxtXcFwfus1NEPz+bsalAyX/Rlu9RKqLce33osQtVKFK/Mnn3ipg6P9t71YR64DGC9LvGbHtFTS5zDtx4D9Pj5sjZCewMraT08rfQLqfUKiHlYQ65HvNDy9QK/jqRf2PsA3036Nb87eDOEPNjd2I7Iy6yGHrAb9WCLehwcIks621cPw8QK0Dat6t3f4nVpDDKPeKGv3JAuVbIwuuwGpx67qcc6BsI7tvD04vnRayGzdOpTmDux1tSS02ujB6NQq+Oal82zVw4t89ZInWM09ZOHR3I4xJ5t+NmbS6145QzJKcfLs428cTCI6rvRl8nkQZvelo1549EcBYl9D5JkF8ibga8V9P9fM/zj7738kP6U22c/pn/UIQ1WtAbc3BAVbFyEHDJ8D9TJ0nsiidDRsDVKOkZTxt6KPOvEmQU6qySdtHYhx7oKG27qA+ywuD3rfs7Ssm3mC34jfRrtfDdecDzAMrVkh1GJleORTK+TmgCsWZMX+cTcYD/nkm6fS7wKn3rik+csxHE+pNGlHKxpFHazwMna6MukJJ7Ns4g8/e95rv+6yf/15tdefA4fDyi+n3eI42LmHenmFDQEQ/WCp8cGW1BTOoA79YrdxpcSFSeQjTtZTj3TkLgCL1x2htoPVv3jwY3JzbNHJOXjJ5BC+UQX26lPa9eilzS471OE5Ukt/eOVHqZMvgCnA7MeolbrnRjq/yKvTPpotRNaQ1HJ9Mqsk29a9EtiUc8vLGcFgxp9ZMk3XiXK/JnFeoharZ+JK8dL6wVljvSbemMBingb/97b5eH9uPktoJ8zvA+iv5AuMlweTpOgYKWgYsJMkSFMU7FzxXC9Ji5gcjoWDj/5PDAezJXZ4MTb/Eqsh6xlfe3k8OKN0UYPoZZ7KEbP8qbL1MNJvT2LnDx1YEysd3KcA0744a1Dlr+brxno6dmGxmWBm14mDUwkeN1n6N1zrzc49Mp7zvL25ubL1yEXHuU3Z2p9ee9nKaujvqyK7i0at6g5KGSWtHd/4e7fxmvOfADQ/j60eTM8JPPL2/T31luEo4TeMCBwF+2sin0ope4hjNx6k0QrrNLIVgpXEVatJ3ayKFPvw1ffVS09PQSYi55imbZ31V0aHp5/x3X/idU87l/WOci5Wc9h7stFq9vLt6wXXoXoqbnn7F+ceLgULGDp5jlokPkZoKluoqL2xqYeYa3WKyd27+gLM1hersOrfPrTLOc88b8ZvUTRx3c/n880+m8OiF4P/hVQfb1wee3pw0PM4TfDN7zs4n8q/vlb+RaTDNIAAolzn+44RJXWTTHxeJmDmTcMc4j4dl7+8T1njE3zay7naIcej/2C5ydx8Pa5PWrWpiVHL9PG9w1mLiK85lZufUCS6y3xQoXWcYLoyfXo+zI9w4VCzBwDy4GADM/a9Im+eNC6vRLyjTTF8OirmOX+SvIaiTb1xTpebbXXq9x6CfH04yhb0TQlxqcwfPmr6ZX//Bu/za//9WYoj7flK+sIjNOIwFOtIRyWeWm9zQEnbr/S24e4hoove+sRhz+Ngu/15OjDzWwNLO95rrSPxNbhq5gwczLb1OCVeePReemnR+sB8bqOnj7wW78kq83Ug1Q++fHueaDBq7mQuQeBVll0Q+sLJ2bFK1zjSpKzZ+CNHpy+Jqyd+Lp6NLVoHz8gtK0fuXEIWvHueYRRz/kJ+dlC/XzhbUq9/JGBSB8qflLbY7frUyULXR4XTVX35dhslAk9dA27KdUg6AnbaJLw14P6VZzUN/oeatlazwU8NfpUnLO5B3gt03UxrsuUQvEN1u46vJ1B9DnARo/fBNDblMta1MOh5jxFcuLyoGbODqtyv1jiZ1oX2yZ2lDcxZ4POw3MSR5+4CoG9l2DqRbfJiR5c/NYTVGLrFJZ8lQo75zUxPzc7v67X2fi7khQ+dseTft0zzfEjw6v+ysXDMnkHnyq5cx3WxqZKXFjuUBo0rAAsOLIejLh8vMGtPDh7n4G6ku6p2oyRuo94V+rRQKyFfs7WcXl0vfp6vjJgcx2vwlpfkOerA0BpvYOW4eCk4JWWpxPKMRi4sSVdZhiMerTs4TYmXntSp5ABpgeYHq0ftYlFP8rLNHr8tU56Lrj9W0/QyVHXPW1WYqjFzX6srGMFh+Zjxr/OxptB4TvybzOg748MJPop3Jv0BcXT+kccygFUy25rT+gbJqibUa5GCq9cfgGVqOfDVEltS4vXGZfNC1AEOPFsPQGPrCpMLSVumG9aceNjWWEb/+mJ3iZmL0n1IQnVeuXZ+5AhTDKxFqV9eaOnDsEDrDhPvlDX+qziEFtfpu1FMOqZDVrrK8YfjNqJvrAUrReWRc4yrku8Frp88TQhPHKDDYOcnKUx5jMD0uI57WEL1/Zc/UMlmuFpvfjfZE5dNm+Gb3rZxW8IeKffDBkkHcgLq63zGM4nJNi8qcZafPTL3XUpdXY9TvSYhKMw4xE0XFo216sw54suO7YYmMqlYvobA0qg2HORl4G30gi1xuWpT6Fk7SdizgmGzg8ue/3woJw0eucqtDeDFbExqxp2OfOf6IvbePLMVftGL05my/1JPmfoWMWeXzHc8IMn954ks2iHFxhfe2u3vgsL51/tEf2db3rNxW8Mi+1HBgr6IvoNGPHPg3LANlaSht0ADA7CWq6NuPXCmpsAPTELEz2cF5aaD6ayc3ipKzyaklSJuh5F6/niB882xSNnbbDoAatn61Vjps6LEn369rwUtIITtL7A3Cc0fsCPIHry6uteMVVCzoMVj5UtHGn8ysbzGIvQ4jN61acncebHa7MEgBnnIq25g7TRi+P2XEaf6A2Doy8/68svXpWu3uKBh4eHlzDeCPTRz9beUGhvm48MoN/w1Re/rO3f8m2n/KEfTH0oCKx2X6mvcPTg4FmJrRc4SqEcfaXN8CGiRxM9yfSYcbVfvhTgFoFaVjDyjsVrfWlcj4hi4d5mXBxm9JyqVfnoPwaYekuL3HpalUfPF31xa6vOa4PSNPT1CKk14AG1z9hw1TMDGLP1LGgiKq51GSB6wOJZb9K6oM+s4eQJQNK9ndR9RVp+hK0nGcuU0mXOcPlu6V369QvhP/XGb/XrfCh3XzOkcvsth+/QT6MfvmN9OFmHL0c2N1SQJt4FJo9PnuAMBd439ozeOpsvB+tXuHSlz02h7lh7ZJmNYVw/px+Yw+izp1475vESxWvOBpAzZg4waxCgB9BqnwALPurLgHK4U2ej+JU32L6v5xs92qswb6lr3+ird8qcrfU1r/MisOX8nhX9CKwnn6u09HWYAegVrIKUkNN39urZNqQyEBcLlxTcfRcOh4f1w7Zvd7S7nHxkoK6PDr+nv1npe/jO0m16YJiFsW+EAgbpwUTqwYrsmjgbPXkBCvtJ8CHjPfW72J7R0586nmtbvcq4ZysPeBMjTm59+WQobOZKnidko5cBec6Gzt4Rxag4wNYXHl321CPLTD4rvUrvOp5NLF9h7j/wJTpye75z+uk/PRR7Rg8Aac3SWN0HJO1PMlbO6HmEY9UHqLOZ7oKjvuDZ+kLdZ9yA7luzQeMzHX5soGZveOBv6fV9Zp19M8B7zssPPyjhr/KVt0k1mHsSE+SBoOoehDwrnOjJEw9ODlClkwM3FX2tWDOHdbp4V+4bNrj4g80b6by8rFPc+l0T68Mt8vTLubPT2u0rCO5Zp354Ngcts1aNLfNFX7aLoYR669HWYxGqVqJ4wWFln7ipw6O9xe+4/GwjsfW6xG96REMtcQ7YegzQeyguKya3N/nUQ9BKv5Bar4CYX9G+505Tf/VLnnf4AUdnLle+Ge6/uHhK/6LJ/TJ6+M47pMS1JvJWQw/YQ/Vg1Wx/cDyih4LegAK0zoFMOu7QslIzGUFxra88PapkaXTZDU69AM8vUXTNFa9jC08v3V8l9PaIEXokybODaU0tOb02fDAKtTqu+dk8e+XQMi8QKzlGUx88HsnhEHu2qSfWIytxzpCcerw828gbB4Oo5ht9mUwetOltmXThxKM5Cojv0adH4jysF/v9999/Uf8kD+rtuvLNAO2VX33xQf2jh6/h0yX/kILGwrlprAwx8x5kUdYTVCA86wn0iN5UFagVtZvkJsIhRhPM+gi0O+SCP0t7QseVbPTFM59L6aMzVxh5dOFu5o/WQ2z74ml9hJVM/Yyh0QvaupQeoOaj5FbVr/WVU8+8luBnw+PeGuGRgTXPJqrZYIt7lIjGLNajq4VX9xmYe0gfi3CqVeSeJRzfCyWZD1LrirTpr958wayvgfkLVV/zhm+9+GAbnwmu+2aA/+qvvfhJbW99jj5d4rf8enE3OGgDKwA+WYAiNleBeSGzFyeQyZ0sxxycLBJXZkJMo25mRvePBzd03lRYlqAnzozlE11sp74kW708ghNEv8xr/iLEa3Jm7Hn6YofN+VtPqTxP9BlcO6E18JUgKZkDtK2HrNU5MYAEeFTYejDq4Ze8c/ipRZT5M4v1ELVaPxNXjpfWC8o56MGn+P5Wql6/b3qtX8dH0Znohm8GNHd8zeG1+nt5HsKcX/N2x5qY5h64puiDQuPG5DSKi+KgcfSD03HaVG0eWKV1wwmqR7ytr4StrZWQ48OC170UF3zEFm2jBzJPl6mnx/Qtqcnpkbpr0RdxchKHlwGsryHZ6Mkj56/Q4KaXScf54Ftf+NTjgelGb3CLUfec5eENUy1wh1x4lN/0bD0CrT6z+K2nEH2FQFnRmFJzUMss+vedD3fzdcIth4f+/PMPr43uevtNvRn4+uGO+w5/QwP8Il8/3MobQsuHYic5c2gfzEUINegKLaqzHvWqzZs29T78ODQ2uRFzdzt4CmqD2jfcPkZWL+eD6/5Tb8Oht9kyODfrOWxI1pMFIN+ytlnmip5aZoPguM5f29IHC1jceY7WO5AXO8tN1t6YUnplDmiszJfYs0efOrkeeLlePuQ8ehXeuYL2vxm9+Jkvvq1Xje8c3ac3gn488It/Qq/b632dMGe4qTcDgvtffPHYLXcdXq7wN/k8jI8QDOJDQxhrDgY88xwCsfUxyA4f0chJWRv+1MM9w7eoLvRlju6P3y63B0202i45+ombdcUF38mt3PoYk1xviRcqtI4TRE+uxzxX24YLhZg5BpYDARmetTZZQXThdnsBwVqSogCH9K2ifZTkNRFt6u1RwVk9vtUDv34I543wGXdDOPym/tHzl3/n/RePldUNt7K8Ia8Jb/u5y+c99ejhvfrrNf7iYx8/HB7XY67ctGCd04nBu7CCzgtv/lX59fTxx3TcrJaMZqGc9IM8eSEC7/CTN9OOY6toNM/N6kfLrQbDWnjVLQ3kudG69gmcP6PGG2P+uvb5wkszn2U3gPW6sFf7pUckwJoyuJG+aK3ZtWo8PHa+yeNvoV4efvGJuw8vf/MrLz486zeKb/ojQ4xe+ZUXH77j3sNX6VuuD/HFCV9HZPkmaurcvOB51vom+a51dQXcRD04NI/5glyEY31Tixf60ro/SWoYVJzZ3AO8lum6GNdlSqHkicxs8dnrc4CNHr8JpM/AqIdDD+cxJycuPjVzdliVff+nn2ldbJvYUd7EnA06D/qwMlvHVYit9xJMvcX4hTi9hAV2vRJbpyA+udPCznndpU/feSPoN68fet7zDl/1TN8IzFlHInxm68HLy1s++t7DD0v1zU/pL2F6VB+M+K/IHDSOe8z5uEE+bA4akXZ4vrFVSyl+8bmuHh+EXEZPQ/G1AciYf8e9rn5Jt3q8giuo9gurJOdoWgsWkvMhOqvnX5lhdq291x5r/fQCZM2znsNEwT/PBRTfsnCp6+HVwRZrjUjTq1Tn9UM0bDd6fqB2n36O4D+Hc3F464vuO7z2Zr9GSO/sdSuTPvP9xx+6/Ea9CX5EB7yXNwT/yPT+iZm5Y9/JY69g7F3K6QWc6I9SRyf60rLZr4LpMy2CxyfPTPT5VCG81orAP53a/AjAi0TZ+tDOcEwe54x24t2mis3BV0leqLTdzImv3jSzbg6XWtYrtm7MsakXTt+e5Rnoz3ldhc2zwZnn6VmF863+e/mBmn7fSG+K1zzwt2/87dP0PLdzrk96/dg7L1+gf0f3QU31JU8+qY8SH9MLgP9qac2DODdKQY+6qz587oCwqZmx9UPnvC8Ea8WKHh2nVgBbtW/SBoMvoPvXnUrOPl9gaFn2TKI8fBfJKzjRV2F6Qj3Rw6t7NOePb9l7i7YkZzHrdLmuXkXmYrVnYZ2v8rqWmTdd2HvW4qHLWcNzaRDB49+wQP7s8t36Jg5vBqW/eu3y8IoHvvnit8v6E97qiJ+wvoUPPnh5y6P3HL5T0323Hvd8TF9Y88jiUBzOh+qgDjum8OGr3jdCdeuHDl/SoynJwBJrd09yCxTU2ufAE9vQlXROUDOVVW+ec5WXV852lb68YmB9MHZWHcCzVd+C1lCdrHSeYRnU7OU37eHmRWmu8qJFuuABTg3waG9xU1MUZ8600Yvj/tXNvOhiNM58p94EfK2qb5t+RLrv+bP3HH7gE/20qFr2xjk+petf/MzlZ1178vAWGX8dB3v8Cf2pa/21lfubkTvY51bQ8ZyocKCuE9Syb92sYHPf99088SKe1U9/zKoxXG5YlxUk7j4bQtWLxDbLrcEzRornmnhTht+cbeoSb/S7AWxT2OTFk50ytf19w5/auiwO6Tyg61DQs1OvFS27a7M4OVXn51t8s6beOD+tN8Prrvrt05I/4405npX1E++9/IonLw//UDfir6rBNb4F+7g+heLTqNzY/fn3N508a1OrO+v6uMv7Gzvk55+QSVCjTQ/yNK/aSM2dOfGJPgaa0bOapMvMwWpNvaXRq259zho99WBwhk+FvXX/cNgjmBjwDjd1h00OJY9RQdeiybzVZ+8XmucZXP74AN8ure9YPq2vz97Fn8T8R6+++C/D6lMWcoZndf3zd13+OR3g9fqi/6/pC8nn8rUEnz7pByIHvgvF4mZwA31DjRwvfWOP0MmTdTN6+9dp957keGz6A2jVtplvepmDXo+8yS2sy9QHN5ekGsIBO7eCz3Lr0ZUovL1HcO+788/zhtd6jEUInp369DJf3MaG7ir/9hqEYHxXiK8F+F04/mSa7uljqv17HfSN+gJ582eW3ftTeGGcT8t68Gcv73vkicM36necXqmb/GJ9h+OC77LwkcJvDMW8OfjOB/eTm3P2xUWxVocJ6uaiBRr32orc8NafI6m40Q/vs/qYjT16Q3v96JnSkK4XlQD32h3A/NJvZomR+MaVBzrnDeY6l2hW2PceDgs/nofEKxp6AemVcedsifNcxi87L36+IOYP3vgXQWUi7qVeB7+g18Pb7rzv8JPfdf/FH6Xvs7nXMZ/NFqfeP/6zl5+rN8HX6NdqX6on4yu1fxZ3lJvKG4SPHuzk3LS8QXDKTTQOgVXPglMueVYmbuJWn55+sukDZ+gTMouX/Og7V+YB29eM9YWgeqxwwz+nbf7smaG0G6689TOv8/MBmJBlXuHz/NGz54W7FEeNZW66Kg7Tz+ZrpthHTx88eehzfe+8CcKr/fdE+zk9/tPh1sNDD3zTxe+2/tMUMMcf+/K3Zq8dvlgvuhfqyfhC3aXP10eQ5+lzxLt1c+7SkHcJv/3sEzWnF1n/r8sqON9hq1L1Jmxk9vGTRF0Bvc+ts7i4JesX34YXr51vYPqY7wFG1zY9YieaKm36xS817VizJm96rSoEPa6Y0+MNUcKNp0D9l//jem4fFf6ontdHFH9Yz+3v6I3xW3qjfkDfGv2173719f+sQc/zLAb/D0EI6cG68deIAAAAAElFTkSuQmCC`\nexport default image\n","import type Line from '../../Model/line'\nimport type { Five } from '@realsee/five-webgpu'\nimport type Point from '../../Model/point'\nimport deleteSvg from './_Assets/delete.svg'\nimport deleteBg from './_Assets/delete_bg.png'\nimport deleteHoverBg from './_Assets/delete_hover_bg.png'\n\nexport default class DeleteDom {\n public visible = false\n\n private five: Five\n private lines: Line[] = []\n private points: Point[] = []\n private onClick: (e: MouseEvent, target: any) => void\n private cancel: (target: any) => void\n private content = document.createElement('div')\n private container = document.createElement('div')\n private masking = document.createElement('div')\n private target: any\n\n public constructor(\n five: Five,\n opts?: { onClick?: (e: MouseEvent, target: any) => void; cancel?: (target: any) => void; i18n?: (key: string) => string },\n ) {\n this.five = five\n this.onClick = opts?.onClick || (() => undefined)\n this.cancel = opts?.cancel || (() => undefined)\n // container\n this.container.classList.add('fpm__delete')\n this.container.style.opacity = '0'\n this.container.style.position = 'absolute'\n this.container.style.left = '0'\n this.container.style.top = '10px'\n this.container.style.transform = `translate3d(0, 0, 10px)`\n this.container.style.pointerEvents = `none`\n this.container.style.transition = 'opacity 200ms ease'\n this.container.style.zIndex = '99'\n\n // content\n this.content.classList.add('fpm__delete-content')\n this.content.style.width = '62px'\n this.content.style.height = '26px'\n this.content.style.display = 'flex'\n this.content.style.alignItems = 'center'\n this.content.style.justifyContent = 'center'\n this.content.style.transform = 'translate(-50%, -50%)'\n this.content.style.color = '#fff'\n this.content.style.fontSize = '12px'\n this.content.style.lineHeight = '17px'\n this.content.style.borderRadius = '11px'\n this.content.style.backgroundSize = '100% 100%'\n this.content.style.cursor = 'pointer'\n this.content.style.userSelect = 'none'\n this.content.style.backgroundImage = `url(${deleteBg})`\n this.content.innerHTML = `\n ${deleteSvg}\n <span>${opts.i18n?.('删除') ?? '删除'}</span>\n `\n this.container.append(this.content)\n\n const deleteSvgDom = this.content.querySelector<SVGElement>('.fpm__delete-icon')\n if (deleteSvgDom) {\n deleteSvgDom.style.width = '16px'\n deleteSvgDom.style.height = '17px'\n deleteSvgDom.style.marginRight = '1px'\n }\n\n this.content.addEventListener('click', this.clickHandler)\n this.content.addEventListener('mouseenter', this.hover)\n this.content.addEventListener('mouseleave', this.unHover)\n\n // masking\n this.masking.setAttribute('style', 'position: absolute;top: 0;left: 0;bottom: 0;right: 0;pointer-events: none;')\n this.masking.addEventListener('click', this.cancelHandler)\n this.masking.addEventListener('touchstart', this.cancelHandler)\n }\n\n public dispose() {\n this.content.removeEventListener('click', this.clickHandler)\n this.content.removeEventListener('mouseenter', this.hover)\n this.content.removeEventListener('mouseleave', this.unHover)\n this.container.remove()\n\n this.masking.removeEventListener('click', this.cancelHandler)\n this.masking.removeEventListener('touchstart', this.cancelHandler)\n this.masking.remove()\n }\n\n public appendTo(element: Element) {\n element.append(this.container)\n element.append(this.masking)\n return this\n }\n\n public setLines(lines: Line[]): this {\n this.lines = lines\n this.points = Array.from(new Set(this.lines.map((line) => [line.points[0], line.points[1]]).flat(1)))\n return this\n }\n\n public setTarget(target: any): this {\n this.target = target\n return this\n }\n\n public updatePosition(left?: string, top?: string) {\n if (left && top) {\n this.container.style.left = left\n this.container.style.top = top\n this.container.style.transform = ''\n return this.show()\n }\n if (this.lines.length === 0) return this\n const points = this.points.map((point) => point.position).map((p) => p.clone().applyMatrix4(this.lines[0].mesh.matrixWorld))\n const ndcPoints = points.map((point) => point.clone().project(this.five.camera))\n if (ndcPoints.some((ndcPoint) => Math.abs(ndcPoint.z) > 1)) return this.hide()\n const xArray = ndcPoints.map((point) => point.x)\n const yArray = ndcPoints.map((point) => point.y)\n const centerX = (Math.min(...xArray) + Math.max(...xArray)) / 2\n const maxY = Math.max(...yArray)\n\n const wrapper = this.container.parentElement\n if (!wrapper) return this\n const centerScreenX = ((centerX + 1) / 2) * wrapper.clientWidth\n const maxScreenY = (-(maxY - 1) / 2) * wrapper.clientHeight\n\n let x = centerScreenX\n let y = maxScreenY - 34\n\n // 只有一条线时且斜率大时删除按钮位于右侧\n if (this.lines.length === 1 && points.length === 2) {\n const k = (yArray[1] - yArray[0]) / (xArray[1] - xArray[0])\n const centerY = (yArray[1] + yArray[0]) / 2\n const centerScreenY = (-(centerY - 1) / 2) * wrapper.clientHeight\n if (Math.abs(k) > 0.4) {\n x = centerScreenX + 57\n y = centerScreenY\n }\n }\n\n this.container.style.top = '0'\n this.container.style.left = '0'\n this.container.style.transform = `translate3d(${x}px, ${y}px, 0)`\n\n return this.show()\n }\n\n public hide() {\n this.visible = false\n this.masking.style.pointerEvents = 'none'\n this.container.style.opacity = '0'\n this.container.style.pointerEvents = 'none'\n this.unHover()\n return this\n }\n\n public show() {\n this.visible = true\n this.masking.style.pointerEvents = 'auto'\n this.container.style.opacity = '1'\n this.container.style.pointerEvents = 'auto'\n return this\n }\n\n private clickHandler = (event: MouseEvent) => {\n this.onClick(event, this.target)\n }\n\n private cancelHandler = () => {\n this.cancel(this.target)\n }\n\n private hover = () => {\n this.content.style.backgroundImage = `url(${deleteHoverBg})`\n }\n\n private unHover = () => {\n this.content.style.backgroundImage = `url(${deleteBg})`\n }\n}\n","import { Vector2 } from 'three/webgpu'\n\n/**\n * 获取一点对于线段上最近的一点,\n * 如果可以是过直线垂线的垂足,不行的话取线段的两端\n * @param point\n * @param linePoints\n * @return\n */\nexport function closestPointOnLine(point: Vector2, linePoints: Vector2[]) {\n const tA = point.x - linePoints[0].x\n const tB = point.y - linePoints[0].y\n const tC = linePoints[1].x - linePoints[0].x\n const tD = linePoints[1].y - linePoints[0].y\n\n // 设线段为 AB 线段,线段外一点为 P\n // tDot = AP 向量与 AB 向量乘积,tLenSq 为 |AB|平方。\n // tParam 是 AP 向量在 AB 向量投影向量 AC 与 AB 向量的比。\n const tDot = tA * tC + tB * tD\n const tLenSq = tC * tC + tD * tD\n const tParam = tDot / tLenSq\n\n let tXx: number, tYy: number\n\n if (tParam < 0 || samePointAt(linePoints[0], linePoints[1])) {\n tXx = linePoints[0].x\n tYy = linePoints[0].y\n } else if (tParam > 1) {\n tXx = linePoints[1].x\n tYy = linePoints[1].y\n } else {\n tXx = linePoints[0].x + tParam * tC\n tYy = linePoints[0].y + tParam * tD\n }\n\n return new Vector2(tXx, tYy)\n}\n\n/**\n * 检查两个点是否位置相同\n * point: { x: number, y: number }\n * @param point1\n * @param point2\n * @return\n */\nexport function samePointAt(point1: Vector2, point2: Vector2) {\n return point1.x === point2.x && point1.y === point2.y\n}\n","import Line from '../Model/line'\nimport Point from '../Model/point'\nimport throttle from '../../shared-utils/throttle'\nimport BaseController from './BaseController'\nimport type { ControllerParams } from './BaseController'\nimport { Polyline } from '../Model/polyline'\nimport Area from '../Model/area'\nimport { isIntersecting } from '../utils/isIntersecting'\nimport { PointSelector, type PointIntersection } from '../../shared-utils/three/PointSelector'\nimport DeleteDom from '../Modules/DeleteDom'\nimport type { EventCallback } from '@realsee/five-webgpu'\nimport { Vector2 } from 'three/webgpu'\nimport isNDCPointInScreen from '../utils/isNDCPointInScreen'\nimport { closestPointOnLine } from '../utils/math'\nimport { getFiveModel } from '../../shared-utils/five/getFiveModel'\nimport * as THREE from 'three/webgpu'\nimport { notNil } from '../../shared-utils'\n\nconst disableFiveEvent = (): false => false\n\nexport default class EditController extends BaseController {\n public type = 'edit'\n public polyline: Polyline\n public area: Area\n private hasAppendDashed = false\n // private deleteDom: DeleteDom\n private fiveElement?: HTMLCanvasElement\n /** 上一个端点位置 */\n private lastPoint: Point | null = null\n private pointSelector: PointSelector\n private deleteDom: DeleteDom\n\n /** 根据 intersection 更新放大镜和吸附点 */\n private onIntersectionUpdate = throttle((position?: PointIntersection) => {\n if (!position) return\n if (this.currentMeasureType === 'area') {\n if (typeof position.isAdsorbed === 'boolean') {\n if (position.isAdsorbed) this.hook.emit('readyComplete')\n else this.hook.emit('notReadyComplete')\n }\n }\n this.updateDashed()\n }, 20)\n\n public constructor(params: ControllerParams) {\n super(params)\n\n // this.model = new Model(this.config)\n\n this.fiveElement = this.five.getElement()\n\n this.deleteDom = new DeleteDom(this.five, {\n i18n: this.config.i18n,\n onClick: (_, target) => {\n const isArea = target.type === 'area'\n const isLine = Array.isArray(target) && target[0]?.type === 'line'\n if (isArea) this.deleteArea(target)\n if (isLine) this.deleteLine(target)\n },\n cancel: (target) => {\n this.deleteDom.hide()\n const isArea = target.type === 'area'\n const isLine = Array.isArray(target) && target[0]?.type === 'line'\n if (isArea) this.unHighlightArea(target)\n if (isLine) this.unHighlightLines(target)\n },\n }).appendTo(this.container)\n\n this.pointSelector = new PointSelector(this.five, {\n ...this.pointSelectorConfig,\n mode: this.editParams.pointSelectorMode,\n helper: { magnifierParams: this.magnifierParams, container: this.container, ...this.pointSelectorConfig.helper },\n })\n\n this.pointSelector.enable()\n\n this.polyline = new Polyline({ model: this.model })\n this.area = new Area(undefined, {\n five: this.five,\n model: this.model,\n meshContainer: this.group,\n domContainer: this.container,\n })\n\n this.model.addPolyline(this.polyline)\n this.model.addArea(this.area)\n // ==================== 新加的逻辑: 不删除旧的东西 (依托答辩) ====================\n this.model.getAllLines().forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n line.distanceItem.setCanSelect(true)\n line.hook.on('selected', this.chooseLine)\n this.group.add(line.mesh)\n })\n this.model.getAllAreas().forEach((area) => {\n area.areaItem.appendTo(this.container)\n area.areaItem.updateDomPosition(this.five)\n area.areaItem.setCanSelect(true)\n area.hook.on('selected', this.chooseArea)\n this.group.add(area.polygon)\n area.polyline.lines.forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n this.group.add(line.mesh)\n })\n })\n\n // ==================== 事件监听 ====================\n // five\n this.five.on('cameraUpdate', this.onCameraUpdate)\n this.five.on('wantsTapGesture', this.wantsTapGesture)\n this.five.on('wantsMoveToPano', this.wantsMoveToPano)\n this.five.on('wantsChangeMode', disableFiveEvent)\n // pointSelector\n this.pointSelector.on('intersectionUpdate', this.onIntersectionUpdate)\n this.pointSelector.on('intersectionUpdate', this.checkMouseLeave)\n this.pointSelector.on('select', this.onSelect)\n this.pointSelector.on('wantsSelect', this.onWantsSelect)\n // polyline events\n this.polyline.hook.on('lineAdded', this.onLineChanged)\n this.polyline.hook.on('lineRemoved', this.onLineChanged)\n this.five.helperVisible = false\n // ==================== 其他 ====================\n this.hook.emit('anchorChange', null)\n this.hook.emit('editedDashedLineChange', null)\n this.five.refresh()\n }\n\n public dispose() {\n super.dispose()\n // 没有闭合的面要移出去,防止在其他Controller的构造函数中又加进去\n this.model.areas.forEach((area) => {\n if (area.points.length < 2 || area.polygon.isBlank) this.model.removeArea(area)\n })\n // five effect\n this.five.helperVisible = true\n this.pointSelector.disable()\n this.dashed.remove()\n this.perpendicularDashed.remove()\n // ==================== 解除事件监听 ====================\n // five\n this.five.off('cameraUpdate', this.onCameraUpdate)\n this.five.off('wantsTapGesture', this.wantsTapGesture)\n this.five.off('wantsMoveToPano', this.wantsMoveToPano)\n this.five.off('wantsChangeMode', disableFiveEvent)\n // pointSelector\n this.pointSelector.off('intersectionUpdate', this.onIntersectionUpdate)\n this.pointSelector.off('intersectionUpdate', this.checkMouseLeave)\n this.pointSelector.off('select', this.onSelect)\n this.pointSelector.off('wantsSelect', this.onWantsSelect)\n // polyline events\n this.polyline.hook.off('lineAdded', this.onLineChanged)\n this.polyline.hook.off('lineRemoved', this.onLineChanged)\n\n this.pointSelector.dispose()\n this.deleteDom.dispose()\n this.dashed.distanceItem.remove()\n this.five.needsRender = true\n }\n\n public getEditingLines() {\n return this.polyline.lines\n }\n\n /** 撤销编辑 */\n public revoke = () => {\n if (this.currentMeasureType === 'area') {\n this.revokeArea()\n } else if (this.currentMeasureType === 'line') {\n this.revokeLine()\n }\n }\n\n /**\n * @description: 测面积的撤销功能\n */\n public revokeArea = () => {\n if (this.area.points.length === 0) return\n this.area.popPoint()\n this.hook.emit('pointsChange', this.area.points)\n if (this.area.points.length === 0) {\n this.lastPoint = null\n this.hasAppendDashed = false\n this.dashed.remove()\n this.five.needsRender = true\n this.hook.emit('revoke', { isEmpty: true })\n return\n } else {\n this.lastPoint = new Point(this.area.points[this.area.points.length - 1])\n this.updateDashed()\n }\n this.five.needsRender = true\n }\n\n /**\n * @description: 测距的撤销功能\n */\n public revokeLine = (_polyline?: Polyline) => {\n const polyline = _polyline || this.polyline\n // ============ revoke points ============\n // 如果当前没有虚线,只有起始点,需要删除起始点,重置起始状态。并删除虚线实例\n if (polyline.lines.length === 0 && this.lastPoint) {\n this.lastPoint = null\n this.hasAppendDashed = false\n this.pointSelector.setAdherePoints(null)\n this.dashed.remove()\n this.hook.emit('anchorChange', null)\n this.hook.emit('editedDashedLineChange', null)\n this.five.needsRender = true\n this.hook.emit('pointsChange', [])\n return\n }\n if (polyline.lines.length === 0 && !this.lastPoint) return\n if (!this.lastPoint) return\n const revokedLine = polyline.lines[polyline.lines.length - 1]\n const lastPoint = revokedLine.findAnotherPoint(this.lastPoint)\n if (!lastPoint) return\n this.lastPoint = lastPoint\n this.hook.emit('anchorChange', lastPoint.position)\n // ============ revoke lines ============\n this.group.remove(revokedLine.mesh)\n polyline.removeLine(revokedLine)\n // ============ revoke lineDistance ============\n revokedLine.distanceItem.remove()\n // ============ revoke dashed ============\n this.updateDashed()\n\n this.five.needsRender = true\n }\n\n public selectPoint() {\n this.onSelect()\n }\n\n public complete() {\n this.hook.emit('complete')\n if (this.currentMeasureType === 'area') {\n if (this.area.points.length < 3) {\n this.deleteArea(this.area)\n } else {\n this.area.showArea()\n this.area.complete() // 闭合面积\n this.area.hook.on('selected', this.chooseArea)\n }\n this.area = new Area(undefined, { five: this.five, model: this.model, meshContainer: this.group, domContainer: this.container })\n this.model.addArea(this.area)\n } else if (this.currentMeasureType === 'line') {\n this.polyline.lines.forEach((line) => {\n line.hook.on('selected', this.chooseLine)\n line.distanceItem.setCanSelect(true)\n })\n this.polyline = new Polyline({ model: this.model })\n this.model.addPolyline(this.polyline)\n }\n this.pointSelector.setAdherePoints(null) // 重置打点器的吸附点\n this.dashed.hide()\n this.perpendicularDashed.hide()\n this.lastPoint = undefined\n }\n\n private checkMouseLeave = (position: PointIntersection) => {\n if (!position) {\n this.dashed.hide()\n this.perpendicularDashed.hide()\n this.area.hideArea()\n }\n }\n\n /** 编辑线条发生改变时通知外部 */\n private onLineChanged = () => {\n this.hook.emit('editedPolylineChange', this.polyline)\n }\n\n private onWantsSelect = () => {\n if (this.currentMeasureType === 'area') {\n const noPolygon = this.area.polygon.isBlank || this.area.polygon.visible === false\n if (this.area.points.length >= 3 && noPolygon) return false\n }\n }\n\n private wantsMoveToPano = (): false | void => {\n if (this.lastPoint) return false\n }\n\n /**\n * 1. 如果存在上一个点,需要绘制当前点到上一个点的连线\n * 2. 把上一个点的位置更新为当前点的位置\n * 3. 清除 pointSelector\n */\n private onSelect = () => {\n if (!this.hasAppendDashed) {\n this.dashed.distanceItem.appendTo(this.container)\n this.group.add(this.dashed.mesh)\n // 测面积中,鼠标位置不在平面上时,要画一条垂线来显示\n if (this.currentMeasureType === 'area') this.group.add(this.perpendicularDashed.mesh)\n }\n this.hasAppendDashed = true\n const currentPosition = (() => {\n if (this.currentMeasureType === 'area') return this.area.projectPoint(this.pointSelector.position?.point)\n else if (this.currentMeasureType === 'line') return this.pointSelector.position?.point\n })()\n if (!currentPosition) return\n\n const nowPoint = new Point(currentPosition)\n const lastPoint = this.lastPoint\n if (lastPoint?.position && nowPoint.position.equals(lastPoint?.position)) return // 不重复打点\n this.lastPoint = nowPoint\n\n const getAdherePoints = (params: { intersection: PointIntersection; pointSelectorInstance: PointSelector }) => {\n if (!this.lastPoint) return []\n const { intersection, pointSelectorInstance } = params\n const pointHelper = pointSelectorInstance.pointSelectorHelper.pointHelper\n const normal = new THREE.Vector3(0, 0, 1).applyQuaternion(pointHelper.quaternion)\n\n if (normal.x > 0.9999 || normal.y > 0.9999 || normal.z > 0.9999 || normal.x < -0.9999 || normal.y < -0.9999 || normal.z < -0.9999) {\n const intersectPoint = intersection.point\n const offset = this.lastPoint.position.clone().sub(intersectPoint)\n pointSelectorInstance.pointSelectorHelper.updateWithIntersect(intersection, { emitEvent: false })\n const xLine = new THREE.Line3(\n pointHelper.localToWorld(new THREE.Vector3(1, 0, 0)).add(offset),\n pointHelper.localToWorld(new THREE.Vector3(-1, 0, 0)).add(offset),\n )\n const yLine = new THREE.Line3(\n pointHelper.localToWorld(new THREE.Vector3(0, 1, 0)).add(offset),\n pointHelper.localToWorld(new THREE.Vector3(0, -1, 0)).add(offset),\n )\n const pointOnXLine = xLine.closestPointToPoint(intersectPoint, false, new THREE.Vector3())\n const pointOnYLine = yLine.closestPointToPoint(intersectPoint, false, new THREE.Vector3())\n return [pointOnXLine, pointOnYLine]\n }\n return []\n }\n\n this.pointSelector.setAdherePoints(getAdherePoints)\n\n // 绘制线\n if (this.currentMeasureType === 'line') {\n if (nowPoint && lastPoint) {\n const line = new Line(lastPoint, nowPoint, this.model)\n line.distanceItem.setCanSelect(false)\n line.distanceItem.appendTo(this.container)\n this.polyline.addLine(line)\n this.group.add(line.mesh)\n line.distanceItem.update(this.five)\n }\n\n const autoEndLineLength = this.editParams?.autoEndConfig?.line\n if (typeof autoEndLineLength === 'number') {\n // TODO: 重置逻辑,不知道放哪好\n if (this.polyline.getPointLength() >= autoEndLineLength) {\n this.complete()\n } else if (this.polyline.getPointLength() === autoEndLineLength - 1) {\n this.hook.emit('readyComplete')\n }\n }\n this.hook.emit('pointsChange', this.polyline.points)\n }\n // 绘制面积\n else if (this.currentMeasureType === 'area') {\n this.area.addPoints(nowPoint.position)\n if (this.area.isClosed) {\n this.complete()\n return\n }\n if (this.area.points.length >= 3) {\n this.pointSelector.setAdherePoints((...params) => [this.area.points[0], ...(getAdherePoints(...params) ?? [])].filter(notNil))\n }\n\n const autoEndAreaLength = this.editParams?.autoEndConfig?.area\n if (typeof autoEndAreaLength === 'number') {\n // TODO: 重置逻辑,不知道放哪好\n if (this.area.points.length >= autoEndAreaLength) {\n this.complete()\n } else if (this.area.points.length === autoEndAreaLength - 1) {\n this.hook.emit('readyComplete')\n }\n }\n this.hook.emit('pointsChange', this.area.points)\n }\n this.updateDashed()\n this.five.needsRender = true\n this.hook.emit('anchorChange', nowPoint.position)\n }\n\n /** 移动全景时更新 distanceItem 在屏幕上的位置 */\n private onCameraUpdate = () => {\n this.updateDistanceUI()\n }\n\n /** 更新虚线 */\n private updateDashed = () => {\n if (!this.lastPoint) return\n const dashedStart = this.lastPoint.position\n const dashedEnd = (() => {\n if (this.currentMeasureType === 'area') return this.area.projectPoint(this.pointSelector.position?.point)\n else if (this.currentMeasureType === 'line') return this.pointSelector.position?.point\n })()\n if (!dashedEnd) {\n this.dashed.hide()\n return\n }\n this.dashed.show()\n this.dashed.setPoints(dashedStart, dashedEnd)\n this.dashed.distanceItem.update(this.five)\n this.hook.emit('editedDashedLineChange', this.dashed)\n\n if (this.currentMeasureType === 'area') {\n this.area.areaItem.setCanSelect(false)\n if (this.area.points.length >= 2) {\n // 更新垂线(与落点是否合法无关)\n const mousePosition = this.pointSelector.position?.point\n if (mousePosition) {\n const perpendicularDashedStart = mousePosition\n const perpendicularDashedEnd = dashedEnd\n this.perpendicularDashed.setPoints(perpendicularDashedStart, perpendicularDashedEnd)\n this.perpendicularDashed.show()\n } else {\n this.perpendicularDashed.hide()\n }\n\n // 判断落点是否合法\n const segments = this.area.polyline.lines.map((line) => ({ start: line.points[0].position, end: line.points[1].position }))\n const intersected0 = isIntersecting({ start: dashedStart, end: dashedEnd }, segments)\n const intersected2 = isIntersecting({ start: dashedEnd, end: this.area.points[0] }, segments)\n /** true: 线段有交点,落点不合法; false: 线段没有交点,落点合法 */\n const intersected = intersected0 || intersected2\n if (intersected) {\n // ====== 落点不合法 ======\n // document.documentElement.style.cursor = 'not-allowed'\n this.area.hideArea()\n this.hook.emit('allowAddPointStateChange', 'forbid')\n } else {\n // ====== 落点合法 ======\n // document.documentElement.style.cursor = 'default'\n this.area.showArea()\n\n // 更新面积\n const newPoints = [...this.area.points, dashedEnd]\n // 更新面积Mesh\n this.area.polygon.updatePoints(newPoints)\n // 更新面积文字\n this.area.areaItem.updateArea(this.five)\n this.hook.emit('allowAddPointStateChange', 'allow')\n }\n } else {\n this.area.hideArea()\n this.perpendicularDashed.hide()\n // document.documentElement.style.cursor = 'default'\n }\n }\n\n this.five.needsRender = true\n }\n\n // ====================================================================================================================================\n\n // 下面一堆高亮相关\n private wantsTapGesture: EventCallback['wantsTapGesture'] = (raycaster) => {\n if (this.editParams.pointSelectorMode === 'cursor') return false\n if (this.lastPoint) return false // 编辑中\n\n // ================================= 这是选择面的逻辑 =================================\n const intersections = this.model.areas\n .map((area) => raycaster.intersectObject(area.polygon, true)[0]) // 获取所有的交点\n .sort((a, b) => a.distance - b.distance) // 按照距离排序\n const intersectionObject = intersections[0]?.object?.parent as any\n if (intersectionObject?.isPolygonMesh) {\n const area = this.model.areas.find((area) => area.polygon === intersectionObject)\n if (area) {\n const { x, y } = intersections[0].point.clone().project(this.five.camera)\n const left = `${((x + 1) / 2) * 100}%`\n const top = `${((-y + 1) / 2) * 100}%`\n this.chooseArea(area, { left, top })\n return false\n }\n }\n // ================================= 这后面是之前的选择线的逻辑 =================================\n const [target] = getFiveModel(this.five).intersectRaycaster(raycaster)\n if (!target) return\n const camera = this.five.camera\n const ndcTarget = target.point.clone().project(camera)\n const screenWidth = this.container.clientWidth\n const screenHeight = this.container.clientHeight\n const targetScreenPosition = new Vector2(ndcTarget.x * screenWidth, ndcTarget.y * screenHeight)\n // 把线的端点全部映射到屏幕上,过滤掉不在视野内的线,同时乘以屏幕宽 & 高\n const screenLines = this.model\n .getAllLines()\n .map((line) => {\n const [startPoint, endPoint] = line.points\n const ndcStartPoint = startPoint.position.clone().project(camera)\n const ndcEndPoint = endPoint.position.clone().project(camera)\n if (!isNDCPointInScreen(ndcStartPoint) && !isNDCPointInScreen(ndcEndPoint)) return null\n const startScreenPosition = new Vector2(ndcStartPoint.x * screenWidth, ndcStartPoint.y * screenHeight)\n const endScreenPosition = new Vector2(ndcEndPoint.x * screenWidth, ndcEndPoint.y * screenHeight)\n return { id: line.id, points: [startScreenPosition, endScreenPosition] }\n })\n .filter((line) => !!line) as { id: string; points: Vector2[] }[]\n if (screenLines.length === 0) return\n // 找这些线距离鼠标点击位置最近的线\n const distanceLines = screenLines\n .map((line) => {\n const closestPoint = closestPointOnLine(targetScreenPosition, line.points)\n return { id: line.id, distance: closestPoint.distanceTo(targetScreenPosition) }\n })\n .sort((a, b) => a.distance - b.distance)\n const closestScreenLine = distanceLines[0]\n if (closestScreenLine.distance > 20) return\n const closestLine = this.model.getAllLines().find(({ id }) => id === closestScreenLine.id)\n if (!closestLine) return\n this.chooseLine(closestLine)\n return false\n }\n\n private chooseLine = (line: Line) => {\n const highlightLines = line.getPolyline().lines\n this.deleteDom.setTarget(highlightLines).setLines(highlightLines).updatePosition().show()\n this.highlightLines(highlightLines)\n this.hook.emit('selectedChange', highlightLines)\n }\n\n private chooseArea = (area: Area, clickPosition: { left: string; top: string }) => {\n this.deleteDom.setTarget(area).updatePosition(clickPosition.left, `calc(${clickPosition.top} - 1.5rem)`).show() // 往上挪一点,出现在鼠标上方\n this.highlightArea(area)\n }\n\n private highlightArea(area: Area) {\n this.highlightLines(area.polyline.lines)\n this.five.needsRender = true\n }\n\n private unHighlightArea(area: Area) {\n this.unHighlightLines(area.polyline.lines)\n this.five.needsRender = true\n }\n\n private highlightLines(lines: Line[]) {\n lines.forEach((line) => this.highlightLine(line))\n }\n\n private unHighlightLines(lines: Line[]) {\n lines.forEach((line) => {\n line.selected = false\n line.distanceItem.unHighlight()\n this.group.remove(line.lightMesh)\n this.five.needsRender = true\n })\n }\n\n private highlightLine(line: Line) {\n this.unHighlightLines(this.model.getAllLines())\n if (line.selected) return\n line.selected = true\n this.group.add(line.lightMesh)\n line.distanceItem.highlight()\n this.five.needsRender = true\n }\n\n private deleteArea = (area: Area) => {\n this.unHighlightArea(area)\n area.dispose()\n this.deleteDom.hide()\n }\n\n private deleteLine = (lines: Line[]) => {\n const firstLine = lines[0]\n const polyline = this.model.getPolylineByLine(firstLine)\n if (!polyline) return\n this.model.removePolyline(polyline)\n polyline.lines.forEach((line) => this.removeLine(line))\n this.deleteDom.setLines([]).hide()\n }\n}\n","import type { Polyline } from '../Model/polyline'\nimport BaseController, { type ControllerParams } from './BaseController'\nimport type { Mode as FiveMode } from '@realsee/five-webgpu'\n\nexport default class ViewController extends BaseController {\n public type = 'view'\n\n public constructor(params: ControllerParams) {\n super(params)\n this.model.getAllLines().forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n this.group.add(line.mesh)\n line.mesh.updateMatrixWorld()\n })\n this.onFiveModeChange(this.five.getCurrentState().mode)\n this.onFivePanoWillArrive(this.five.getCurrentState().panoIndex)\n this.onFivePanoArrived(this.five.getCurrentState().panoIndex)\n this.updateDistanceUI()\n this.five.needsRender = true\n this.model.hook.on('polylineAdded', this.polylineAdded)\n this.model.hook.on('polylineRemoved', this.polylineRemoved)\n this.five.on('cameraUpdate', this.onCameraUpdate)\n this.five.on('panoArrived', this.onFivePanoArrived)\n this.five.on('modeChange', this.onFiveModeChange)\n this.five.on('panoWillArrive', this.onFivePanoWillArrive)\n }\n\n public dispose() {\n super.dispose()\n this.model.hook.off('polylineAdded', this.polylineAdded)\n this.model.hook.off('polylineRemoved', this.polylineRemoved)\n this.five.off('cameraUpdate', this.onCameraUpdate)\n this.five.off('panoArrived', this.onFivePanoArrived)\n this.five.off('modeChange', this.onFiveModeChange)\n this.five.off('panoWillArrive', this.onFivePanoWillArrive)\n this.five.needsRender = true\n this.hook.emit('selectedChange', [])\n }\n\n private polylineRemoved = (polyline: Polyline) => {\n polyline.lines.forEach((line) => this.removeLine(line))\n // TODO: 这个逻辑不太好,改进一下\n this.hook.emit(\n 'selectedChange',\n this.model\n .getAllLines()\n .filter((line) => line.selected)\n .map((line) => line),\n )\n }\n\n private polylineAdded = (polyline: Polyline) => {\n const { panoIndex, mode } = this.five.getCurrentState()\n polyline.lines.forEach((line) => {\n if (polyline.visibleFiveMode && !polyline.visibleFiveMode.includes(mode)) {\n line.mesh.visible = false\n }\n if (polyline.visiblePanoIndexes && !polyline.visiblePanoIndexes.includes(panoIndex)) {\n line.mesh.visible = false\n }\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n this.group.add(line.mesh)\n })\n this.updateDistanceUI()\n }\n\n private onCameraUpdate = () => {\n this.updateDistanceUI()\n }\n\n private onFiveModeChange = (mode: FiveMode) => {\n if (mode === 'Panorama') return\n\n this.model.polylines.forEach((polyline) => {\n if (polyline.visibleFiveMode && !polyline.visibleFiveMode.includes(mode)) {\n polyline.lines.forEach((line) => {\n line.mesh.visible = false\n line.distanceItem.update(this.five)\n })\n }\n })\n\n this.five.ready().then(() => {\n const mode = this.five.getCurrentState().mode\n if (mode === 'Panorama') return\n\n this.model.polylines.forEach((polyline) => {\n if (polyline.visibleFiveMode && polyline.visibleFiveMode.includes(mode)) {\n polyline.lines.forEach((line) => {\n line.mesh.visible = true\n line.distanceItem.update(this.five)\n })\n }\n })\n })\n }\n\n private onFivePanoWillArrive = (panoIndex: number) => {\n this.model.polylines.forEach((polyline) => {\n if (\n (polyline.visiblePanoIndexes && !polyline.visiblePanoIndexes.includes(panoIndex)) ||\n (polyline.visibleFiveMode && !polyline.visibleFiveMode.includes(this.five.getCurrentState().mode))\n ) {\n polyline.lines.forEach((line) => {\n line.mesh.visible = false\n line.distanceItem.update(this.five)\n })\n }\n })\n }\n\n private onFivePanoArrived = (panoIndex: number) => {\n this.model.polylines.forEach((polyline) => {\n if (polyline.visiblePanoIndexes && polyline.visiblePanoIndexes.includes(panoIndex)) {\n if (polyline.visibleFiveMode && polyline.visibleFiveMode.includes(this.five.getCurrentState().mode)) {\n polyline.lines.forEach((line) => {\n line.mesh.visible = true\n line.distanceItem.update(this.five)\n })\n }\n }\n })\n }\n}\n","import { Vector2 } from 'three/webgpu'\nimport type { Vector3 } from 'three/webgpu'\n\nexport default function ndc2Screen(ndcPosition: Vector3, containerSize: { width: number; height: number }) {\n const left = ((ndcPosition.x + 1) / 2) * containerSize.width\n const top = (-(ndcPosition.y - 1) / 2) * containerSize.height\n return new Vector2(left, top)\n}\n","import type { Vector2 } from 'three/webgpu'\nimport type Point from '../Model/point'\nimport type { Five } from '@realsee/five-webgpu'\nimport ndc2Screen from './ndc2Screen'\nimport isNDCPointInScreen from './isNDCPointInScreen'\n\n/**\n * @param tapPoint 注意这里的坐标是相对于 FiveElement 的\n */\n\nexport function findClosestPoint(five: Five, points: Point[], tapPoint: Vector2, maxDistance?: number) {\n const container = five.getElement()\n if (!container) return null\n if (points.length === 0) return null\n\n const containerSize = { width: container.clientWidth, height: container.clientHeight }\n const ndcPoints = points\n .map((point) => {\n const ndcPosition = point.position.clone().project(five.camera)\n if (!isNDCPointInScreen(ndcPosition)) return { distance: Infinity, point }\n const screenPosition = ndc2Screen(ndcPosition, containerSize)\n const distance = screenPosition.distanceTo(tapPoint)\n return { distance, point }\n })\n .sort((a, b) => a.distance - b.distance)\n if (typeof maxDistance === 'number' && ndcPoints[0].distance > maxDistance) return null\n return ndcPoints[0]\n}\n","import type Hammer from 'hammerjs'\nimport { Vector2 } from 'three/webgpu'\n\n/**\n * 从 Hammer 事件中获取操作的点在交互 DOM 中的位置\n * @ignore TODO: make a suitable name\n */\nexport function getPointFromHammerEvent(event: (typeof Hammer)['Input']) {\n // clientX 与 clientY 是相对 document 的,需要转换成相对于 target 的坐标\n const { x: clientX, y: clientY } = event.center\n const { clientWidth, clientHeight } = event.target\n const clientRect = event.target.getBoundingClientRect()\n const position = new Vector2(clientX, clientY).sub(new Vector2(clientRect.left, clientRect.top))\n const mouse = new Vector2((position.x / clientWidth) * 2 - 1, -(position.y / clientHeight) * 2 + 1)\n return { point: position, ndcPoint: mouse }\n}\n","import type Line from '../Model/line'\nimport type Point from '../Model/point'\nimport type { EventCallback, Intersection, IntersectMeshInterface } from '@realsee/five-webgpu'\nimport type { Polyline } from '../Model/polyline'\nimport type Hammer from 'hammerjs'\nimport DeleteDom from '../Modules/DeleteDom'\nimport isNDCPointInScreen from '../utils/isNDCPointInScreen'\nimport BaseController, { type ControllerParams } from './BaseController'\nimport { Raycaster, Vector2 } from 'three/webgpu'\nimport { closestPointOnLine } from '../utils/math'\nimport { findClosestPoint } from '../utils/findClosestPoint'\nimport { getPointFromHammerEvent } from '../../shared-utils/getPointFromHammerEvent'\nimport Area from '../Model/area'\nimport { PolygonMesh } from '../Model/polygon'\nimport { getFiveModel } from '../../shared-utils/five/getFiveModel'\n\nconst disableFiveEvent = (): false => false\n\nexport default class WatchController extends BaseController {\n public type = 'watch'\n private deleteDom: DeleteDom\n private choose: 'line' | Area | null // tmd 真没时间改了,先这样吧,理解万岁\n private highlightedLines: Line[] = []\n private highlightedArea: Area\n private fiveElement?: HTMLCanvasElement\n private editPointState?: {\n point: Point\n associatedLines: Line[]\n }\n private hammer?: InstanceType<(typeof Hammer)['Manager']>\n private isDisposed = false\n\n public constructor(params: ControllerParams) {\n super(params)\n this.deleteDom = new DeleteDom(this.five, {\n i18n: this.config.i18n,\n onClick: () => {\n if (this.choose === 'line') this.deleteLine()\n else if (this.choose instanceof Area) this.deleteArea(this.choose)\n },\n cancel: this.cancelDeleteClickCallback,\n }).appendTo(this.container)\n this.model.getAllLines().forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n line.hook.on('selected', this.chooseLine)\n line.distanceItem.setCanSelect(true)\n this.group.add(line.mesh)\n })\n this.model.getAllAreas().forEach((area) => {\n area.areaItem.appendTo(this.container)\n area.areaItem.updateArea(this.five)\n area.hook.on('selected', this.chooseArea)\n area.areaItem.setCanSelect(true)\n\n this.group.add(area.polygon)\n area.polyline.lines.forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n this.group.add(line.mesh)\n })\n })\n const fiveElement = this.five.getElement()\n if (fiveElement) {\n this.fiveElement = fiveElement\n void import('hammerjs').then(({ default: Hammer }) => {\n if (this.isDisposed) return\n const hammer = new Hammer(fiveElement)\n this.hammer = hammer\n hammer.on('pan', this.onPan)\n hammer.on('panstart', this.onPanStart)\n hammer.on('panend', this.onPanEnd)\n })\n }\n\n this.updateDistanceUI()\n this.five.needsRender = true\n this.five.on('cameraUpdate', this.onCameraUpdate)\n this.five.on('wantsTapGesture', this.wantsTapGesture)\n this.five.on('wantsPanGesture', this.wantsPanGesture)\n this.five.on('wantsChangeMode', disableFiveEvent)\n this.model.hook.on('polylineRemoved', this.polylineRemoved)\n }\n\n public dispose() {\n this.isDisposed = true\n super.dispose()\n this.deleteDom.dispose()\n this.model.hook.off('polylineRemoved', this.polylineRemoved)\n this.model.getAllLines().forEach((line) => line.hook.off('selected', this.chooseLine))\n this.five.off('cameraUpdate', this.onCameraUpdate)\n this.five.off('wantsPanGesture', this.wantsPanGesture)\n this.five.off('wantsTapGesture', this.wantsTapGesture)\n this.five.off('wantsChangeMode', disableFiveEvent)\n this.five.needsRender = true\n this.hook.emit('selectedChange', [])\n this.hammer?.destroy()\n }\n\n public highlightLine(line: Line) {\n if (line.selected) return\n line.selected = true\n this.group.add(line.lightMesh)\n line.distanceItem.highlight()\n this.five.needsRender = true\n }\n\n public clearHighlightLines() {\n if (this.group.children.length === 0) return\n this.unHighlightLines(this.highlightedLines)\n this.highlightedLines = []\n }\n\n private highlightArea(area: Area) {\n this.unHighlightLines()\n this.unHighlightArea()\n this.highlightLines(area.polyline.lines)\n this.five.needsRender = true\n }\n\n private unHighlightArea(_area?: Area) {\n const area = _area ?? this.highlightedArea\n if (!area) return\n this.unHighlightLines(area.polyline.lines)\n this.five.needsRender = true\n }\n\n private highlightLines(lines: Line[]) {\n this.unHighlightLines()\n this.highlightedLines = lines\n lines.forEach((line) => this.highlightLine(line))\n }\n\n private unHighlightLines(_lines?: Line[]) {\n this.unHighlightArea()\n const lines = _lines ?? this.highlightedLines\n if (!lines) return\n lines.forEach((line) => {\n line.selected = false\n line.distanceItem.unHighlight()\n this.group.remove(line.lightMesh)\n this.five.needsRender = true\n })\n }\n\n private onPanStart = (e: (typeof Hammer)['Input']) => {\n if (this.model.getAllLines().length === 0 || !this.fiveElement) return\n const mouse = getPointFromHammerEvent(e).point\n const closestPoint = findClosestPoint(this.five, this.model.getAllPoints(), mouse, 20)?.point\n if (!closestPoint) {\n this.editPointState = undefined\n return\n }\n const closestPolyline = this.model.polylines.find((polyline) => polyline.includes(closestPoint))\n const editPointState = {\n point: closestPoint,\n associatedLines: closestPolyline.lines,\n }\n const cancelDragLine = this.hook.emit('wantsDragLine', {\n point: closestPoint.id,\n lines: editPointState.associatedLines.map(({ id }) => id),\n })\n if (cancelDragLine) return\n this.editPointState = editPointState\n this.magnifier.appendTo(this.container)\n this.magnifier.enable()\n this.group.add(this.mouseGroup)\n }\n\n private onPanEnd = () => {\n if (!this.editPointState) return\n // 把拖动的线从虚线转换为实线\n this.editPointState.associatedLines.forEach((line) => line.mesh.setMaterial({ dashed: false }))\n // 还原选中态\n this.highlightLines(this.editPointState.associatedLines)\n this.editPointState = undefined\n\n this.magnifier.disable()\n this.group.remove(this.mouseGroup)\n }\n\n private onPan = (e: (typeof Hammer)['Input']) => {\n if (!this.editPointState || !this.fiveElement) return\n const mouse = getPointFromHammerEvent(e).ndcPoint\n const raycaster = new Raycaster()\n raycaster.setFromCamera(mouse, this.five.camera)\n const [intersection] = getFiveModel(this.five).intersectRaycaster(raycaster)\n if (!intersection) return\n this.onIntersectionUpdate(intersection)\n }\n\n private onIntersectionUpdate = (intersection: Intersection, mesh?: IntersectMeshInterface) => {\n if (!this.editPointState) return\n // 拖动过程中清除选中态\n this.clearHighlightLines()\n // 把拖动点相关的线变成虚线 & 改变相关线的位置\n this.editPointState.point.position.copy(intersection.point)\n this.editPointState.associatedLines.forEach((line) => {\n line.mesh.setPoints(line.points[0].position.clone(), line.points[1].position.clone())\n line.lightMesh.setPoints(line.points[0].position.clone(), line.points[1].position.clone())\n line.mesh.setMaterial({ dashed: true })\n })\n this.updateDistanceUI()\n this.magnifier.renderWithPoint(intersection.point)\n this.mouseGroup.position.copy(intersection.point)\n if (mesh) {\n this.mouseGroup.quaternion.copy(mesh.quaternion)\n } else if (intersection.face) {\n const face = intersection.face.normal\n const positionVector = face.clone().multiplyScalar(0.05)\n const position = intersection.point.clone().add(positionVector)\n const lookAtVector = position.clone().add(positionVector)\n this.mouseGroup.lookAt(lookAtVector)\n }\n this.five.needsRender = true\n this.hook.emit(\n 'selectedChange',\n this.editPointState.associatedLines.map((line) => line),\n )\n }\n\n private wantsPanGesture: EventCallback['wantsPanGesture'] = () => {\n if (this.editPointState) return false\n }\n\n private wantsTapGesture: EventCallback['wantsTapGesture'] = (raycaster) => {\n // ================================= 这是选择面的逻辑 =================================\n const intersections = this.model.areas\n .map((area) => raycaster.intersectObject(area.polygon, true)[0]) // 获取所有的交点\n .sort((a, b) => a.distance - b.distance) // 按照距离排序\n const intersectionObject = intersections[0]?.object.parent\n if (intersectionObject instanceof PolygonMesh) {\n const area = this.model.areas.find((area) => area.polygon === intersectionObject)\n if (area) {\n const { x, y } = intersections[0].point.clone().project(this.five.camera)\n const left = `${((x + 1) / 2) * 100}%`\n const top = `${((-y + 1) / 2) * 100}%`\n this.chooseArea(area, { left, top })\n return false\n }\n }\n // ================================= 这后面是之前的选择线的逻辑 =================================\n const model = getFiveModel(this.five)\n const [target] = model.intersectRaycaster(raycaster)\n if (!target) return\n const camera = this.five.camera\n const ndcTarget = target.point.clone().project(camera)\n const screenWidth = this.container.clientWidth\n const screenHeight = this.container.clientHeight\n const targetScreenPosition = new Vector2(ndcTarget.x * screenWidth, ndcTarget.y * screenHeight)\n // 把线的端点全部映射到屏幕上,过滤掉不在视野内的线,同时乘以屏幕宽 & 高\n const screenLines = this.model\n .getAllLines()\n .map((line) => {\n const [startPoint, endPoint] = line.points\n const ndcStartPoint = startPoint.position.clone().project(camera)\n const ndcEndPoint = endPoint.position.clone().project(camera)\n if (!isNDCPointInScreen(ndcStartPoint) && !isNDCPointInScreen(ndcEndPoint)) return null\n const startScreenPosition = new Vector2(ndcStartPoint.x * screenWidth, ndcStartPoint.y * screenHeight)\n const endScreenPosition = new Vector2(ndcEndPoint.x * screenWidth, ndcEndPoint.y * screenHeight)\n return { id: line.id, points: [startScreenPosition, endScreenPosition] }\n })\n .filter((line) => !!line) as { id: string; points: Vector2[] }[]\n if (screenLines.length === 0) return\n // 找这些线距离鼠标点击位置最近的线\n const distanceLines = screenLines\n .map((line) => {\n const closestPoint = closestPointOnLine(targetScreenPosition, line.points)\n return { id: line.id, distance: closestPoint.distanceTo(targetScreenPosition) }\n })\n .sort((a, b) => a.distance - b.distance)\n const closestScreenLine = distanceLines[0]\n if (closestScreenLine.distance > 20) return\n const closestLine = this.model.getAllLines().find(({ id }) => id === closestScreenLine.id)\n if (!closestLine) return\n this.chooseLine(closestLine)\n return false\n }\n\n private chooseLine = (line: Line) => {\n this.choose = 'line'\n const highlightLines = line.getPolyline().lines\n this.highlightLines(highlightLines)\n this.five.needsRender = true\n this.hook.emit(\n 'selectedChange',\n highlightLines.map((line) => line),\n )\n }\n\n private chooseArea = (area: Area, clickPosition: { left: string; top: string }) => {\n this.choose = area\n this.deleteDom.updatePosition(clickPosition.left, `calc(${clickPosition.top} - 20px)`).show() // 往上挪一点,出现在鼠标上方\n this.highlightArea(area)\n }\n\n private polylineRemoved = (polyline: Polyline) => {\n polyline.lines.forEach((line) => this.removeLine(line))\n // TODO: 这个逻辑不太好,改进一下\n this.hook.emit(\n 'selectedChange',\n this.model\n .getAllLines()\n .filter((line) => line.selected)\n .map((line) => line),\n )\n }\n\n private onCameraUpdate = () => {\n this.updateDistanceUI()\n this.highlightedLines.length > 0 && this.deleteDom.updatePosition()\n }\n\n private deleteArea = (area: Area) => {\n this.unHighlightArea(area)\n area.dispose()\n this.deleteDom.hide()\n }\n\n private deleteLine = () => {\n const firstLine = this.highlightedLines[0]\n const polyline = this.model.getPolylineByLine(firstLine)\n if (!polyline) return\n this.model.removePolyline(polyline)\n this.highlightedLines = []\n this.deleteDom.setLines([]).hide()\n }\n\n private cancelDeleteClickCallback = () => {\n this.deleteDom.hide()\n this.clearHighlightLines()\n this.unHighlightArea()\n }\n}\n","import { Subscribe } from '../../shared-utils/Subscribe'\nimport type { Config } from '../typings'\nimport type { MeasurePluginData } from '../typings/data'\nimport type Area from './area'\nimport type Line from './line'\nimport { Polyline } from './polyline'\n\ntype IModelEvent = {\n /** 新增线条\n * @param line 被创建的线条\n */\n polylineAdded: (line: Polyline) => void\n\n /** 新增面积\n * @param area 被创建的面积\n */\n areaAdded: (area: Area) => void\n\n /** 删除线条\n * @param lines 被删除的线条数组\n */\n polylineRemoved: (lines: Polyline) => void\n}\n\nexport class Model {\n public readonly config?: Config\n public readonly polylines: Polyline[] = []\n public readonly areas: Area[] = []\n public readonly hook = new Subscribe<IModelEvent>()\n\n public constructor(config?: Config) {\n this.config = config\n }\n\n public addPolyline(polyline: Polyline) {\n if (this.includes(polyline)) {\n console.error(new Error('不能重复添加 polyline'))\n return\n }\n this.polylines.push(polyline)\n this.hook.emit('polylineAdded', polyline)\n }\n\n public addArea(area: Area) {\n if (this.areas.find(({ id }) => id === area.id) !== undefined) {\n console.error(new Error('不能重复添加 area'))\n return\n }\n this.areas.push(area)\n this.hook.emit('areaAdded', area)\n }\n\n public replacePolylineByID(id: string, polyline: Polyline) {\n const prevPolyline = this.getPolylineByID(id)\n prevPolyline?.replace(polyline)\n }\n\n public removePolyline(polyline: Polyline) {\n const index = this.polylines.findIndex(({ id }) => id === polyline.id)\n if (index === -1) {\n console.error(new Error('polyline 不存在'))\n return\n }\n this.polylines.splice(index, 1)\n this.hook.emit('polylineRemoved', polyline)\n }\n\n public removeArea(area: Area) {\n const index = this.areas.findIndex(({ id }) => id === area.id)\n if (index === -1) {\n console.error(new Error('area 不存在'))\n return\n }\n this.areas.splice(index, 1)\n }\n\n public getPolylineByID(id: string) {\n return this.polylines.find((polyline) => polyline.id === id)\n }\n\n public getPolylineByLine(line: Line) {\n return this.polylines.find((polyline) => polyline.includes(line))\n }\n\n public getLineByID(id: string) {\n return this.getAllLines().find((line) => line.id === id)\n }\n\n public getAllLines() {\n return this.polylines.map((polyline) => polyline.lines).flat(1)\n }\n\n public getAllAreas() {\n return this.areas\n }\n\n public getAllPoints() {\n return this.polylines.map((polyline) => polyline.points).flat(1)\n }\n\n public includes(item: Polyline) {\n return this.polylines.find(({ id }) => id === item.id) !== undefined\n }\n\n public clear() {\n this.polylines.forEach((polyline) => this.hook.emit('polylineRemoved', polyline))\n this.areas.forEach((area) => area.dispose())\n this.polylines.splice(0, this.polylines.length)\n this.areas.splice(0, this.areas.length)\n }\n\n public dispose() {\n this.clear()\n }\n\n public getClosestPoint() {}\n\n public parse(data: MeasurePluginData) {\n this.clear()\n this.polylines.push(...data.polylines.map((polylineData) => new Polyline({ model: this }).fromJson(polylineData)))\n this.polylines.forEach((polyline) => this.hook.emit('polylineAdded', polyline))\n }\n\n public toJson(): MeasurePluginData {\n return {\n polylines: this.polylines.map((polyline) => polyline.toJson()).filter((polylines) => polylines.lines.length > 0),\n }\n }\n}\n","function noop(): void {\n return void 0\n}\n\n/**\n * 空函数\n */\nexport default noop\n","import {\n CurvePath,\n DoubleSide,\n Group,\n LinearFilter,\n LineCurve3,\n Mesh,\n MeshBasicMaterial,\n PlaneGeometry,\n BufferAttribute,\n SphereGeometry,\n SRGBColorSpace,\n TextureLoader,\n TubeGeometry,\n Vector3,\n} from 'three/webgpu'\n\n// 移动端纹理贴图(只有十字不带圆圈)\nconst mobileTextureUrl = `data:image/png;base64,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`\n\n// pc端纹理贴图(带圆圈)\nconst pcTextureUrl = `data:image/png;base64,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`\n\n\nexport interface MouseGroupParameter {\n isMobile?: boolean\n useNormalVector?: boolean // 是否展示法向量\n ballColor?: number // 法向量小球色值\n}\n\nexport function getMouseGroup(params: MouseGroupParameter) {\n const isMobile = params.isMobile ?? true\n const useNormalVector = params.useNormalVector ?? true\n let ballColor = 0x9ded6b\n if (useNormalVector && params.ballColor >= 0) {\n ballColor = params.ballColor\n }\n\n const group = new Group()\n // 底部纹理贴图面片\n const planGeometry = new PlaneGeometry(0.3, 0.3)\n const planTextureUrl = isMobile ? mobileTextureUrl : pcTextureUrl\n const planTexture = new TextureLoader().load(planTextureUrl)\n planTexture.colorSpace = SRGBColorSpace\n planTexture.minFilter = LinearFilter\n const planMaterial = new MeshBasicMaterial({\n map: planTexture,\n transparent: true,\n depthTest: false,\n })\n const planMesh = new Mesh(planGeometry, planMaterial)\n // 法向量垂直管\n const zPath = new CurvePath<Vector3>()\n zPath.add(new LineCurve3(new Vector3(0, 0, 0), new Vector3(0, 0, 0.1)))\n const zGeometry = new TubeGeometry(zPath, 8, 0.003)\n const colors = new Float32Array(zGeometry.getAttribute('position').count * 4)\n const uv = zGeometry.getAttribute('uv')\n for (let i = 0; i < uv.count; i++) colors.set([1, 1, 1, 1 - uv.getX(i)], i * 4)\n zGeometry.setAttribute('color', new BufferAttribute(colors, 4))\n const zMaterial = new MeshBasicMaterial({\n vertexColors: true,\n depthTest: false,\n transparent: true,\n })\n const zMesh = new Mesh(zGeometry, zMaterial)\n // 法向量圆球\n const ballGeometry = new SphereGeometry(0.01, 20, 20)\n const ballMaterial = new MeshBasicMaterial({\n color: ballColor,\n depthTest: false,\n transparent: true,\n side: DoubleSide,\n })\n const ballMesh = new Mesh(ballGeometry, ballMaterial)\n ballMesh.position.set(0, 0, 0.1)\n\n group.name = 'mouse-current'\n group.add(planMesh)\n if (useNormalVector) group.add(zMesh, ballMesh)\n\n return group\n}\n","import type { Five, Intersection, IntersectMeshInterface } from '@realsee/five-webgpu'\nimport type { Group, Vector3 } from 'three/webgpu'\nimport { DoubleSide, Mesh, MeshBasicMaterial, Raycaster, RingGeometry } from 'three/webgpu'\nimport type { Model } from '../../Model'\nimport type { PanoMeasurePluginEvent } from '../../typings/event.type'\nimport Point from '../../Model/point'\nimport * as TWEEN from '@tweenjs/tween.js'\nimport htmlString from '../../../shared-utils/three/PointSelector/utils/html'\nimport { requestAnimationFrameInterval } from '../../../shared-utils/animationFrame'\nimport noop from '../../../shared-utils/noop'\nimport { getMouseGroup } from '../../utils/mouseGroup'\nimport type { OpenParameter } from '../../typings/data'\nimport { calculateThreeMouse } from '../../../shared-utils/five/calculateThreeMouse'\nimport type { Subscribe } from '../../../shared-utils/Subscribe'\nimport { getFiveModel } from '../../../shared-utils/five/getFiveModel'\n\nexport interface RangePieceControllerParams {\n openParams: OpenParameter\n container: Element\n five: Five\n group: Group\n model: Model\n mouseGroup: Group\n hook: Subscribe<PanoMeasurePluginEvent>\n}\n\nexport default class RangePieceController {\n private container = document.createElement('div')\n private five: Five\n private group: Group\n private mouseGroup: Group\n private hasAppendMouseGroup = false\n private hook: Subscribe<PanoMeasurePluginEvent>\n private content: HTMLElement | null\n private intersectMesh: Mesh\n private centerMouseXY: any\n private raycaster = new Raycaster()\n private pieceStyl = {\n matrix3d: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],\n scale: 1,\n opacity: 0.4,\n }\n\n\n constructor(params: RangePieceControllerParams) {\n this.five = params.five\n this.hook = params.hook\n this.group = params.group\n this.mouseGroup = getMouseGroup({ isMobile: true, ...params.openParams.crossHairParameter })\n this.container.innerHTML = htmlString\n this.container.classList.add('range-piece-controller')\n this.content = this.container.querySelector<HTMLElement>('.range-piece__content')\n if (this.content) {\n this.content.style.transform = `matrix3d(${this.pieceStyl.matrix3d.toString()}) scale(${this.pieceStyl.scale})`\n this.content.style.opacity = `${this.pieceStyl.opacity}`\n }\n params.container.append(this.container)\n\n this.intersectMesh = new Mesh(\n new RingGeometry(0.04, 0.08, 32),\n new MeshBasicMaterial({ color: 0x12fffb, opacity: 0, side: DoubleSide, transparent: true }),\n )\n\n this.container.addEventListener('animationend', this.computedCenterMouseXY)\n\n this.five.on('cameraUpdate', this.onCameraDirectionUpdate)\n this.hook.on('willChangeState', this.onWillChangeState)\n }\n\n public dispose() {\n this.container.removeEventListener('animationend', this.computedCenterMouseXY)\n this.five.off('cameraUpdate', this.onCameraDirectionUpdate)\n this.hook.off('willChangeState', this.onWillChangeState)\n this.container.remove()\n this.group.remove(this.mouseGroup)\n this.mouseGroup.remove()\n this.hasAppendMouseGroup = false\n this.five.scene.remove(this.intersectMesh)\n }\n\n private onCameraDirectionUpdate = () => {\n const intersection = this.getIntersection()\n if (intersection) {\n this.pieceChange(intersection)\n this.updateMouseGroup(intersection)\n const nowPoint = new Point(this.mouseGroup.position)\n this.hook.emit('nowPointChange', nowPoint)\n }\n }\n\n private onWillChangeState: PanoMeasurePluginEvent['willChangeState'] = (state, newState) => {\n this.dotAnimation()\n const point = this.getIntersection()?.point\n if (!point) return\n if (newState === 'editing') {\n this.hook.emit('getStartPoint', new Point(point))\n } else {\n this.hook.emit('getEndPoint', new Point(point))\n }\n }\n\n /** 计算目标中心点经纬度 */\n private computedCenterMouseXY = () => {\n const aimRef = this.container.querySelector<HTMLElement>('.range-piece__aim')\n if (!aimRef) return null\n const { left, top, width, height } = aimRef.getBoundingClientRect()\n const mouseX = Math.round(left + width / 2)\n const mouseY = Math.round(top + height / 2)\n const mouse = { x: mouseX, y: mouseY }\n const mouseXY = calculateThreeMouse(mouse, this.five.getElement()) // 经纬度\n this.centerMouseXY = mouseXY\n }\n\n /** 计算目标中心点intersection */\n private getIntersection = () => {\n if (!this.centerMouseXY) return null\n this.raycaster.setFromCamera(this.centerMouseXY, this.five.camera)\n const intersection = getFiveModel(this.five).intersectRaycaster(this.raycaster)[0]\n if (intersection) return intersection\n else return null\n }\n\n private pieceChange(intersection: Intersection) {\n const face = intersection.face\n const point = intersection.point\n if (face && point) {\n const normal = face.normal.clone()\n const positionVector = normal.clone().multiplyScalar(0.05)\n const position = point.clone().add(positionVector)\n this.intersectMesh.position.copy(position)\n const lookAtVector = position.clone().add(positionVector)\n this.intersectMesh.lookAt(lookAtVector)\n this.five.scene.add(this.intersectMesh)\n const matrix = this.intersectMesh.modelViewMatrix.clone().toArray()\n this.changePieceStyl('matrix3d', matrix)\n const scale = this.calculateSize(point)\n this.changePieceStyl('scale', scale)\n }\n }\n\n private calculateSize(vector: Vector3) {\n if (!vector) return\n const cameraPos = this.five.camera.position\n let distance = vector.distanceTo(cameraPos)\n const maxDis = 4\n const minDis = 1\n if (distance > maxDis) distance = maxDis\n if (distance < minDis) distance = minDis\n const scale = (-0.51 / (maxDis - minDis)) * distance + 1\n return scale\n }\n\n /** 点击按钮时圆片动画 */\n private dotAnimation() {\n const firstEasing = TWEEN.Easing.Quadratic.InOut\n const from = { opacity: 0.4, scale: this.pieceStyl.scale }\n const to = { opacity: [1, 0.4], scale: [this.pieceStyl.scale * 0.8, this.pieceStyl.scale] }\n let stop = noop\n\n const firstTween = new TWEEN.Tween(from)\n .to(to, 500)\n .easing(firstEasing)\n .start(0)\n .onUpdate(({ opacity, scale }) => {\n this.changePieceStyl('scale', scale)\n this.changePieceStyl('opacity', opacity)\n })\n .onComplete(() => {\n stop()\n })\n\n stop = requestAnimationFrameInterval((time: number) => {\n firstTween.update(time)\n })\n }\n\n private changePieceStyl(key, value) {\n if (!this.content) return\n this.pieceStyl[key] = value\n this.content.style.transform = `matrix3d(${this.pieceStyl.matrix3d.toString()}) scale(${this.pieceStyl.scale})`\n this.content.style.opacity = `${this.pieceStyl.opacity}`\n }\n\n private updateMouseGroup(intersection: Intersection, mesh?: IntersectMeshInterface) {\n if (!this.hasAppendMouseGroup) {\n this.group.add(this.mouseGroup)\n this.hasAppendMouseGroup = true\n const aimRef = this.container.querySelector<HTMLElement>('.range-piece__aim')\n if (aimRef) aimRef.style.opacity = '0'\n }\n if (!intersection) return this.mouseGroup\n this.mouseGroup.position.copy(intersection.point)\n // ============ update mouseGroup quaternion ============\n if (mesh) {\n this.mouseGroup.quaternion.copy(mesh.quaternion)\n } else if (intersection.face) {\n const normal = intersection.face.normal\n const positionVector = normal.clone().multiplyScalar(0.05)\n const position = intersection.point.clone().add(positionVector)\n const lookAtVector = position.clone().add(positionVector)\n this.mouseGroup.lookAt(lookAtVector)\n }\n return this.mouseGroup\n }\n}\n","import type Point from '../Model/point'\nimport type { EventCallback } from '@realsee/five-webgpu'\nimport type { ControllerParams } from './BaseController'\nimport { Model } from '../Model'\nimport Line from '../Model/line'\nimport BaseController from './BaseController'\nimport DeleteDom from '../Modules/DeleteDom'\nimport { Vector2 } from 'three/webgpu'\nimport isNDCPointInScreen from '../utils/isNDCPointInScreen'\nimport { closestPointOnLine } from '../utils/math'\nimport { Polyline } from '../Model/polyline'\nimport RangePieceController from '../Modules/rangePiece'\nimport { getFiveModel } from '../../shared-utils/five/getFiveModel'\n\nexport type State = 'watching' | 'editing'\n\nexport default class MixedController extends BaseController {\n public state: State = 'watching'\n public polyline: Polyline\n private hasAppendDashed = false\n private mobileStartPoint: Point | null = null\n private mobileNowPoint: Point | null = null\n private highlightedLines: Line[] = []\n private deleteDom: DeleteDom\n private rangePieceController: RangePieceController\n private disposers: Function[] = []\n\n public constructor(params: ControllerParams) {\n super(params)\n this.model = new Model(this.config)\n this.polyline = new Polyline({ model: this.model })\n this.rangePieceController = new RangePieceController(params)\n this.deleteDom = new DeleteDom(this.five, {\n i18n: this.config.i18n,\n onClick: this.deleteDomClickCallback,\n cancel: this.cancelDeleteClickCallback,\n }).appendTo(this.container)\n // ==================== 事件监听 ====================\n // five\n this.five.on('cameraUpdate', this.onCameraUpdate)\n this.five.on('wantsTapGesture', this.onWantsTapGesture)\n this.five.on('wantsToMoveToPano', this.onWantsToMoveToPano)\n // five effect\n this.five.helperVisible = false\n // ==================== 触发事件 ====================\n this.hook.emit('editedDashedLineChange', null)\n // ==================== 其他 ====================\n this.hook.on('getStartPoint', this.onGetStartPoint)\n this.hook.on('getEndPoint', this.onGetEndPoint)\n this.hook.on('nowPointChange', this.onNowPointChange)\n this.hook.on('willChangeState', this.onWillChangeState)\n this.five.refresh()\n }\n\n public dispose() {\n super.dispose()\n this.disposers.forEach((disposer) => disposer())\n // five effect\n this.five.helperVisible = true\n this.rangePieceController.dispose()\n this.deleteDom.dispose()\n this.group.remove(this.mouseGroup)\n this.dashed.remove()\n this.perpendicularDashed.remove()\n // ==================== 解除事件监听 ====================\n // five\n this.five.off('cameraUpdate', this.onCameraUpdate)\n this.five.off('wantsTapGesture', this.onWantsTapGesture)\n this.five.off('wantsToMoveToPano', this.onWantsToMoveToPano)\n\n this.hook.off('getStartPoint', this.onGetStartPoint)\n this.hook.off('getEndPoint', this.onGetEndPoint)\n this.hook.off('nowPointChange', this.onNowPointChange)\n this.hook.off('willChangeState', this.onWillChangeState)\n this.hook.emit('selectedChange', [])\n this.five.needsRender = true\n }\n\n public highlightLine(line: Line) {\n if (line.selected) return\n line.selected = true\n this.group.add(line.lightMesh)\n line.distanceItem.highlight()\n this.five.needsRender = true\n }\n\n public clearHighlightLines() {\n if (this.group.children.length === 0) return\n this.deleteDom.setLines([]).hide()\n this.model.getAllLines().forEach((line) => {\n line.selected = false\n line.distanceItem.unHighlight()\n this.group.remove(line.lightMesh)\n })\n this.highlightedLines = []\n this.five.needsRender = true\n }\n\n public getEditingLines() {\n return this.model.polylines\n }\n\n private onWantsTapGesture: EventCallback['wantsTapGesture'] = (raycaster) => {\n if (this.state === 'editing') return false\n const model = getFiveModel(this.five)\n\n const [target] = model.intersectRaycaster(raycaster)\n if (!target) return\n const camera = this.five.camera\n const ndcTarget = target.point.clone().project(camera)\n const screenWidth = this.container.clientWidth\n const screenHeight = this.container.clientHeight\n const targetScreenPosition = new Vector2(ndcTarget.x * screenWidth, ndcTarget.y * screenHeight)\n // 把线的端点全部映射到屏幕上,过滤掉不在视野内的线,同时乘以屏幕宽 & 高\n const screenLines = this.model\n .getAllLines()\n .map((line) => {\n const [startPoint, endPoint] = line.points\n const ndcStartPoint = startPoint.position.clone().project(camera)\n const ndcEndPoint = endPoint.position.clone().project(camera)\n if (!isNDCPointInScreen(ndcStartPoint) && !isNDCPointInScreen(ndcEndPoint)) return null\n const startScreenPosition = new Vector2(ndcStartPoint.x * screenWidth, ndcStartPoint.y * screenHeight)\n const endScreenPosition = new Vector2(ndcEndPoint.x * screenWidth, ndcEndPoint.y * screenHeight)\n return { id: line.id, points: [startScreenPosition, endScreenPosition] }\n })\n .filter((line) => !!line) as { id: string; points: Vector2[] }[]\n if (screenLines.length === 0) return\n // 找这些线距离鼠标点击位置最近的线\n const distanceLines = screenLines\n .map((line) => {\n const closestPoint = closestPointOnLine(targetScreenPosition, line.points)\n return { id: line.id, distance: closestPoint.distanceTo(targetScreenPosition) }\n })\n .sort((a, b) => a.distance - b.distance)\n const closestScreenLine = distanceLines[0]\n if (closestScreenLine.distance > 20) return\n const closestLine = this.model.getAllLines().find(({ id }) => id === closestScreenLine.id)\n if (!closestLine) return\n this.chooseLine(closestLine)\n return false\n }\n\n /** 编辑时取消走点,watch时可以走 */\n private onWantsToMoveToPano = () => this.state === 'watching'\n\n /** 移动全景时更新 distanceItem 在屏幕上的位置 */\n private onCameraUpdate = () => {\n this.updateDistanceUI()\n this.dashed.distanceItem.update(this.five)\n }\n\n /** mobile态时更新虚线 */\n private updateMobileDashed = () => {\n if (!this.mobileStartPoint || !this.mobileNowPoint) return\n this.dashed.setPoints(this.mobileStartPoint.position, this.mobileNowPoint.position)\n this.dashed.distanceItem.update(this.five)\n this.hook.emit('editedDashedLineChange', this.dashed)\n }\n\n /** mobile态时更新放大镜 */\n private updateMagnifier = (point: Point) => {\n if (this.magnifier.containerDom !== this.container) {\n this.magnifier.appendTo(this.container)\n }\n if (!this.magnifier.state.enabled) {\n this.magnifier.enable()\n }\n requestAnimationFrame(() => this.magnifier.renderWithPoint(point.position))\n this.five.needsRender = true\n }\n\n private onGetStartPoint = (point) => {\n this.mobileStartPoint = point\n this.polyline = new Polyline({ model: this.model })\n this.polyline.hook.on('lineAdded', () => this.hook.emit('editedPolylineChange', this.polyline))\n this.polyline.hook.on('lineRemoved', () => this.hook.emit('editedPolylineChange', this.polyline))\n }\n\n private onGetEndPoint = () => {\n const endPoint = this.mobileNowPoint\n\n this.removeLine(this.dashed)\n this.hasAppendDashed = false\n\n if (this.mobileStartPoint && endPoint) {\n const line = new Line(this.mobileStartPoint, endPoint, this.model)\n this.polyline.addLine(line)\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n line.hook.on('selected', this.chooseLine)\n this.disposers.push(() => line.hook.off('selected', this.chooseLine))\n this.group.add(line.mesh)\n this.model.addPolyline(this.polyline)\n }\n\n this.mobileStartPoint = null\n this.mobileNowPoint = null\n\n this.five.needsRender = true\n }\n\n private onNowPointChange = (point) => {\n if (this.state === 'watching') {\n this.mobileNowPoint = point\n this.updateMagnifier(point)\n return\n }\n\n if (!this.hasAppendDashed) {\n this.dashed.distanceItem.appendTo(this.container)\n this.group.add(this.dashed.mesh)\n this.hasAppendDashed = true\n }\n\n this.five.needsRender = true\n this.mobileNowPoint = point\n this.updateMobileDashed()\n this.updateMagnifier(point)\n this.five.needsRender = true\n }\n\n private onWillChangeState = (state, newState) => {\n this.state = newState\n if (this.state === 'watching') {\n this.five.helperVisible = true\n } else {\n // 隐藏点位和鼠标聚焦环\n this.five.helperVisible = false\n }\n }\n\n private chooseLine = (line: Line) => {\n const highlightLines = line.getPolyline().lines\n this.highlightLines(highlightLines)\n this.five.needsRender = true\n this.hook.emit(\n 'selectedChange',\n highlightLines.map((line) => line),\n )\n }\n\n private highlightLines(lines: Line[]) {\n this.clearHighlightLines()\n this.highlightedLines = lines\n this.deleteDom.setLines(lines).updatePosition().show()\n lines.forEach((line) => this.highlightLine(line))\n }\n\n private deleteDomClickCallback = () => {\n this.highlightedLines.forEach((line) => {\n this.removeLine(line)\n const polyline = this.model.getPolylineByLine(line)\n this.model.removePolyline(polyline)\n })\n this.highlightedLines = []\n this.deleteDom.setLines([]).hide()\n }\n\n private cancelDeleteClickCallback = () => {\n this.clearHighlightLines()\n }\n}\n","export const startIconImage = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzIiIGhlaWdodD0iNzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxmaWx0ZXIgeD0iLTUuMyUiIHk9Ii01LjMlIiB3aWR0aD0iMTEwLjUlIiBoZWlnaHQ9IjExMC41JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0icHJlZml4X19hIj48ZmVPZmZzZXQgaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9InNoYWRvd09mZnNldE91dGVyMSIvPjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSIvPjxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93Qmx1ck91dGVyMSIgaW4yPSJTb3VyY2VBbHBoYSIgb3BlcmF0b3I9Im91dCIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDEgMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwLjUgMCIgaW49InNoYWRvd0JsdXJPdXRlcjEiLz48L2ZpbHRlcj48ZmlsdGVyIHg9Ii0xMS40JSIgeT0iLTExLjQlIiB3aWR0aD0iMTIyLjklIiBoZWlnaHQ9IjEyMi45JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0icHJlZml4X19jIj48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI0LjUiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dCbHVySW5uZXIxIi8+PGZlT2Zmc2V0IGluPSJzaGFkb3dCbHVySW5uZXIxIiByZXN1bHQ9InNoYWRvd09mZnNldElubmVyMSIvPjxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93T2Zmc2V0SW5uZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0iYXJpdGhtZXRpYyIgazI9Ii0xIiBrMz0iMSIgcmVzdWx0PSJzaGFkb3dJbm5lcklubmVyMSIvPjxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwIDEgMCAwIDAgMC4zIDAiIGluPSJzaGFkb3dJbm5lcklubmVyMSIvPjwvZmlsdGVyPjxmaWx0ZXIgeD0iLTEyNi42JSIgeT0iLTMzNy41JSIgd2lkdGg9IjM1My4xJSIgaGVpZ2h0PSI3NzUlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJwcmVmaXhfX2UiPjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjE2IiBpbj0iU291cmNlR3JhcGhpYyIvPjwvZmlsdGVyPjxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMTAwJSIgeDI9IjUwJSIgeTI9IjAlIiBpZD0icHJlZml4X19kIj48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9Ii43IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjI2LjQzMiUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iODIuMzA1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iLjQiIG9mZnNldD0iMTAwJSIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IHgxPSI1MCUiIHkxPSIwJSIgeDI9IjUwJSIgeTI9IjEwMCUiIGlkPSJwcmVmaXhfX2YiPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iLjA1IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIuMiIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48Y2lyY2xlIGlkPSJwcmVmaXhfX2IiIGN4PSIzNiIgY3k9IjM2IiByPSIyOC40NDQiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNwcmVmaXhfX2EpIiB4bGluazpocmVmPSIjcHJlZml4X19iIi8+PHVzZSBmaWxsPSIjMDAwIiBmaWx0ZXI9InVybCgjcHJlZml4X19jKSIgeGxpbms6aHJlZj0iI3ByZWZpeF9fYiIvPjxjaXJjbGUgc3Ryb2tlPSJ1cmwoI3ByZWZpeF9fZCkiIHN0cm9rZS13aWR0aD0iLjQiIGZpbGwtb3BhY2l0eT0iLjI0MSIgZmlsbD0iI0ZGRiIgc3Ryb2tlLWxpbmVqb2luPSJzcXVhcmUiIGN4PSIzNiIgY3k9IjM2IiByPSIyOC4yNDQiLz48ZWxsaXBzZSBmaWxsPSIjRkZGIiBvcGFjaXR5PSIuNTk2IiBmaWx0ZXI9InVybCgjcHJlZml4X19lKSIgY3g9IjM2IiBjeT0iMzYiIHJ4PSIxOC45NjMiIHJ5PSI3LjExMSIvPjxwYXRoIGQ9Ik0zNiAwQzE2LjExOCAwIDAgMTYuMTE4IDAgMzZzMTYuMTE4IDM2IDM2IDM2IDM2LTE2LjExOCAzNi0zNlM1NS44ODIgMCAzNiAwem0wIDQuNDQ0YzE3LjQyOCAwIDMxLjU1NiAxNC4xMjggMzEuNTU2IDMxLjU1NlM1My40MjggNjcuNTU2IDM2IDY3LjU1NiA0LjQ0NCA1My40MjggNC40NDQgMzYgMTguNTcyIDQuNDQ0IDM2IDQuNDQ0eiIgZmlsbD0idXJsKCNwcmVmaXhfX2YpIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48L2c+PC9zdmc+`\nexport const endIconImage = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzIiIGhlaWdodD0iNzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IHgxPSIxNS41MSUiIHkxPSIxMi40OTclIiB4Mj0iODUuMjY1JSIgeTI9Ijg2LjE0MyUiIGlkPSJwcmVmaXhfX2IiPjxzdG9wIHN0b3AtY29sb3I9IiM5NUFFRkYiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjNjM4NkZGIiBvZmZzZXQ9IjEwMCUiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMTAwJSIgeDI9IjUwJSIgeTI9IjAlIiBpZD0icHJlZml4X19hIj48c3RvcCBzdG9wLWNvbG9yPSIjOTlBRUZGIiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjI2LjQzMiUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iODIuMzA1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiM5OUFFRkYiIHN0b3Atb3BhY2l0eT0iLjQiIG9mZnNldD0iMTAwJSIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IHgxPSI1MCUiIHkxPSIwJSIgeDI9IjUwJSIgeTI9IjEwMCUiIGlkPSJwcmVmaXhfX2QiPjxzdG9wIHN0b3AtY29sb3I9IiM4Nzk3RDIiIHN0b3Atb3BhY2l0eT0iLjA1IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iIzYyNzdDNyIgc3RvcC1vcGFjaXR5PSIuMiIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48ZmlsdGVyIHg9Ii02My4zJSIgeT0iLTE2OC44JSIgd2lkdGg9IjIyNi42JSIgaGVpZ2h0PSI0MzcuNSUiIGZpbHRlclVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgaWQ9InByZWZpeF9fYyI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iOCIgaW49IlNvdXJjZUdyYXBoaWMiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48Y2lyY2xlIHN0cm9rZT0idXJsKCNwcmVmaXhfX2EpIiBzdHJva2Utd2lkdGg9Ii40IiBmaWxsPSJ1cmwoI3ByZWZpeF9fYikiIG9wYWNpdHk9Ii43IiBjeD0iMzYiIGN5PSIzNiIgcj0iMjguMjQ0Ii8+PGVsbGlwc2UgZmlsbD0iIzdDOTBEQSIgb3BhY2l0eT0iLjU5NiIgZmlsdGVyPSJ1cmwoI3ByZWZpeF9fYykiIGN4PSIzNiIgY3k9IjM2IiByeD0iMTguOTYzIiByeT0iNy4xMTEiLz48cGF0aCBkPSJNMzYgMEMxNi4xMTggMCAwIDE2LjExOCAwIDM2czE2LjExOCAzNiAzNiAzNiAzNi0xNi4xMTggMzYtMzZTNTUuODgyIDAgMzYgMHptMCA0LjQ0NGMxNy40MjggMCAzMS41NTYgMTQuMTI4IDMxLjU1NiAzMS41NTZTNTMuNDI4IDY3LjU1NiAzNiA2Ny41NTYgNC40NDQgNTMuNDI4IDQuNDQ0IDM2IDE4LjU3MiA0LjQ0NCAzNiA0LjQ0NHoiIGZpbGw9InVybCgjcHJlZml4X19kKSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9nPjwvc3ZnPg==`\n\nconst exitIconSvg = `\n <svg class=\"fpm__exit-icon width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <radialGradient cx=\"50%\" cy=\"50%\" fx=\"50%\" fy=\"50%\" r=\"86.3016741%\" id=\"radialGradient-1\">\n <stop stop-color=\"#FFFFFF\" offset=\"0%\"></stop>\n <stop stop-color=\"#FFFFFF\" stop-opacity=\"0.3\" offset=\"100%\"></stop>\n </radialGradient>\n <radialGradient cx=\"50%\" cy=\"50%\" fx=\"50%\" fy=\"50%\" r=\"70.7106781%\" id=\"radialGradient-2\">\n <stop stop-color=\"#FFFFFF\" offset=\"0%\"></stop>\n <stop stop-color=\"#FFFFFF\" stop-opacity=\"0\" offset=\"100%\"></stop>\n </radialGradient>\n </defs>\n <g fill=\"url(#radialGradient-1)\" fill-rule=\"nonzero\" stroke=\"url(#radialGradient-2)\" stroke-width=\"0.2\">\n <path d=\"M19.1859205,4.10000004 C19.3691554,4.09993923 19.5526088,4.16602323 19.6925352,4.29904206 C19.8171021,4.41745965 19.8858582,4.56899486 19.8980316,4.7239943 C19.9103475,4.88080848 19.8647874,5.04088037 19.7661957,5.16777131 L19.7661957,5.16777131 L14.3769795,11.1697063 C14.1649599,11.4058657 14.0589501,11.7029328 14.0589501,12 C14.0589501,12.2970672 14.1649599,12.5941343 14.3769795,12.8302937 L14.3769795,12.8302937 L19.6928862,18.7509889 C19.8173649,18.8694879 19.8860087,19.0210672 19.8980683,19.1760728 C19.9102693,19.3328965 19.8645908,19.4929392 19.7701664,19.6153111 C19.6099275,19.772809 19.4324896,19.8610254 19.2586274,19.8856752 C19.0810547,19.910851 18.9081905,19.8692156 18.765363,19.7704965 L18.765363,19.7704965 L11.9999322,13.2904645 L5.32508998,19.6962598 C5.16077108,19.8156635 4.99335965,19.8785989 4.83451361,19.8898888 C4.67442082,19.9012674 4.52389835,19.8596921 4.3968979,19.7731206 C4.23619359,19.588506 4.14871527,19.4164558 4.12392544,19.2589757 C4.09801173,19.094356 4.14341261,18.9485987 4.23380428,18.8322287 L4.23380428,18.8322287 L9.62302046,12.8302937 C9.81773049,12.6134147 9.92302682,12.3451662 9.93892926,12.0727274 C9.95499717,11.7974536 9.87975312,11.5179151 9.70614397,11.2737767 L9.70614397,11.2737767 L4.31595492,5.25860214 C4.17860663,5.08857057 4.11166276,4.9104714 4.11172409,4.7432513 C4.11178577,4.57506821 4.18051603,4.41972395 4.30746483,4.29904206 C4.43371817,4.17902131 4.59543385,4.11349344 4.76041858,4.10187732 L4.76041858,4.10187732 L12.0000677,10.7085251 L18.6794563,4.29937602 C18.8192839,4.16626546 19.0026873,4.10006086 19.1859205,4.10000004 Z\" id=\"形状结合\"></path>\n </g>\n </svg>\n`\n\nexport default `\n <style>\n .mobile .fpm__exit {\n position: absolute;\n top: 53px;\n left: 16px;\n width: 24px;\n height: 24px;\n z-index: 10;\n pointer-events: all;\n }\n .mobile .fpm__exit-icon {\n width: 100%;\n height: 100%;\n cursor: pointer;\n }\n .fpm_operating--mobile {\n padding-bottom: 23px;\n }\n .fpm__main-btn {\n display: flex;\n justify-content: center;\n align-items: center;\n margin: 0 !important;\n }\n .fpm__main-btn-text {\n position: absolute;\n font-weight: 500;\n font-size: 14px;\n color: #FFFFFF;\n text-align: center;\n text-shadow: 0 2px 8px rgba(0,0,0,0.50);\n transition: all 200ms ease-in-out;\n }\n .fpm__main-text__hide {\n transform: scale(0.8) translateY(4px);\n opacity: 0;\n }\n .fpm__main-text__show {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n .fpm__main__start {\n background-image: url(${startIconImage});\n }\n .fpm__main__end {\n background-image: url(${endIconImage});\n }\n\n </style>\n <div class=\"fpm__exit\">\n ${exitIconSvg}\n </div>\n <div class=\"fpm_ui-bg\"></div>\n <div class=\"fpm_operating-space fpm_operating--mobile\">\n <div class=\"fpm__main fpm__main-btn\">\n <div class=\"fpm__main-icon fpm__main__start\"></div>\n <div class=\"fpm__text fpm__main-text fpm__main-btn-text\"></div>\n </div>\n </div>\n`\n","import { endIconImage, startIconImage } from './mobileHTML'\n\nconst revokeSvg = `\n <svg class=\"fpm__revoke-icon\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient x1=\"47.631%\" y1=\"55.183%\" x2=\"2.967%\" y2=\"86.323%\" id=\"fpm__revoke-a\">\n <stop stop-color=\"#FFF\" offset=\"0%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\".5\" offset=\"100%\" />\n </linearGradient>\n <linearGradient x1=\"5.297%\" y1=\"43.016%\" x2=\"38.238%\" y2=\"79.932%\" id=\"fpm__revoke-b\">\n <stop stop-color=\"#FFF\" offset=\"0%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\"0\" offset=\"100%\" />\n </linearGradient>\n </defs>\n <path\n d=\"M13.388 7.108c.552 0 1.005.42 1.06.957l.006.11v1.224c0 .921.745 1.667 1.666 1.667h7.184c5.804 0 10.509 4.616 10.509 10.309 0 5.595-4.544 10.15-10.21 10.305l-.3.004H8.924c-.917 0-1.66-.729-1.66-1.628 0-.846.658-1.541 1.5-1.62l.16-.008h14.38c3.972 0 7.191-3.158 7.191-7.053 0-3.81-3.08-6.916-6.933-7.049l-.257-.004H10.029l-.109-.005H8.212c-.245 0-.482-.085-.67-.237l-.09-.082a1.066 1.066 0 0 1-.065-1.422l.079-.086 5.175-5.077c.2-.195.468-.305.747-.305z\"\n fill=\"url(#fpm__revoke-a)\"\n fill-rule=\"nonzero\"\n stroke=\"url(#fpm__revoke-b)\"\n stroke-width=\".5\"\n />\n </svg>\n`\nconst exitSvg = `\n <svg class=\"fpm__exit-icon width=\"40\" height=\"40\" viewBox=\"0 0 40 40\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient x1=\"36.288%\" y1=\"73.736%\" x2=\"54.242%\" y2=\"97.166%\" id=\"fpm__exit-a\">\n <stop stop-color=\"#FFF\" offset=\"0%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\".5\" offset=\"100%\" />\n </linearGradient>\n <linearGradient x1=\"100%\" y1=\"47.234%\" x2=\"24.047%\" y2=\"47.234%\" id=\"fpm__exit-b\">\n <stop stop-color=\"#FFF\" offset=\"0%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\".005\" offset=\"99.535%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\"0\" offset=\"100%\" />\n </linearGradient>\n </defs>\n <path\n d=\"M22 7a1.5 1.5 0 0 1 .144 2.993L22 10h-9a1.5 1.5 0 0 0-1.493 1.356l-.007.144v17a1.5 1.5 0 0 0 1.356 1.493L13 30h9a1.5 1.5 0 0 1 .144 2.993L22 33h-9a4.5 4.5 0 0 1-4.495-4.288L8.5 28.5v-17a4.5 4.5 0 0 1 4.288-4.495L13 7h9zm6.317 7.755a1 1 0 0 1 .7.286l4.856 4.764a1 1 0 0 1-.7 1.713h-5.856V21.5h-8.032a1.5 1.5 0 1 1 0-3h6.365c.92 0 1.666-.746 1.667-1.667v-1.078a1 1 0 0 1 1-1z\"\n fill=\"url(#fpm__exit-a)\"\n fill-rule=\"nonzero\"\n stroke=\"url(#fpm__exit-b)\"\n stroke-width=\".5\"\n />\n </svg>\n`\n\nexport default `\n <style>\n .fpm__other-btn {\n height: 40px;\n width: 88px;\n background: rgba(0, 0, 0, 0.15);\n border-radius: 20px;\n overflow: hidden; \n }\n\n .fpm__other-content {\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .fpm__revoke {\n opacity: 0.3;\n } \n .fpm__revoke.enabled {\n opacity: 0.85;\n } \n .fpm__revoke.enabled:hover {\n opacity: 1;\n }\n \n .fpm__revoke-icon {\n width: 24px;\n height: 24px;\n margin-right: 4px;\n cursor: pointer;\n }\n \n .fpm__main-btn {\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .fpm__main-btn-text {\n position: absolute;\n font-weight: 500;\n font-size: 14px;\n color: #FFFFFF;\n text-align: center;\n text-shadow: 0 2px 8px rgba(0,0,0,0.50);\n transition: all 200ms ease-in-out;\n }\n .fpm__main-text__hide {\n transform: scale(0.8) translateY(4px);\n opacity: 0;\n }\n .fpm__main-text__show {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n .fpm__main__start {\n background-image: url(${startIconImage});\n }\n .fpm__main__end {\n background-image: url(${endIconImage});\n }\n \n </style>\n <div class=\"fpm_ui-bg\"></div>\n <div class=\"fpm_operating-space\">\n <div class=\"fpm__other-btn\">\n <div class=\"fpm__other-content fpm__revoke\">\n ${revokeSvg}\n <span class=\"fpm__text fpm__revoke-text\"></span>\n </div>\n </div>\n <div class=\"fpm__main fpm__main-btn\">\n <div class=\"fpm__main-icon fpm__main__start\"></div>\n <div class=\"fpm__text fpm__main-text fpm__main-btn-text\"></div>\n </div>\n <div class=\"fpm__other-btn\">\n <div class=\"fpm__other-content fpm__exit\">\n ${exitSvg}\n <span class=\"fpm__text fpm__exit-text\"></span>\n </div>\n </div>\n </div>\n`\n","export const uiWrapperStyle: Partial<CSSStyleDeclaration> = {\n display: 'none',\n position: 'absolute',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n opacity: '0',\n transform: 'translate(0, 10px)',\n transition: 'opacity 500ms ease-in-out, transform 500ms ease-in-out',\n}\n\nexport const operatingSpaceStyle: Partial<CSSStyleDeclaration> = {\n position: 'absolute',\n left: '50%',\n bottom: '32px',\n transform: 'translateX(-50%)',\n height: '89px',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n fontSize: '14px',\n pointerEvents: 'all',\n color: '#fff',\n zIndex: '10',\n}\n\n// 操作区下方的背景\nexport const controllerBackgroundStyle: Partial<CSSStyleDeclaration> = {\n position: 'absolute',\n bottom: '0',\n left: '0',\n opacity: '0.5',\n width: '100%',\n height: '184px',\n background: `linear-gradient(180deg, rgba(0,0,0,0.00) 0%, #000000 100%)`,\n zIndex: '0',\n}\n\n// item\nexport const mainItemStyle: Partial<CSSStyleDeclaration> = {\n margin: '0 64px',\n}\n\nexport const exitItemStyle: Partial<CSSStyleDeclaration> = {\n opacity: '0.85',\n}\n\n// icon\nexport const mainIconStyle: Partial<CSSStyleDeclaration> = {\n width: '72px',\n height: '72px',\n backgroundSize: '100%',\n cursor: 'pointer',\n transition: 'all 200ms ease-in-out',\n}\nexport const exitIconStyle: Partial<CSSStyleDeclaration> = {\n width: '24px',\n height: '24px',\n marginRight: '4px',\n backgroundSize: '100%',\n cursor: 'pointer',\n}\n\n// text\nexport const textStyle: Partial<CSSStyleDeclaration> = {\n userSelect: 'none',\n pointerEvents: 'none',\n}\n","import type { UIControllerParams } from '.'\nimport type MeasureController from '../../Controller'\nimport type { PanoMeasurePluginEvent } from '../../typings/event.type'\nimport { mainIconStyle, mainItemStyle } from './style'\nexport class MainBtnController {\n private container: Element\n private measureController: MeasureController\n private mainElement: ReturnType<MainBtnController['getMainElement']>\n private _params: UIControllerParams\n\n private _btnTexts = {\n start: '开始',\n end: '结束',\n revoke: '撤销',\n exit: '退出',\n }\n\n public constructor(measureController: MeasureController, container: Element, params: UIControllerParams) {\n this._params = params\n\n this._btnTexts = {\n start: this._params.startButtonText ?? this._btnTexts.start,\n end: this._params.endButtonText ?? this._btnTexts.end,\n revoke: this._params.revokeButtonText ?? this._btnTexts.revoke,\n exit: this._params.exitButtonText ?? this._btnTexts.exit,\n }\n\n this.measureController = measureController\n this.container = container\n this.mainElement = this.getMainElement()\n\n Object.assign(this.mainElement.mainIcon.style, mainIconStyle)\n Object.assign(this.mainElement.mainItem.style, mainItemStyle)\n\n const { revokeTextDom, exitTextDom } = this._getTextElement()\n if (revokeTextDom) {\n revokeTextDom.innerText = this._btnTexts.revoke\n }\n if (exitTextDom) {\n exitTextDom.innerText = this._btnTexts.exit\n }\n\n this.change2Add()\n\n this.measureController.hooks.on('modeChange', this.modeChangeHandler)\n this.mainElement.mainItem.addEventListener('click', this.onClick)\n this.mainElement.mainItem.addEventListener('mouseenter', this.onMouseEnter)\n this.mainElement.mainItem.addEventListener('mouseleave', this.onMouseLeave)\n }\n\n public dispose() {\n this.measureController.hooks.off('modeChange', this.modeChangeHandler)\n this.mainElement.mainItem.removeEventListener('click', this.onClick)\n this.mainElement.mainItem.removeEventListener('mouseenter', this.onMouseEnter)\n this.mainElement.mainItem.removeEventListener('mouseleave', this.onMouseLeave)\n }\n\n private getMainElement() {\n const mainTextDom = this.container.querySelector<HTMLSpanElement>('.fpm__main-text')\n const mainItem = this.container.querySelector<HTMLButtonElement>('.fpm__main')\n const mainIcon = this.container.querySelector<HTMLElement>('.fpm__main-icon')\n if (!mainItem || !mainTextDom || !mainIcon) throw new Error('cannot find dom')\n\n return { mainTextDom, mainItem, mainIcon }\n }\n\n private _getTextElement() {\n const revokeTextDom = this.container.querySelector<HTMLSpanElement>('.fpm__revoke-text')\n const exitTextDom = this.container.querySelector<HTMLSpanElement>('.fpm__exit-text')\n return { revokeTextDom, exitTextDom }\n }\n\n private change2Add() {\n const { mainIcon, mainTextDom } = this.mainElement\n if (mainIcon.className.includes('fpm__main__start')) {\n mainTextDom.innerText = this._btnTexts.start\n return\n }\n if (mainIcon.className.includes('fpm__main__end')) {\n mainIcon.style.transform = `scale(0.8)`\n if (mainTextDom.className.includes('fpm__main-text__show')) {\n mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide')\n } else {\n mainTextDom.classList.add('fpm__main-text__hide')\n }\n setTimeout(() => {\n mainIcon.classList.replace('fpm__main__end', 'fpm__main__start')\n mainIcon.style.transform = 'scale(1)'\n mainTextDom.innerText = this._btnTexts.start\n mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show')\n }, 200)\n }\n }\n\n private change2Done() {\n const { mainTextDom, mainIcon } = this.getMainElement()\n if (mainTextDom.innerText === this._btnTexts.end) return\n if (mainIcon.className.includes('fpm__main__end')) return\n if (mainIcon.className.includes('fpm__main__start')) {\n mainIcon.style.transform = `scale(0.8)`\n if (mainTextDom.className.includes('fpm__main-text__show')) {\n mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide')\n } else {\n mainTextDom.classList.add('fpm__main-text__hide')\n }\n setTimeout(() => {\n mainIcon.classList.replace('fpm__main__start', 'fpm__main__end')\n mainIcon.style.transform = 'scale(1)'\n mainTextDom.innerText = this._btnTexts.end\n mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show')\n }, 200)\n }\n }\n\n /* 鼠标移入时 */\n private onMouseEnter = () => {\n const { mainItem } = this.mainElement\n mainItem.style.opacity = '1'\n }\n\n /* 鼠标移出时 */\n private onMouseLeave = () => {\n const { mainItem } = this.mainElement\n mainItem.style.opacity = '0.85'\n }\n\n private onClick = () => {\n const mode = this.measureController.getCurrentMode()\n if (mode !== 'Edit') {\n this.measureController.changeMode('Edit')\n } else {\n this.measureController.save().changeMode('Watch')\n }\n }\n\n private modeChangeHandler: PanoMeasurePluginEvent['modeChange'] = (mode) => {\n mode === 'Edit' ? this.change2Done() : this.change2Add()\n }\n}\n","import type { UIControllerParams } from '.'\nimport type MeasureController from '../../Controller'\nimport { mainIconStyle, mainItemStyle } from './style'\n\nexport class MobileMainBtnController {\n private container: Element\n private measureController: MeasureController\n private mainElement: ReturnType<MobileMainBtnController['getMainElement']>\n private _params: UIControllerParams\n\n private _btnTexts = {\n start: '开始',\n end: '结束',\n }\n\n public constructor(measureController: MeasureController, container: Element, params: UIControllerParams) {\n this._params = params\n\n this._btnTexts = {\n start: this._params.startButtonText ?? this._btnTexts.start,\n end: this._params.endButtonText ?? this._btnTexts.end,\n }\n\n this.measureController = measureController\n this.container = container\n this.mainElement = this.getMainElement()\n\n this.mainElement.mainIcon.setAttribute('style', `-webkit-tap-highlight-color: rgba(0,0,0,0);`)\n Object.assign(this.mainElement.mainIcon.style, mainIconStyle)\n Object.assign(this.mainElement.mainItem.style, mainItemStyle)\n this.change2Add()\n\n this.mainElement.mainItem.addEventListener('click', this.onClick)\n }\n\n public dispose() {\n this.mainElement.mainItem.removeEventListener('click', this.onClick)\n }\n\n private getMainElement() {\n const mainTextDom = this.container.querySelector<HTMLSpanElement>('.fpm__main-text')\n const mainItem = this.container.querySelector<HTMLButtonElement>('.fpm__main')\n const mainIcon = this.container.querySelector<HTMLElement>('.fpm__main-icon')\n if (!mainItem || !mainTextDom || !mainIcon) throw new Error('cannot find dom')\n\n return { mainTextDom, mainItem, mainIcon }\n }\n\n private change2Add() {\n const { mainIcon, mainTextDom } = this.mainElement\n if (mainIcon.className.includes('fpm__main__start')) {\n mainTextDom.innerText = this._btnTexts.start\n return\n }\n if (mainIcon.className.includes('fpm__main__end')) {\n mainIcon.style.transform = `scale(0.8)`\n if (mainTextDom.className.includes('fpm__main-text__show')) {\n mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide')\n } else {\n mainTextDom.classList.add('fpm__main-text__hide')\n }\n setTimeout(() => {\n mainIcon.classList.replace('fpm__main__end', 'fpm__main__start')\n mainIcon.style.transform = 'scale(1)'\n mainTextDom.innerText = this._btnTexts.start\n mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show')\n }, 200)\n }\n }\n\n private change2Done() {\n const { mainTextDom, mainIcon } = this.mainElement\n if (mainTextDom.innerText === this._btnTexts.end) return\n if (mainIcon.className.includes('fpm__main__end')) return\n if (mainIcon.className.includes('fpm__main__start')) {\n mainIcon.style.transform = `scale(0.8)`\n if (mainTextDom.className.includes('fpm__main-text__show')) {\n mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide')\n } else {\n mainTextDom.classList.add('fpm__main-text__hide')\n }\n setTimeout(() => {\n mainIcon.classList.replace('fpm__main__start', 'fpm__main__end')\n mainIcon.style.transform = 'scale(1)'\n mainTextDom.innerText = this._btnTexts.end\n mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show')\n }, 200)\n }\n }\n\n private onClick = () => {\n if (this.mainElement.mainTextDom.innerText === (this._params.startButtonText ?? '开始')) {\n this.measureController.hooks.emit('willChangeState', 'watching', 'editing')\n this.change2Done()\n } else {\n this.measureController.hooks.emit('willChangeState', 'editing', 'watching')\n this.change2Add()\n }\n }\n}\n","import type { Vector3 } from 'three/webgpu'\nimport type { Mode } from '../../../Controller'\nimport type MeasureController from '../../../Controller'\n\nexport default class Revoke {\n private container: Element\n private revokeIcon: HTMLElement\n private revokeItem: HTMLDivElement\n private measureController: MeasureController\n\n public constructor(measureController: MeasureController, container: Element) {\n this.measureController = measureController\n this.container = container\n\n const revokeIcon = this.container.querySelector<HTMLElement>('.fpm__revoke-icon')\n const revokeItem = this.container.querySelector<HTMLDivElement>('.fpm__revoke')\n if (!revokeIcon || !revokeItem) throw new Error('不正确的选择器')\n this.revokeIcon = revokeIcon\n this.revokeItem = revokeItem\n this.revokeItem.addEventListener('click', this.onClick)\n measureController.hooks.on('modeChange', this.onModeChange)\n }\n\n public dispose() {\n this.revokeItem.removeEventListener('click', this.onClick)\n this.measureController.hooks.off('modeChange', this.onModeChange)\n }\n\n private onClick = () => {\n this.measureController.revoke()\n }\n\n private onModeChange = (mode: Mode) => {\n if (mode !== 'Edit' && this.revokeItem.className.includes('enabled')) {\n this.revokeItem.classList.remove('enabled')\n this.measureController.hooks.off('anchorChange', this.onAnchorChange)\n return\n }\n this.measureController.hooks.on('anchorChange', this.onAnchorChange)\n }\n\n private onAnchorChange = (anchor: Vector3 | null) => {\n // 开始测量标记一个点后才能撤销\n anchor && this.revokeItem.classList.add('enabled')\n }\n}\n","<!--\n @component\n 一个滑动选择器,样式大概是这样\n\n ( ( 选中的选项1 ) 选项2 选项3 )\n -->\n<script lang=\"ts\" generics=\"T extends string\">\n // 要这么转换一下T应该是 svelte 的 language tools 的 bug,没时间查\n\n type K = T\n export const defaultIndex: number | null = null\n export const setIndex = (index: number | null) => {\n activeIndex = index\n }\n export let options: Array<{ key: K; value: string; icon?: string }>\n export let onChange: (key: K) => void\n\n const elementList: HTMLElement[] = []\n let container: HTMLElement\n let activeIndex: number | null = defaultIndex\n $: activeButton = elementList[activeIndex]\n\n // 用来控制滑块移动的\n let activeButtonWidth: number | undefined\n let activeButtonLeft: number | undefined\n $: {\n if (activeButton && container) {\n setTimeout(() => {\n activeButtonWidth = activeButton.clientWidth\n activeButtonLeft = activeButton.getBoundingClientRect().left - container.getBoundingClientRect().left\n }, 0)\n }\n }\n</script>\n\n<div class=\"Switcher\" bind:this={container}>\n <div class=\"Switcher-bg\" />\n {#if activeButton}\n <div class=\"active-slider\" style:width={activeButtonWidth + 'px'} style:transform={`translate(${activeButtonLeft}px, -50%)`} />\n {/if}\n <div class=\"Switcher-buttons\" class:has-divider={!activeButton}>\n {#each options as option, index}\n <!-- svelte-ignore a11y-click-events-have-key-events -->\n <div\n class=\"button\"\n class:active={activeIndex === index}\n bind:this={elementList[index]}\n on:click={() => {\n onChange(option.key)\n activeIndex = index\n }}\n >\n <div class=\"content\">\n {#if option.icon}\n <span class=\"icon\" style:background-image={`url(${option.icon})`} />\n {/if}\n {option.value}\n </div>\n </div>\n {/each}\n </div>\n</div>\n\n<style lang=\"scss\">\n .Switcher {\n position: relative;\n box-sizing: border-box;\n width: max-content;\n\n .content,\n .active-slider {\n transition-property: transform, width, opacity;\n transition-duration: 300ms;\n transition-timing-function: ease-out;\n }\n }\n\n .Switcher-bg {\n content: '';\n position: absolute;\n box-sizing: border-box;\n top: 50%;\n left: 0;\n width: 100%;\n height: 60px;\n transform: translateY(-50%);\n border-style: solid;\n border-width: 0px 30px;\n border-image: url('data:image/png;base64,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');\n border-image-slice: 0 90 fill;\n }\n\n .Switcher-buttons {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n padding: 0 3px;\n height: 100%;\n &.has-divider .button:not(:last-child)::after {\n content: '';\n position: absolute;\n right: 0;\n top: 10%;\n height: 80%;\n width: 1px;\n background-image: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.3), transparent);\n background-size: 100%;\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n\n .active-slider {\n box-sizing: border-box;\n position: absolute;\n height: 52px;\n top: 50%;\n transform: translate(0, -50%);\n border-style: solid;\n border-width: 0px 30px;\n border-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXQAAACcCAMAAABY3aA6AAAAhFBMVEX///////8AAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////88i7DIAAAALHRSTlNmawBvc3d6BAcZDid8NwyFja/XEhYkHTErIS41gpajnUyRVEE7XKpiRczDuH1q6FcAAA1mSURBVHja7Ndtk5owFAXg2KKtiiUdlTdBYH1Z//8vbC4SjkmuDlpmOht7AWfdLyaPZw4ovo06PzydcZX+Eh3QP99gXvsCRkbvsX91s/B29A41/rch9mOjq09twUl6TbNRM/d4aH9rmsWVfkDmx0XX4ORN1HGcZdlWzdLbod2pTcYx8St5Dc/7jIiOjGtw4lbSaZ4nSbJTs/J0aG9qi3meKn+i1/AM+/joWlyBk3eaJ7tj/RlEsiyr/fm3t3PeV2Upo+CzPu6SPFXyBM+4j4oO8k6cwI+nUFbdihopI49HyqbLVSXD05HgO3ejZsZDR5OrkHfiCnxWns9VKaNQzczzCa+vaiJZVudzOVPwnbuKO9RHRidyCnkrLqQCb6I73FNvhtsdyTcKXorWneIO9jHRf1zJ5/F2ma9O0X5fEriXzvfHgi/3++i0ypfbeA72EdF78jS5TKtW/J20efvWvZpekvRJdjH49rneEHld7CsZhhx44Pm48OQuq31RE/tmPfhJRgwzBzlC7mhPA2/hsTXYI+5gH/YgI4aWebZM6qhqil4c4P5ac/o0lntRVlGdLLOhHSMGxnyZH6Y9Od8n3z0fvm069qaaHvLlwLCLQTfQbbr7LEuD3NUOPD9c+1v2qCw/d+n2GvbX0RFzahbd5ZZ4z+190G/xLXfd7apjdNhfQof5PEtXk1K65AB3ZmJfX2bshbP47TDsspys0mwO9RfQ1YPiYh1v80PRFA656327dPui40uczsIxVurhDnYFdci38XqBh8cn0anOqVo+JMXcJg8c7W7V7sq/UNCZvOjDtmfYKezygyoGxf4celvnVC1N1Mdci2M099eSfWVu8cGu3fuwRw1VTFvsT6Kjzo+hLBBzM+Tv4+3g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');\n border-image-slice: 0 90 fill; // 90 随便写的,够大就行,懒得量了\n }\n\n .button {\n height: 56px;\n display: flex;\n position: relative;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n pointer-events: all;\n width: 116px;\n .content {\n position: absolute;\n display: flex;\n align-items: center;\n font-size: 16px;\n color: #fff;\n text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);\n font-weight: bold;\n .icon {\n display: inline-block;\n width: 18.5px;\n height: 18.5px;\n background-repeat: no-repeat;\n background-size: 100%;\n margin-right: 2px;\n }\n }\n\n // 动画\n &:not(.active) {\n .content {\n opacity: 0.65;\n transform: scale(0.875);\n &:hover {\n opacity: 0.85;\n }\n }\n }\n &.active {\n .content {\n opacity: 1;\n transform: scale(1);\n }\n }\n }\n</style>\n","<!-- \n @component\n 一个退出按钮\n -->\n<script lang=\"ts\">\n export let onClick: () => void | undefined | null = null\n</script>\n\n<div class=\"exit\" on:click={onClick} />\n\n<style lang=\"scss\">\n .exit {\n position: relative;\n pointer-events: all;\n cursor: pointer;\n left: 24px;\n top: 24px;\n width: 24px;\n height: 24px;\n background-image: url(data:image/png;base64,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);\n background-repeat: no-repeat;\n background-size: 100% 100%;\n }\n</style>\n","export const IconUndo =\n 'data:image/png;base64,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'\n\nexport const IconOk =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAASKADAAQAAAABAAAASAAAAACQMUbvAAAFO0lEQVR4Ae2YWYgdRRSG78SFOG6Ju4MxIRnRgCCKBlSC24P64IO4h7wI6oMPCioqAX1TfFIQRFFBETQmIioqGhDBh3GJiMSAZnABNSIuUQTFbcz4fZcup297b9+t7525wznwU11d1aervj6nurprtbAgEASCQBAIAkEgCASBIBAEgkAQCAJBIAgEgSAQBIJAEMgIzM7OLkHL0STaJ8DMgRkDyDK0CX2MptEUOrMbSGPddB6VvkAwUo5Hd6OzCuP+hfr5Y2NjvxbON60uaXp2hE8CZ3+GfzJ6ABXhOLND0VoPOrF9O+k0Kn2AM85Y16M70UTJuL8taWtoWjSAgHMYM7sQ3YyWN8yysbKZ9NrdeKp1bVGsQcBxvbkUXYsOaD3d2jbabgXQ3yV9GppGPoKA43pyDboclb3G36T9rm7g0L82soAAY/S7CG9E56GybHiLduH4BuvKRhIQcIyUi5BwTmsz47dpvwftadOvafPIAQLOUmZiSl2JVjed1dzJ7Rzei74iembnTnd+NFKAgHMIU7seXYKObTPN92kXzue9wtH/yAACjkBuQecgN3tltoNGN4rTwNlb1rFd20gAAs4JTOR2dAYqe407351IOB/2C0dnlQBiAm7vZ6oYkIPKG77XUd+E1iDvU2bTND6I3qtqLH0BYvDuWP3uORHNUHeAOxlcRx+C9C01/F1MhzvQUahsj6OfT9HDaKoqODot2zvY3tIYvOuAi+W5SD++Xf5BU+h1BvklZc+G/+u4+AbkwtxunF/QRzivcl/HUJn1E0GTjMKNmtGin7+QKeD30AQTfI1ye7dPk+uMFFPqMtRuvaFLzQfxOKocjs57ApRNwrfKDPKJ+YSV9Z/RKcj2lfR9BUi/cdzW6GsU3o98U3Uytq/p9wR6serIwWfdevoflA3mh8yHGzBfpYJK5U8cuz5dhW5k4isoS40+ptJDaD3qBM439HsKbR0UHHzXegLkhdhnaBcyrfJwhKSMGtPuAnQbAM6mbGq0HU3DI+h01Akc/+c8owYJB/9tFz/7NDUmZUqtRFegVehP5OSU64jlfpkOp/wRbUNbmNQflHXDzyoO7kMnIX16rWr18L6nbTN6FD+m9EDNAfVsGaRJHAjpOGTEJDgJViqX0WakvYu2ot3oVHQT0odRJxT7C1Y/RUtwHgNOx/90ik66qfcFyBvlIG2gOoGMjgTFMg/sQOoHo++QQFynjC7BJjjpWq/LQ3LNM62GBod79Z5iXpwsg7SWul/YQiqmW4qINPmD6OM5zUU+QbQs9vUhzgsc7tsyz23r2Ah3J/kJegE5mXFkOjVbvNMC7v7JaHMd8ZzST/4a6/MGh3vXU8GybxMS9hGOfOJG0jFIAGnylk7edpXOm1qpzWPb7Ge0mYrPoaGmFff7zxxEZZZB2oFD00RIRyAhJSh5MHkoAhFOeit5vQvyFvTksBZk7vU/qxSQ3jNIH2R3cqPoh+bvKEVMiqJ8tKSo8TLXIdPqWfT0fMLh/tWlmM6SMam9pFsRkgt3ihRhGS3FiHLT6X7JfY475KG8yrlXS6s8gtKdCpCu5ryR5Os8H0H5NDNyhGNaPc/1Kd2ozp8NDJBTKkDawKkjkZFkeuVBOY49yMh5eaHAYSyDSTEdJytAcuF2n2TqmF5pD5Tg+B9pQUQOY6ubgxyKsSYZNf4GEdJqJJylyA/Pl9AbCw0OY6o/RcuhGJB8IMJZh1Ygf4u8g3YBx5QLk4DRhMaRC3NYEAgCQSAIBIEgEASCQBAIAkEgCASBIBAEgkAQCAJBYJEQ+BdpRqKi3IjqNwAAAABJRU5ErkJggg=='\n\nexport const IconLine =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAMKADAAQAAAABAAAAMAAAAADbN2wMAAABi0lEQVRoBe2Yu20DMRBEdW7EuVLX4NQVuAEVoUhFuAFV4FQ1OHWuRkzNABRwMLhDfbhcBhyA0IEjnvYNjjxoN5upmcBMYCYQmcCifjyl9AL/E+Md4xXjjHHCOC7L8ofPcJkAufgvVPhWqPIHc7sRIJiwJSZfKp7f5zz9cCkAPjZKNV+tbeYpAD7zSjVfrW3mKQBuWKWar9Y28xQATxsl7PNkHgJqYUtPARzxQzxtLG1h7KMhZIL5KP3/HkgonMVf9Y2LA45UzneXBChVkxPfw/tY+WEQdwOw6JEgHgIYCeJhgFEgngIYAeJpgGiIJgCREM0AoiCaAkRANAfoDeEC0BPCDaAXhCtADwh3AG+ILgCeEN0AvCC6AnhAdAdoDRECICB+4bEmtmzOGNU2ZhgAirP+2dFaS7YxVVdifROX69wIOODmTN6SbGOGArDiDFF7Esw2ZjhAjr3WpjT9UQC4YZVMfxSAWhvT9EcBUG1MnkL0i6ptnuIij0mjjVl9D3jUMu85E5gJzARuT+ACS7KuMQ7rOEcAAAAASUVORK5CYII='\n\nexport const IconArea =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAMKADAAQAAAABAAAAMAAAAADbN2wMAAAByElEQVRoBe1ZMU4DMRC8Q7yCJjVNKCh4ARVfAPo0PCYNPeQLVLyAggIa6jQ8g2NGsiJjeUfHrdGd0K60Sm7t3R3P+hx503UhwUAwEAzMyUCvkg/DcITxa+gldAXdQ5+hu77vv/DZTKbmMheQAt4D4XkF5Stsm1aL8OQiw5aQ+Rp4zqed461kci5VgUegO22F0BnnA9W+qcVQFeCeX4qYWNQC+MIuRUwsxwIhTxu1hV4w/ib8fzN0hskXwoFYqqIqsIMHT5uafML4XhuYaGMsxqwJMRBLVcyXmLOzs/ku8ybzTDhkthZfiWUNzSuxxbP8zVEV6HjOQx8KdNw2rcEzBWP+2JLMTQwctEQuwHJakj0WMHc1ogJRAScDsYWcBLrdowJuCp0BogJOAt3uUQE3hc4AUQEngW73/10BXimhtwVNvIDLq2gxf+wjYzL2QZg7XWsPtvKLCSQ5Wq1FXsCfoK2ulsRxBT2BliLbmGoLqXYfE/EC3koYqwae8WUbU1UgWoutyoM4KyuW2kJ7y2kGu4nF01rcVnpGk9aWTrq8eVbGad5alO2+MvuIZ9XGlLnMl5hJ01HK02ixfzGNICemBAPBQDDwhwx8A43PdoQvgLfYAAAAAElFTkSuQmCC'\n","<!--\n @component\n pc 端控制器\n -->\n<script lang=\"ts\">\n import Switcher0 from './Common/Switcher0.svelte'\n import type MeasureController from '../Controller'\n import { onDestroy, onMount } from 'svelte'\n import type { Mode } from '../Controller'\n import Exit from './Common/Exit.svelte'\n import EditController from '../Controller/EditController'\n import { IconLine, IconOk, IconUndo, IconArea } from './Common/icons'\n\n export let measureController: MeasureController\n export let showExit = false\n export let i18n: (key: string) => string = (key) => key\n\n let canRevoke = false\n\n /** 设置哪个块高亮的 */\n let setSwitcherActiveIndex: (index: number | null) => void\n\n function handleModeChange(mode: Mode) {\n if (mode === 'Edit') {\n showController = true\n } else {\n setSwitcherActiveIndex(null)\n showController = false\n }\n }\n\n function complete() {\n if (measureController.controller instanceof EditController) {\n measureController.controller.complete()\n }\n measureController.save({ mode: 'Watch' })\n }\n\n function handlePointsChange(points: any[]) {\n canRevoke = points.length > 0\n }\n\n function handleComplete() {\n canRevoke = false\n }\n\n onMount(() => {\n measureController.hooks.on('modeChange', handleModeChange)\n measureController.hooks.on('complete', handleComplete)\n measureController.hooks.on('pointsChange', handlePointsChange)\n })\n\n onDestroy(() => {\n measureController.hooks.off('modeChange', handleModeChange)\n measureController.hooks.off('complete', handleComplete)\n measureController.hooks.off('pointsChange', handlePointsChange)\n })\n\n let showController = false\n</script>\n\n<div class=\"Measure-Controller\">\n {#if showExit}\n <Exit onClick={measureController.disable} />\n {/if}\n <div class=\"bottom\">\n <div class=\"mask\" />\n <div class=\"center\">\n {#if showController}\n <div class=\"buttons\">\n <div class=\"button\" class:forbid={!canRevoke} on:click={() => measureController.revoke()}>\n <div class=\"icon\" style:background-image={`url(${IconUndo})`} />\n {i18n('撤销')}\n </div>\n <div class=\"button\" on:click={complete}>\n <div class=\"icon\" style:background-image={`url(${IconOk})`} />\n {i18n('结束')}\n </div>\n </div>\n {/if}\n <div class=\"mode-switcher\">\n <Switcher0\n options={[\n { key: 'line', value: i18n('测距离'), icon: IconLine },\n { key: 'area', value: i18n('测面积'), icon: IconArea },\n ]}\n onChange={(value) => {\n measureController.save().changeMode('Edit') // 保存并且切换至edit态\n measureController.changeMeasureType(value)\n }}\n bind:setIndex={setSwitcherActiveIndex}\n />\n </div>\n </div>\n </div>\n</div>\n\n<style lang=\"scss\">\n *.forbid {\n pointer-events: none !important;\n opacity: 0.5;\n }\n .Measure-Controller {\n pointer-events: none;\n position: relative;\n width: 100%;\n height: 100%;\n z-index: 2;\n .mode-switcher {\n margin-top: 36px;\n }\n .bottom {\n position: absolute;\n width: 100%;\n bottom: 0;\n .mask {\n position: absolute;\n bottom: 0;\n width: 100%;\n height: 184px;\n background-size: 100%;\n background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.3));\n }\n .center {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 40px;\n }\n }\n .buttons {\n pointer-events: all;\n display: flex;\n align-items: center;\n height: 40px;\n background: rgba(0, 0, 0, 0.2);\n color: rgba(255, 255, 255, 0.85);\n width: max-content;\n border-radius: 9999px;\n overflow: hidden;\n .button {\n cursor: pointer;\n display: flex;\n align-items: center;\n position: relative;\n font-size: 14px;\n padding: 0px 16px;\n .icon {\n width: 24px;\n height: 24px;\n background-repeat: no-repeat;\n background-size: 100%;\n margin-right: 4px;\n }\n // 分割线\n &::after {\n content: '';\n position: absolute;\n display: block;\n right: -0.5px;\n height: 24px;\n width: 1px;\n background-image: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.3), transparent);\n background-size: 100%;\n background-repeat: no-repeat;\n background-position: center;\n }\n &:last-child {\n &::after {\n display: none;\n }\n }\n }\n }\n }\n</style>\n","<!--\n @component\n 一个滑动选择器,样式大概是这样,选中的选项永远在最中间\n\n 选项1 ( 选中的选项 ) 选项2 选项3\n -->\n<script lang=\"ts\" generics=\"T extends string\">\n // 要这么转换一下T应该是 svelte 的 language tools 的 bug,没时间查\n\n type K = T\n export let options: Array<{ key: K; value: string; icon?: string }>\n export let defaultKey: K | null = null\n export let onChange: (key: K) => void\n\n const gap = 18\n const elementList: HTMLElement[] = []\n let container: HTMLElement\n $: activeIndex = defaultKey ? options.findIndex((option) => option.key === defaultKey) : 0\n $: activeButton = elementList[activeIndex]\n\n // 用来控制滑块移动的\n let activeButtonWidth: number | undefined\n let activeButtonLeft = 0\n\n function setAnimeResult() {\n if (activeButton && container) {\n activeButtonWidth = activeButton.clientWidth\n const newActiveButtonLeft = activeButtonLeft + container.getBoundingClientRect().left - activeButton.getBoundingClientRect().left\n activeButtonLeft = newActiveButtonLeft\n }\n }\n\n $: {\n if (activeButton && container) setTimeout(() => setAnimeResult(), 0)\n }\n</script>\n\n<div class=\"Switcher\" bind:this={container}>\n <div class=\"highlight\" style:width={activeButtonWidth ? `${activeButtonWidth}px` : undefined} />\n <div class=\"Switcher-buttons\" style:transform={`translate(${activeButtonLeft}px, -50%)`}>\n {#each options as option, index}\n <!-- svelte-ignore a11y-click-events-have-key-events -->\n <div\n class=\"button\"\n class:active={activeIndex === index}\n bind:this={elementList[index]}\n on:click={() => {\n onChange(option.key)\n activeIndex = index\n }}\n >\n <div class=\"content\">\n {#if option.icon}\n <span class=\"icon\" style:background-image={option.icon} />\n {/if}\n {option.value}\n </div>\n </div>\n {/each}\n </div>\n</div>\n\n<style lang=\"scss\">\n .Switcher {\n pointer-events: all;\n position: relative;\n margin-bottom: 24px;\n box-sizing: border-box;\n width: max-content;\n\n * {\n transition-duration: 300ms;\n transition-timing-function: ease-out;\n }\n\n .content {\n transition-property: opacity;\n }\n\n .highlight {\n transition-property: width;\n }\n\n .Switcher-buttons {\n transition-property: transform;\n }\n\n .Switcher-buttons {\n position: absolute;\n top: 50%;\n left: 0;\n transform: translate(0, -50%);\n width: max-content;\n .button {\n display: inline-block;\n margin: 0 9px;\n }\n }\n\n .highlight {\n height: 32px;\n background: rgba(0, 0, 0, 0.3);\n border-radius: 9999px;\n }\n\n .content {\n position: relative;\n padding: 0 12px;\n }\n\n .button:not(.active) {\n .content::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 10%;\n width: 80%;\n transform: translateY(-50%);\n height: 0;\n box-shadow: 0 0 15px 5px rgba(0, 0, 0, 0.3);\n }\n }\n }\n</style>\n","<!-- \n @component\n 一个圆的按钮\n -->\n<script lang=\"ts\">\n import { fade } from 'svelte/transition'\n import { endIconImage, startIconImage } from '../../Modules/UIController/mobileHTML'\n\n export let text: string\n export let onClick: () => void | undefined | null = null\n export let color: 'white' | 'blue' = 'white'\n\n $: bgImage = (() => {\n if (color === 'white') return startIconImage\n else if (color === 'blue') return endIconImage\n else return startIconImage\n })()\n</script>\n\n<div class=\"CircleButton\" style:background-image={`url(${bgImage})`} on:click={onClick}>\n {#key text}\n <div class=\"text\" transition:fade={{ duration: 300 }}>\n {text}\n </div>\n {/key}\n</div>\n\n<style lang=\"scss\">\n .CircleButton {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 72px;\n height: 72px;\n background-image: inherit;\n background-size: 100% auto;\n background-repeat: no-repeat;\n transition: transform 200ms ease-in-out;\n &:active {\n transform: scale(0.8);\n }\n .text {\n position: absolute;\n }\n }\n</style>\n","<!--\n @component\n 移动端控制器\n -->\n<script lang=\"ts\">\n import Switcher1 from './Common/Switcher1.svelte'\n import type MeasureController from '../Controller'\n import { onDestroy, onMount } from 'svelte'\n import CircleButton from './Common/CircleButton.svelte'\n import EditController from '../Controller/EditController'\n import Exit from './Common/Exit.svelte'\n import type { MeasureType } from '../typings/data'\n import { fade } from 'svelte/transition'\n import { IconOk, IconUndo } from './Common/icons'\n\n type ButtonState = 'start' | 'add' | 'end' | 'complete'\n\n export let measureController: MeasureController\n export let showExit = false\n export let i18n: (key: string) => string = (key) => key\n\n const buttonTextMap: Record<typeof buttonState, string> = {\n start: i18n('开始'),\n add: i18n('添加'),\n end: i18n('结束'),\n complete: i18n('完成'),\n }\n\n const buttonColorMap: Record<typeof buttonState, 'white' | 'blue'> = {\n start: 'white',\n add: 'white',\n end: 'blue',\n complete: 'blue',\n }\n\n const fadeDuration = 100\n\n /** 是否展示 */\n let showButton = false\n let pointsLength = 0\n let allowAddPoint = true\n let buttonState: ButtonState = 'start'\n let lastButtonState: ButtonState | null = null\n let currentMeasureType = measureController.currentMeasureType\n\n $: showButton = currentMeasureType === 'area' && buttonState !== 'start'\n\n /**\n * @description: 开始按钮的逻辑\n */\n const start = () => {\n if (measureController.getCurrentMode() !== 'Edit') {\n measureController.changeMode('Edit')\n } else {\n changeButtonState('add')\n addPoint()\n }\n }\n\n /**\n * @description: 添加按钮的逻辑\n */\n const addPoint = () => {\n if (measureController.controller instanceof EditController) {\n measureController.controller.selectPoint()\n }\n }\n\n const complete = () => {\n if (measureController.controller instanceof EditController) {\n measureController.controller.complete()\n }\n pointsLength = 0\n }\n\n const changeButtonState = (state: ButtonState) => {\n if (buttonState !== lastButtonState) {\n lastButtonState = buttonState\n }\n buttonState = state\n }\n\n /**\n * @description: 结束按钮的逻辑,打点并结束\n */\n const end = () => {\n addPoint()\n onAllowAddPointStateChange('allow')\n }\n\n const readyComplete = () => {\n changeButtonState('complete')\n }\n\n const notReadyComplete = () => {\n if (measureController.currentMeasureType === 'area') {\n if (buttonState === 'complete') {\n changeButtonState('add')\n }\n }\n }\n\n const handlePointsChange = (point: any[]) => {\n pointsLength = point.length\n }\n\n const setStartState = () => {\n changeButtonState('start')\n onAllowAddPointStateChange('allow')\n }\n\n const onAllowAddPointStateChange = (state: 'allow' | 'forbid') => {\n allowAddPoint = state === 'allow'\n }\n\n const onMeasureTypeChange = (measureType: MeasureType) => {\n currentMeasureType = measureType\n }\n\n const onRevoke = (params: { isEmpty: boolean }) => {\n if (params.isEmpty) changeButtonState('start')\n }\n\n onMount(() => {\n measureController.hooks.on('revoke', onRevoke)\n measureController.hooks.on('measureTypeChange', onMeasureTypeChange)\n measureController.hooks.on('modeChange', setStartState)\n measureController.hooks.on('pointsChange', handlePointsChange)\n measureController.hooks.on('allowAddPointStateChange', onAllowAddPointStateChange)\n measureController.hooks.on('readyComplete', readyComplete)\n measureController.hooks.on('notReadyComplete', notReadyComplete)\n measureController.hooks.on('complete', setStartState)\n })\n\n onDestroy(() => {\n measureController.hooks.off('measureTypeChange', onMeasureTypeChange)\n measureController.hooks.off('modeChange', setStartState)\n measureController.hooks.off('allowAddPointStateChange', onAllowAddPointStateChange)\n measureController.hooks.off('readyComplete', readyComplete)\n measureController.hooks.off('pointsChange', handlePointsChange)\n measureController.hooks.off('notReadyComplete', notReadyComplete)\n measureController.hooks.off('complete', setStartState)\n })\n</script>\n\n<div class=\"Measure-Controller\">\n {#if showExit}\n <Exit onClick={measureController.disable} />\n {/if}\n <div class=\"bottom\">\n <div class=\"mask\" />\n <div class=\"center\">\n <!-- 两个以上才有切换功能 -->\n {#if measureController.allowMeasureType.length >= 2 && buttonState === 'start'}\n <div class=\"mode-switcher\" transition:fade|local={{ duration: fadeDuration }}>\n <Switcher1\n options={[\n { key: 'line', value: i18n('测距离') },\n { key: 'area', value: i18n('测面积') },\n ]}\n defaultKey={measureController.currentMeasureType}\n onChange={measureController.changeMeasureType}\n />\n </div>\n {/if}\n <div class=\"controller\">\n {#if showButton}\n <div\n transition:fade|local={{ duration: fadeDuration }}\n class=\"button\"\n class:forbid={buttonState === 'start'}\n on:click={() => measureController.revoke()}\n >\n <div class=\"icon\" style:background-image={`url(${IconUndo})`} />\n {i18n('撤销')}\n </div>\n {/if}\n <div class=\"main-button\" class:forbid={!allowAddPoint}>\n <CircleButton\n onClick={() => {\n if (buttonState === 'start') start()\n else if (buttonState === 'add') addPoint()\n else if (buttonState === 'end' || buttonState === 'complete') end()\n }}\n text={buttonTextMap[buttonState]}\n color={buttonColorMap[buttonState]}\n />\n </div>\n {#if showButton}\n <div transition:fade|local={{ duration: fadeDuration }} class=\"button\" on:click={complete}>\n <div class=\"icon\" style:background-image={`url(${IconOk})`} />\n {i18n('结束')}\n </div>\n {/if}\n </div>\n </div>\n </div>\n</div>\n\n<style lang=\"scss\">\n *.forbid {\n pointer-events: none !important;\n opacity: 0.5;\n }\n .Measure-Controller {\n pointer-events: none;\n position: relative;\n width: 100%;\n height: 100%;\n z-index: 2;\n color: white;\n .mode-switcher {\n margin-top: 36px;\n }\n .bottom {\n position: absolute;\n width: 100%;\n bottom: 0;\n .mask {\n position: absolute;\n bottom: 0;\n width: 100%;\n height: 200px;\n background-size: 100%;\n z-index: -1;\n background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.5));\n }\n .center {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 40px;\n }\n }\n }\n\n .Measure-Controller {\n .controller {\n pointer-events: all;\n display: flex;\n align-items: center;\n .button {\n cursor: pointer;\n display: flex;\n align-items: center;\n height: 40px;\n padding-left: 16px;\n padding-right: 16px;\n border-radius: 9999px;\n font-size: 14px;\n color: #fff;\n background-color: rgba(0, 0, 0, 0.2);\n .icon {\n width: 24px;\n height: 24px;\n background-repeat: no-repeat;\n background-size: 100%;\n margin: 0 4px;\n }\n }\n .main-button {\n margin-left: 28px;\n margin-right: 28px;\n font-size: 14px;\n font-weight: bold;\n }\n }\n }\n</style>\n","import type MeasureController from '../../Controller'\nimport htmlString from './HTML'\nimport mobileHTMLString from './mobileHTML'\nimport { uiWrapperStyle, operatingSpaceStyle, controllerBackgroundStyle, exitIconStyle, exitItemStyle, textStyle } from './style'\nimport { MainBtnController } from './MainBtnController'\nimport { MobileMainBtnController } from './mobileMainBtnController'\nimport Revoke from './Revoke'\nimport Controller0 from '../../Components/Controller0.svelte'\nimport Controller1 from '../../Components/Controller1.svelte'\n\nimport { mountComponent, type MountedComponent } from '../../../shared-utils/svelte/component.svelte'\nexport type UIMode = 'pc' | 'mobile'\n\nexport interface UIControllerParams {\n container?: Element\n mode?: UIMode\n pointSelectorMode?: 'fixed' | 'cursor'\n useNewUI?: boolean\n /**\n * @description: 是否展示退出按钮\n */\n showExit?: boolean\n startButtonText?: string\n endButtonText?: string\n revokeButtonText?: string\n exitButtonText?: string\n i18n?: (key: string) => string\n}\n\nexport class UIController {\n private revoke?: Revoke\n private container: HTMLDivElement\n private wrapper?: HTMLDivElement\n private mainController?: MainBtnController | MobileMainBtnController\n private disposers: (() => unknown)[] = []\n private measureController: MeasureController\n private mode: UIMode\n private svelteDom?: MountedComponent<any>\n private _params: UIControllerParams\n private useNewUI: boolean = false\n\n public constructor(measureController: MeasureController, params: UIControllerParams) {\n this._params = params\n this.measureController = measureController\n this.mode = params.mode ?? 'pc'\n this.wrapper = params.container as HTMLDivElement\n this.container = document.createElement('div')\n this.wrapper.appendChild(this.container)\n\n const useNewUI = params.useNewUI ?? false\n this.useNewUI = useNewUI\n\n // 新整的UI\n if (useNewUI) {\n this.container.style.position = 'absolute'\n this.container.style.top = '0'\n this.container.style.left = '0'\n this.container.style.width = '100%'\n this.container.style.height = '100%'\n if (params.pointSelectorMode === 'cursor') {\n this.svelteDom = mountComponent(Controller0, this.container, { measureController: this.measureController, i18n: params.i18n, showExit: params.showExit })\n } else if (params.pointSelectorMode === 'fixed') {\n this.svelteDom = mountComponent(Controller1, this.container, { measureController: this.measureController, i18n: params.i18n, showExit: params.showExit })\n }\n }\n\n // 以前的UI\n if (!useNewUI) {\n this.container.innerHTML = this.mode === 'mobile' ? mobileHTMLString : htmlString\n this.container.classList.add('fpm__ui-controller', this.mode)\n this.container.style.background = 'rgba(0, 0, 0, 0.15)'\n\n const textDoms = this.container.querySelectorAll<HTMLSpanElement>('.fpm__text')\n const bgDom = this.container.querySelector<HTMLSpanElement>('.fpm_ui-bg')\n const operatingSpaceDom = this.container.querySelector<HTMLSpanElement>('.fpm_operating-space')\n\n Object.assign(bgDom?.style, controllerBackgroundStyle)\n Object.assign(operatingSpaceDom?.style, operatingSpaceStyle)\n Object.assign(this.container.style, uiWrapperStyle)\n textDoms.forEach((item) => Object.assign(item.style, textStyle))\n }\n }\n\n public dispose() {\n this.hide()\n this.svelteDom?.destroy()\n this.container.remove()\n }\n\n public show() {\n this.container.style.display = 'block'\n this.container.style.opacity = '1'\n this.container.style.transform = 'translate(0, 0)'\n if (this.useNewUI === false) {\n if (this.mode === 'pc') {\n this.revoke = new Revoke(this.measureController, this.container)\n this.mainController = new MainBtnController(this.measureController, this.container, this._params)\n } else {\n this.mainController = new MobileMainBtnController(this.measureController, this.container, this._params)\n }\n this.disposers.push(this.handleExit())\n }\n\n return this\n }\n\n public hide() {\n this.container.style.display = 'none'\n this.container.style.opacity = '0'\n this.container.style.transform = 'translate(0, 10px)'\n if (this.useNewUI === false) {\n this.mode === 'pc' && this.revoke?.dispose()\n }\n this.mainController?.dispose()\n this.disposers.forEach((disposer) => disposer())\n this.disposers = []\n return this\n }\n\n private handleExit = () => {\n const exitIcon = this.container.querySelector<HTMLElement>('.fpm__exit-icon')\n const exitItem = this.container.querySelector<HTMLButtonElement>('.fpm__exit')\n if (!exitItem || !exitIcon) throw new Error('cannot find dom')\n\n if (this.mode === 'pc') {\n Object.assign(exitItem.style, exitItemStyle)\n Object.assign(exitIcon?.style, exitIconStyle)\n }\n\n const onMouseEnter = () => {\n exitItem.style.opacity = '1'\n }\n const onMouseLeave = () => {\n exitItem.style.opacity = '0.85'\n }\n const handleClick = () => {\n this.measureController.disable()\n }\n\n exitItem.addEventListener('click', handleClick)\n exitItem.addEventListener('mouseenter', onMouseEnter)\n exitItem.addEventListener('mouseleave', onMouseLeave)\n\n return () => {\n exitItem.removeEventListener('click', handleClick)\n exitItem.removeEventListener('mouseenter', onMouseEnter)\n exitItem.removeEventListener('mouseleave', onMouseLeave)\n }\n }\n}\n","<!--\n @component\n pc 端控制器\n -->\n<script lang=\"ts\">\n import type MeasureController from '../Controller'\n import { onDestroy, onMount } from 'svelte'\n import type { MeasureTip } from '../Modules/GuideController'\n import type { Mode } from '../Controller'\n import { fade } from 'svelte/transition'\n\n type TipKey = keyof (MeasureTip['line'] & MeasureTip['area'] & Omit<MeasureTip, 'line' | 'area'>)\n\n export let measureController: MeasureController\n export let i18n: (key: string) => string = (key) => key\n export let tips: MeasureTip\n export let tipStyle: Partial<CSSStyleDeclaration> = {}\n export let visible = true\n\n let textDom: HTMLDivElement | null = null\n\n $: {\n if (textDom) {\n for (const key in tipStyle) {\n if (tipStyle.hasOwnProperty(key)) {\n textDom.style[key] = tipStyle[key]\n }\n }\n }\n }\n\n const getTip = (key: TipKey) => {\n const currentType = measureController.currentMeasureType\n let tip = ''\n tip = tips[key as any]\n if (tip === undefined) {\n tip = tips[currentType][key as any]\n }\n return tip\n }\n\n const setTip = (key: TipKey) => {\n tip = i18n(getTip(key))\n }\n\n const clear = () => {\n tip = ''\n }\n\n let tip = ''\n\n const handleModeChange = (mode: Mode) => {\n if (mode === 'Edit') {\n if (measureController.changeMeasureType) setTip('start')\n else clear()\n } else {\n clear()\n }\n }\n\n const complete = () => {\n if (measureController.getCurrentMode() === 'Watch') {\n clear()\n }\n }\n\n const start = () => {\n if (measureController.getCurrentMode() === 'Edit') {\n setTip('start')\n }\n }\n\n const pointsChange = (points: any[]) => {\n if (measureController.currentMeasureType === 'area') {\n if (points.length >= 2) setTip('close')\n else if (points.length === 0) setTip('start')\n else clear()\n }\n }\n\n onMount(() => {\n handleModeChange(measureController.getCurrentMode())\n measureController.hooks.on('modeChange', handleModeChange)\n measureController.hooks.on('complete', complete)\n measureController.hooks.on('pointsChange', pointsChange)\n measureController.hooks.on('measureTypeChange', start)\n })\n\n onDestroy(() => {\n measureController.hooks.off('modeChange', handleModeChange)\n measureController.hooks.off('complete', complete)\n measureController.hooks.off('pointsChange', pointsChange)\n measureController.hooks.off('measureTypeChange', start)\n clear()\n })\n</script>\n\n{#if visible}\n <div class=\"Measure-Tips\" transition:fade>\n <div class=\"text\" bind:this={textDom}>{tip}</div>\n </div>\n{/if}\n\n<style lang=\"scss\">.Measure-Tips {\n box-sizing: border-box;\n position: absolute;\n pointer-events: none;\n top: 0;\n width: 100%;\n padding: 0 2.5rem;\n}\n.Measure-Tips .text {\n text-align: center;\n position: relative;\n max-width: 100%;\n top: 3.125rem;\n color: #fff;\n word-break: break-word;\n overflow-wrap: break-word;\n hyphens: auto;\n -webkit-hyphens: auto;\n text-shadow: 0 0.0625rem 0.375rem rgba(0, 0, 0, 0.5);\n font-size: 1.25rem;\n font-weight: bold;\n}</style>\n","<!--\n @component\n pc 端控制器\n -->\n<script lang=\"ts\">\n import type MeasureController from '../Controller'\n import { onDestroy, onMount } from 'svelte'\n import type { MeasureTip } from '../Modules/GuideController'\n import type { Mode } from '../Controller'\n import { fade } from 'svelte/transition'\n\n type TipKey = keyof (MeasureTip['line'] & MeasureTip['area'] & Omit<MeasureTip, 'line' | 'area'>)\n\n export let measureController: MeasureController\n export let i18n: (key: string) => string = (key) => key\n export let tips: MeasureTip\n export let tipStyle: Partial<CSSStyleDeclaration> = {}\n export let visible = true\n\n let textDom: HTMLDivElement | null = null\n\n $: {\n if (textDom) {\n for (const key in tipStyle) {\n if (tipStyle.hasOwnProperty(key)) {\n textDom.style[key] = tipStyle[key]\n }\n }\n }\n }\n\n const getTip = (key: TipKey) => {\n const currentType = measureController.currentMeasureType\n let tip = ''\n tip = tips[key as any]\n if (tip === undefined) {\n tip = tips[currentType][key as any]\n }\n return tip\n }\n\n const setTip = (key: TipKey) => {\n tip = i18n(getTip(key))\n }\n\n const clear = () => {\n tip = ''\n }\n\n let tip = ''\n\n const handleModeChange = (mode: Mode) => {\n if (mode === 'Edit') {\n if (measureController.changeMeasureType) setTip('start')\n else clear()\n } else {\n clear()\n }\n }\n\n const complete = () => {\n if (measureController.getCurrentMode() === 'Watch') {\n clear()\n }\n }\n\n const start = () => {\n if (measureController.getCurrentMode() === 'Edit') {\n setTip('start')\n }\n }\n\n const pointsChange = (points: any[]) => {\n if (measureController.currentMeasureType === 'area') {\n if (points.length >= 2) setTip('close')\n else if (points.length === 0) setTip('start')\n else clear()\n }\n }\n\n onMount(() => {\n handleModeChange(measureController.getCurrentMode())\n measureController.hooks.on('modeChange', handleModeChange)\n measureController.hooks.on('complete', complete)\n measureController.hooks.on('pointsChange', pointsChange)\n measureController.hooks.on('measureTypeChange', start)\n })\n\n onDestroy(() => {\n measureController.hooks.off('modeChange', handleModeChange)\n measureController.hooks.off('complete', complete)\n measureController.hooks.off('pointsChange', pointsChange)\n measureController.hooks.off('measureTypeChange', start)\n clear()\n })\n</script>\n\n{#if visible}\n <div class=\"Measure-Tips\" transition:fade>\n <div class=\"text\" bind:this={textDom}>{tip}</div>\n </div>\n{/if}\n\n<style lang=\"scss\">\n .Measure-Tips {\n box-sizing: border-box;\n position: absolute;\n pointer-events: none;\n top: 0;\n width: 100%;\n padding: 0 40px;\n .text {\n text-align: center;\n position: relative;\n max-width: 100%;\n top: 50px;\n color: #fff;\n word-break: break-word;\n overflow-wrap: break-word;\n hyphens: auto;\n -webkit-hyphens: auto;\n text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);\n font-size: 20px;\n font-weight: bold;\n }\n }\n</style>\n","import objectAssignDeep from 'object-assign-deep'\nimport Tip from '../Components/Tip.svelte'\nimport type MeasureController from '../Controller'\nimport type { PartialObjectDeep } from '../../typings/typings'\nimport type { PointSelectorMode } from '../typings/data'\n\nimport { mountComponent, type MountedComponent } from '../../shared-utils/svelte/component.svelte'\nconst pcTip: MeasureTip = {\n line: {\n start: '选择一个合适的位置开始测量,点击【结束】或【鼠标右键】结束测量',\n },\n area: {\n start: '选择一个合适的位置开始绘制平面',\n close: '选择3个点后将闭合平面,点击【结束】或【鼠标右键】将自动闭合',\n },\n}\n\nconst mobileTip: MeasureTip = {\n line: {\n start: '',\n },\n area: {\n start: '',\n close: '选择3个点后将闭合平面,点击结束自动闭合',\n },\n}\n\nexport interface MeasureTip {\n line: {\n // 开始的提示\n start: string\n }\n area: {\n // 开始的提示\n start: string\n // 提示闭合\n close: string\n }\n}\n\nexport interface GuideControllerParams {\n container?: Element\n i18n?: (key: string) => string\n tips?: PartialObjectDeep<MeasureTip>\n tipStyle?: Partial<CSSStyleDeclaration>\n pointSelectorMode?: PointSelectorMode\n}\n\nexport class GuideController {\n private tipSvelteDom?: MountedComponent<any>\n\n public constructor(measureController: MeasureController, params: GuideControllerParams) {\n this.tipSvelteDom = mountComponent(Tip, params.container, {\n measureController,\n tips: objectAssignDeep({}, params.pointSelectorMode === 'fixed' ? mobileTip : pcTip, params.tips),\n i18n: params.i18n,\n visible: true,\n tipStyle: params.tipStyle,\n })\n }\n\n public dispose() {\n this.tipSvelteDom?.destroy()\n }\n\n public show() {\n this.tipSvelteDom?.update({ visible: true })\n return this\n }\n\n public hide() {\n this.tipSvelteDom?.update({ visible: false })\n return this\n }\n}\n","import type MeasureController from '.'\nimport type { Five } from '@realsee/five-webgpu'\n\n/** 快捷键控制器 */\nexport class ShortcutKeyController {\n public five: Five\n public measureController: MeasureController\n\n public constructor(measureController: MeasureController, five: Five) {\n this.five = five\n this.measureController = measureController\n\n const fiveElement = this.five.getElement()\n if (!fiveElement) return\n document.body.addEventListener('keydown', this.onKeyDown)\n }\n\n public dispose() {\n const fiveElement = this.five.getElement()\n if (!fiveElement) return\n document.body.removeEventListener('keydown', this.onKeyDown)\n }\n\n private escape() {\n if (this.measureController.getCurrentMode() === 'Watch') return this.measureController.disable()\n return this.measureController.save().changeMode('Watch')\n }\n\n private onKeyDown = (e: KeyboardEvent) => {\n // Command + S -> 保存 & 更改场景\n if (e.metaKey && e.code === 'KeyS') {\n this.measureController.save().changeMode('Watch')\n e.preventDefault()\n return\n }\n\n // Escape -> 切换到观察模式 / 如果已经在观察模式,退出功能\n if (e.code === 'Escape') return this.escape()\n }\n\n private onMouseDown = (e: MouseEvent) => {\n // 鼠标右键取消\n if (e.button !== 2) return\n e.preventDefault()\n this.measureController.save().changeMode('Watch')\n }\n}\n","import type { Config } from '../typings'\nimport type {\n EditParameter,\n MeasureType,\n OpenParameter,\n MeasurePluginData,\n PointSelectorMode,\n MeasurePluginServerData,\n} from '../typings/data'\nimport type { PanoMeasurePluginEvent } from '../typings/event.type'\nimport type { UserDistanceItem } from '../utils/dom/distanceItem'\nimport type { Polyline } from '../Model/polyline'\nimport type { ControllerParams } from './BaseController'\nimport EditController from './EditController'\nimport ViewController from './ViewController'\nimport WatchController from './WatchController'\nimport MixedController from './MixedController'\nimport { omit } from '../../shared-utils/filter'\nimport { Group } from 'three/webgpu'\nimport { Model } from '../Model'\nimport type { Subscribe } from '../../shared-utils/Subscribe'\nimport type { Five } from '@realsee/five-webgpu'\nimport { getMouseGroup } from '../utils/mouseGroup'\nimport { UIController, type UIControllerParams } from '../Modules/UIController'\nimport { GuideController, type GuideControllerParams } from '../Modules/GuideController'\nimport { ShortcutKeyController } from './ShortcutKeyController'\nimport safeObj from '../../shared-utils/safeObj'\nimport { Magnifier } from '../../shared-utils'\nimport type { MagnifierParameter } from '../../shared-utils'\nimport { isTouchDevice } from '../../shared-utils/isTouchDevice'\nimport type Area from '../Model/area'\nimport * as BasePlugin from '../../base/BasePlugin'\nimport type { PointSelectorConfig } from '../../shared-utils/three/PointSelector'\n\n// 新增Mixed模式专用于mobile端\nexport type Mode = 'Watch' | 'Edit' | 'Mixed' | 'View'\n\n// 参数\nexport interface PanoMeasureParameterType extends Partial<Config> {\n editParams?: EditParameter\n pointSelectorConfig?: PointSelectorConfig\n openParams?: OpenParameter\n useUIController?: boolean | UIControllerParams\n useGuideController?: boolean | GuideControllerParams\n // TODO: 这个参数传递的太恶心了,优化一下\n userDistanceItemCreator?: () => UserDistanceItem\n}\n\nexport default class PanoMeasureController extends BasePlugin.Controller<\n BasePlugin.State,\n BasePlugin.EventMap<BasePlugin.State> & PanoMeasurePluginEvent\n> {\n public state: BasePlugin.State = { enabled: true }\n public hasOpen = false\n public magnifier: Magnifier\n public controller: WatchController | EditController | MixedController | ViewController | null = null\n /** 允许的测量类型 */\n public allowMeasureType: Array<MeasureType>\n /** 当前的测量类型 */\n public currentMeasureType: MeasureType | null\n\n private model: Model\n private group: Group\n private config: Config\n\n private isMobile: boolean\n private useUIController?: UIController\n private params: PanoMeasureParameterType\n private useGuideController?: GuideController\n private container = document.createElement('div')\n private shortcutKeyController?: ShortcutKeyController\n\n public constructor(five: Five, params: PanoMeasureParameterType) {\n super(five)\n this.five = five\n // TODO: 最早的设计里面 params 应该是一个只读值,但是后面一直在改这个值,考虑删掉\n this.params = params\n this.config = omit(params, ['openParams', 'pointSelectorConfig'])\n this.model = new Model(this.config)\n // isMobile\n this.isMobile = params?.openParams?.isMobile ?? false\n // magnifier\n this.magnifier = new Magnifier(\n five,\n params.pointSelectorConfig?.helper?.magnifierParams ?? { width: 190, height: 190, scale: 2 },\n )\n // measure type\n this.allowMeasureType = Array.from(new Set(params.editParams?.allowMeasureType ?? ['line']))\n this.currentMeasureType = this.allowMeasureType[0] ?? 'line'\n // ==================== Group ====================\n this.group = new Group()\n this.group.name = 'plugin-measure-group'\n this.container.classList.add('five-plugin-measure-container')\n this.container.style.position = 'absolute'\n this.container.style.left = '0'\n this.container.style.top = '0'\n this.container.style.visibility = 'hidden'\n this.container.style.pointerEvents = 'none'\n this.container.style.width = '100%'\n this.container.style.height = '100%'\n this.container.style.opacity = '0'\n this.container.style.zIndex = '1'\n\n const pointSelectorMode: PointSelectorMode = params.editParams?.pointSelectorMode ?? (isTouchDevice ? 'fixed' : 'cursor')\n\n // 加载UI\n // TODO: 优化 UIController 初始化逻辑\n const openParams = this.params.openParams ?? {}\n if (this.params.useUIController !== false) {\n const uiControllerParams = {\n container: this.container,\n openParams,\n i18n: params.i18n,\n pointSelectorMode,\n useNewUI: this.allowMeasureType.length > 1,\n ...safeObj(this.params.useUIController),\n }\n this.useUIController = new UIController(this, uiControllerParams)\n }\n if (this.params.useGuideController !== false) {\n const guideControllerParams = {\n container: this.container,\n pointSelectorMode,\n i18n: params.i18n,\n ...safeObj(this.params.useGuideController),\n }\n this.useGuideController = new GuideController(this, guideControllerParams)\n }\n }\n\n public appendTo(parent: HTMLElement) {\n parent.append(this.container)\n }\n\n public clear() {\n this.model.clear()\n }\n\n public dispose() {\n this.disable()\n this.clear()\n this.useUIController?.dispose()\n this.magnifier?.dispose()\n this.five.needsRender = true\n }\n\n /** 加载数据\n * @description 数据加载时会覆盖当前已保存的数据\n * @description 如果当前正在编辑中,会自动退出并保存编辑\n */\n public load(data: MeasurePluginData | MeasurePluginServerData) {\n let transformedData: MeasurePluginData = data as any\n if ((data as any).list) {\n const polylines = (data as MeasurePluginServerData).list.map((item) => item.polyline)\n transformedData = {\n polylines: polylines.map((polyline) => ({\n ...polyline,\n visibleFiveMode: polyline.visibleFiveMode ?? ['Panorama'],\n })),\n }\n }\n\n this.model.parse(transformedData)\n this.save()\n }\n\n /** 插件功能入口\n * @description 会隐藏鼠标的默认聚焦环\n * @description 会隐藏当前 VR 内的点位展示\n */\n public override enable(config?: { mode: Mode }): void {\n if (this.hasOpen) return\n\n if (!this.container.parentElement && this.five.getElement()?.parentElement) {\n this.appendTo(this.five.getElement()!.parentElement!)\n }\n\n this.state.enabled = true\n this.hasOpen = true\n\n this.group.matrix.copy(this.workUtil.transform)\n this.group.matrix.decompose(this.group.position, this.group.quaternion, this.group.scale)\n this.group.updateMatrixWorld()\n\n this.five.scene.add(this.group)\n\n // TODO: 为什么用透明度解决,该销毁的 DOM 销毁\n // 修改透明度\n this.container.style.visibility = 'visible'\n this.container.style.opacity = '1'\n if (config?.mode) {\n this.changeMode(config.mode)\n } else if (this.isMobile) {\n this.changeMode('Mixed')\n } else {\n this.changeMode('Watch')\n }\n if (config?.mode !== 'View') {\n this.useUIController?.show()\n this.useGuideController?.show()\n }\n this.shortcutKeyController = new ShortcutKeyController(this, this.five)\n this.hooks.emit('enable', true)\n }\n\n /** 关闭插件功能\n * @description 清除标尺线条\n * @description 还原点位展示和默认鼠标 UI\n */\n public disable = (): void => {\n this.hasOpen = false\n this.state.enabled = false\n // 修改透明度\n this.container.style.visibility = 'hidden'\n this.container.style.opacity = '0'\n // 展示点位和鼠标聚焦环\n this.controller?.dispose()\n this.useUIController?.hide()\n this.useGuideController?.hide()\n this.shortcutKeyController?.dispose()\n this.controller = null\n this.five.helperVisible = true\n this.five.scene.remove(this.group)\n this.five.needsRender = true\n this.hooks.emit('disable', true)\n }\n\n public getCurrentMode = (): Mode | null => {\n if (this.controller instanceof EditController) return 'Edit'\n if (this.controller instanceof WatchController) return 'Watch'\n if (this.controller instanceof MixedController) return 'Mixed'\n if (this.controller instanceof ViewController) return 'View'\n return null\n }\n\n /** 变更场景\n * @description 如果从编辑场景改变到观看场景,不会自动保存,默认丢弃所有改动\n */\n public changeMode = (mode: Mode) => {\n if (!this.hasOpen) return\n if (this.getCurrentMode() === mode) return\n this.controller?.dispose()\n const controllerMap = {\n View: ViewController,\n Watch: WatchController,\n Edit: EditController,\n Mixed: MixedController,\n }\n if (!controllerMap[mode]) throw new Error('不存在的 Mode')\n const controllerParams = this.createControllerParams()\n this.controller = new controllerMap[mode](controllerParams)\n if (mode === 'View') {\n this.useUIController?.hide()\n this.useGuideController?.hide()\n } else {\n this.useUIController?.show()\n this.useGuideController?.show()\n }\n this.hooks.emit('modeChange', mode)\n }\n\n /**\n * @description: 切换测量的类型\n */\n public changeMeasureType = (measureType: MeasureType) => {\n this.currentMeasureType = measureType\n this.hooks.emit('measureTypeChange', measureType)\n }\n\n /** 进入编辑模式 */\n public edit(measureType?: MeasureType) {\n if (measureType) this.changeMeasureType(measureType)\n const mode: Mode = this.isMobile ? 'Mixed' : 'Edit'\n this.changeMode(mode)\n }\n\n /** 撤销编辑 */\n public revoke(): void {\n if (!(this.controller instanceof EditController)) return\n this.controller.revoke()\n return\n }\n\n public removePolyline(polyline: Polyline) {\n this.model.removePolyline(polyline)\n }\n\n public removeArea(area: Area) {\n this.model.removeArea(area)\n }\n\n public removePolylineByID(id: string) {\n const polyline = this.model.getPolylineByID(id)\n polyline && this.model.removePolyline(polyline)\n }\n\n public getPolylineByID(id: string) {\n return this.model.getPolylineByID(id)\n }\n\n public getEditedPolyline(): Polyline | undefined {\n return this.controller instanceof EditController || this.controller instanceof MixedController\n ? (this.controller as EditController | MixedController).polyline\n : undefined\n }\n\n /**\n * 高亮当前线段\n */\n public highlightLine(lineID: string) {\n if (this.getCurrentMode() !== 'Watch') return false\n const line = this.model.getLineByID(lineID)\n if (!line) return false\n ;(this.controller as WatchController).highlightLine(line)\n return true\n }\n\n public clearHighlightLines() {\n if (this.getCurrentMode() !== 'Watch') return false\n ;(this.controller as WatchController).clearHighlightLines()\n return true\n }\n\n /** 保存编辑\n * @description 以下情况可能报错\n */\n public save(config?: { mode?: Mode }) {\n if (!(this.controller instanceof EditController) && !(this.controller instanceof MixedController)) return this\n const mode = config?.mode ?? 'View'\n const areas = this.controller.model.areas\n\n if (this.controller instanceof EditController) {\n this.controller.complete()\n } else {\n areas.forEach((area) => {\n area.showArea()\n this.model.addArea(area)\n })\n }\n this.changeMode(mode)\n return this\n }\n\n /** Mixed 模式才有用,添加起点 */\n public addStartPoint() {\n if (!(this.controller instanceof MixedController)) return\n this.hooks.emit('willChangeState', 'watching', 'editing')\n }\n\n /** Mixed 模式才有用,添加终点 */\n public addEndPoint() {\n if (!(this.controller instanceof MixedController)) return\n this.hooks.emit('willChangeState', 'editing', 'watching')\n }\n\n /** 导出数据 */\n public toJson() {\n return this.model.toJson()\n }\n\n public changeConfigs(config: Config) {\n Object.assign(this.config, config)\n this.controller?.updateDistanceUI()\n this.controller?.updateAreaUI()\n }\n\n /** 设置线段的文本 */\n public setCustomText(lineID: string, text: string) {\n const line = this.model.getLineByID(lineID)\n if (!line) throw new Error('不存在的线段')\n line.setText(text)\n this.controller?.updateDistanceUI()\n }\n\n private createControllerParams(): ControllerParams {\n const openParams = this.params.openParams ?? {}\n const editParams = this.params.editParams ?? {}\n openParams.isMobile = this.isMobile\n return {\n five: this.five,\n hook: this.hooks,\n group: this.group,\n model: this.model,\n config: this.config,\n magnifier: this.magnifier,\n container: this.container,\n workUtil: this.workUtil,\n openParams,\n editParams,\n pointSelectorConfig: this.params.pointSelectorConfig,\n getMeasureType: () => this.currentMeasureType,\n mouseGroup: getMouseGroup({ ...openParams.crossHairParameter }),\n userDistanceItemCreator: this.params.userDistanceItemCreator,\n }\n }\n}\n","import type { FivePlugin } from '@realsee/five-webgpu'\nimport MeasureController, { type PanoMeasureParameterType } from './Controller'\nimport Magnifier from './Modules/Magnifier'\n\nexport const PanoMeasurePlugin: FivePlugin<PanoMeasureParameterType, PanoMeasureReturnType> = function PanoMeasurePlugin(five, params) {\n return new MeasureController(five, params)\n}\n\nexport default PanoMeasurePlugin\nexport { Magnifier }\nexport { Model as PanoMeasurePluginModel } from './Model'\nexport { default as PanoMeasurePluginPoint } from './Model/point'\nexport { default as PanoMeasurePluginLine } from './Model/line'\nexport { Polyline as PanoMeasurePluginPolyline } from './Model/polyline'\n\n// 类型导出\nexport type PanoMeasureReturnType = MeasureController\nexport type { PanoMeasurePluginEvent } from './typings/event.type'\nexport type {\n LineJson as PanoMeasurePluginLineJson,\n PointJson as PanoMeasurePluginPointJson,\n PolylineJson as PanoMeasurePluginPolylineJson,\n OpenParameter as PanoMeasurePluginOpenParameter,\n} from './typings/data'\nexport type { PanoMeasureParameterType } from './Controller'\n"],"mappings":"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"}
1
+ {"version":3,"file":"pano-measure-BIgCWkVJ.js","names":["image","deleteBg","deleteSvg","deleteHoverBg","disableFiveEvent","Subscribe","htmlString","TWEEN.Tween","root","$.from_html","root_1","root_2","root_3","$.mutable_source","$.prop","$.get","$.sibling","$.child","$.set_style","$.index","$.untrack","$.mutate","$.set_class","$.set","$.pop","root","$.from_html","$.prop","root","$.from_html","root_1","$.prop","$.mutable_source","$.child","$.deep_read_state","$.untrack","$.sibling","$.set_class","$.get","$.set_style","$.derived_safe_equal","root","$.from_html","root_1","root_2","$.mutable_source","$.prop","$.get","$.deep_read_state","$.child","$.sibling","$.index","$.set_style","$.untrack","$.mutate","$.set_class","$.set","root","$.from_html","root_1","$.mutable_source","$.prop","$.deep_read_state","$.child","$.only_child","$.set_text","$.set_style","$.get","root","$.from_html","$.prop","$.mutable_source","$.get","$.child","$.deep_read_state","$.untrack","$.sibling","$.derived_safe_equal","$.set_class","$.set_style","mobileHTMLString","htmlString","$.from_html","$.prop","$.mutable_source","$.get","$.deep_read_state","$.comment","$.first_child","$.child","$.only_child","$.set","$.set_text","objectAssignDeep","BasePlugin.Controller","MeasureController","__toESM","isTouchDevice","Magnifier","html_default","PointSelector","getGeometryInfo","calculateThreeMouse","isIntersecting","generatePolygonGeometry","getFiveModel","centerPoint","IObject3D","throttle","notNil","isNil","uuid","Tween","Easing","requestAnimationFrameInterval","Controller","if_block","template_effect","only_child","child","event","append","comment","onDestroy","from_html","set","deep_read_state","key","legacy_pre_effect","untrack","legacy_pre_effect_reset","mutable_source","sibling","mutate","transition","each","bind_prop","derived_safe_equal","push","set_text","onMount","bind_this","set_class","prop","init","set_style","first_child","pop","reset","mountComponent","index","get","require_objectAssignDeep","safeObj","FiveLine","fade","omit","THREE","lineWidth","lightLineWidth","lineColor","Color","lightLineColor","pointColor","lightPointColor","pointSize","lightPointSize","pointImage","pointTexture","getPointTexture","TextureLoader","normalLineOpts","lightLineOpts","createLine","opts","lineRenderOrder","pointsRenderOrder","line","start","end","pointMaterial","createLineMesh","point","anotherPoint","type","fiveLine","isNDCPointInScreen","ndcPoint","x","y","z","isNDCPointInFront","createContentDom","contentDom","params","createContainerDom","containerDom","ItemDom","canSelect","container","fiveElement","five","screenWidth","screenHeight","ndcDomPosition","left","top","DistanceItem","style","startPoint","endPoint","distance","customDefaultText","customDistanceText","halfScreenWidth","halfScreenHeight","p","ndcStartPosition","ndcEndPosition","screenStartPosition","Vector2","screenEndPosition","lineScreenLength","cameraDistance","fov","sseDenominator","scaleFactor","deg","offsetY","content","\"five\"","Line","model","Subscribe","modelPolyline","polyline","id","text","Point","Vector3","position","preventDefault","BaseController","area","intersection","mesh","positionVector","lookAtVector","Polyline","pointsSet","config","lastPoint","lastLine","lines","item","_id","data","createPointCache","pointData","anotherPointData","getPoint","pointMap","cachePoint","getAllPoints","blankGeometry","PolygonMesh","materialFront","materialBackground","meshFront","meshBackground","points","newGeometry","AreaItem","geometry","_geometry","geometryInfo","center","fix","unit","Area","lineStart","lineEnd","svg","image$1","image","DeleteDom","deleteSvgDom","element","target","ndcPoints","xArray","yArray","centerX","maxY","wrapper","centerScreenX","maxScreenY","k","centerScreenY","closestPointOnLine","tA","linePoints","tB","tC","tD","tParam","tXx","tYy","samePointAt","point1","point2","disableFiveEvent$1","EditController","isArea","isLine","_polyline","revokedLine","noPolygon","currentPosition","nowPoint","getAdherePoints","pointHelper","pointSelectorInstance","normal","intersectPoint","offset","xLine","yLine","autoEndLineLength","autoEndAreaLength","dashedStart","dashedEnd","mousePosition","perpendicularDashedStart","perpendicularDashedEnd","segments","intersected0","intersected2","newPoints","intersections","raycaster","a","b","intersectionObject","camera","ndcTarget","targetScreenPosition","screenLines","ndcStartPoint","ndcEndPoint","startScreenPosition","endScreenPosition","closestScreenLine","closestPoint","closestLine","highlightLines","clickPosition","firstLine","ViewController","mode","panoIndex","ndc2Screen","ndcPosition","containerSize","findClosestPoint","tapPoint","maxDistance","getPointFromHammerEvent","clientX","clientY","clientRect","clientWidth","clientHeight","disableFiveEvent","WatchController","m","Hammer","hammer","_area","_lines","mouse","editPointState","Raycaster","Model","Subscribe$1","polylineData","polylines","noop","mobileTextureUrl","pcTextureUrl","getMouseGroup","isMobile","useNormalVector","ballColor","group","Group","planGeometry","PlaneGeometry","planTextureUrl","planTexture","SRGBColorSpace","LinearFilter","planMaterial","MeshBasicMaterial","planMesh","Mesh","zPath","CurvePath","LineCurve3","zGeometry","TubeGeometry","colors","uv","i","BufferAttribute","zMaterial","zMesh","ballGeometry","SphereGeometry","ballMaterial","DoubleSide","ballMesh","RangePieceController","RingGeometry","newState","aimRef","width","height","mouseXY","face","matrix","scale","vector","cameraPos","firstEasing","from","to","stop","firstTween","opacity","time","value","MixedController","disposer","startIconImage","endIconImage","mobileHTML_default","HTML_default","uiWrapperStyle","operatingSpaceStyle","controllerBackgroundStyle","mainItemStyle","exitItemStyle","mainIconStyle","exitIconStyle","textStyle","MainBtnController","measureController","revokeTextDom","exitTextDom","mainTextDom","mainItem","mainIcon","MobileMainBtnController","Revoke","revokeIcon","revokeItem","root$6","root_1$4","root_2$2","root_3$1","Switcher0","$$props","activeButton","setIndex","activeIndex","options","onChange","elementList","activeButtonWidth","activeButtonLeft","$$exports","div","node","consequent","div_1","styles","$$anchor","$$render","div_2","classes","div_3","classes_1","div_4","node_1","consequent_1","span","styles_1","option","$$value","root$5","Exit","onClick","$$args","IconUndo","IconOk","IconLine","IconArea","root$4","root_1$3","Controller0","showExit","i18n","canRevoke","setSwitcherActiveIndex","handleModeChange","showController","complete","handlePointsChange","handleComplete","div_5","div_6","div_7","text_1","$0","$1","div_8","node_2","root$3","root_1$2","root_2$1","Switcher1","defaultKey","setAnimeResult","newActiveButtonLeft","styles_2","root$2","root_1$1","CircleButton","bgImage","color","root$1","root_1","root_2","root_3","Controller1","buttonTextMap","buttonColorMap","showButton","allowAddPoint","buttonState","lastButtonState","currentMeasureType","changeButtonState","addPoint","state","onAllowAddPointStateChange","readyComplete","notReadyComplete","setStartState","onMeasureTypeChange","measureType","onRevoke","node_3","consequent_2","node_5","consequent_3","div_9","UIController","useNewUI","textDoms","bgDom","operatingSpaceDom","exitIcon","exitItem","onMouseEnter","onMouseLeave","handleClick","import_objectAssignDeep","root","Tip","tips","tipStyle","visible","textDom","getTip","currentType","tip","setTip","clear","pointsChange","fragment","pcTip","mobileTip","GuideController","ShortcutKeyController","PanoMeasureController","pointSelectorMode","openParams","uiControllerParams","guideControllerParams","transformedData","controllerMap","controllerParams","lineID","areas","editParams","PanoMeasurePlugin"],"sources":["../../src/PanoMeasurePlugin/utils/constants.ts","../../src/PanoMeasurePlugin/utils/line.ts","../../src/PanoMeasurePlugin/utils/isNDCPointInScreen.ts","../../src/PanoMeasurePlugin/utils/dom/base.ts","../../src/PanoMeasurePlugin/utils/dom/distanceItem.ts","../../src/PanoMeasurePlugin/Model/line.ts","../../src/PanoMeasurePlugin/Model/point.ts","../../src/PanoMeasurePlugin/utils/ironbox.ts","../../src/PanoMeasurePlugin/Controller/BaseController.ts","../../src/PanoMeasurePlugin/Model/polyline.ts","../../src/PanoMeasurePlugin/Model/polygon.ts","../../src/PanoMeasurePlugin/utils/dom/areaDom.ts","../../src/PanoMeasurePlugin/Model/area.ts","../../src/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete.svg.ts","../../src/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete_bg.png.ts","../../src/PanoMeasurePlugin/Modules/DeleteDom/_Assets/delete_hover_bg.png.ts","../../src/PanoMeasurePlugin/Modules/DeleteDom/index.ts","../../src/PanoMeasurePlugin/utils/math.ts","../../src/PanoMeasurePlugin/Controller/EditController.ts","../../src/PanoMeasurePlugin/Controller/ViewController.ts","../../src/PanoMeasurePlugin/utils/ndc2Screen.ts","../../src/PanoMeasurePlugin/utils/findClosestPoint.ts","../../src/shared-utils/getPointFromHammerEvent.ts","../../src/PanoMeasurePlugin/Controller/WatchController.ts","../../src/PanoMeasurePlugin/Model/index.ts","../../src/shared-utils/noop.ts","../../src/PanoMeasurePlugin/utils/mouseGroup.ts","../../src/PanoMeasurePlugin/Modules/rangePiece/index.ts","../../src/PanoMeasurePlugin/Controller/MixedController.ts","../../src/PanoMeasurePlugin/Modules/UIController/mobileHTML.ts","../../src/PanoMeasurePlugin/Modules/UIController/HTML.ts","../../src/PanoMeasurePlugin/Modules/UIController/style.ts","../../src/PanoMeasurePlugin/Modules/UIController/MainBtnController.ts","../../src/PanoMeasurePlugin/Modules/UIController/mobileMainBtnController.ts","../../src/PanoMeasurePlugin/Modules/UIController/Revoke/index.ts","../../src/PanoMeasurePlugin/Components/Common/Switcher0.svelte","../../src/PanoMeasurePlugin/Components/Common/Exit.svelte","../../src/PanoMeasurePlugin/Components/Common/icons/index.ts","../../src/PanoMeasurePlugin/Components/Controller0.svelte","../../src/PanoMeasurePlugin/Components/Common/Switcher1.svelte","../../src/PanoMeasurePlugin/Components/Common/CircleButton.svelte","../../src/PanoMeasurePlugin/Components/Controller1.svelte","../../src/PanoMeasurePlugin/Modules/UIController/index.ts","../../src/PanoMeasurePlugin/Components/Tip.svelte","../../src/PanoMeasurePlugin/Components/Tip.svelte","../../src/PanoMeasurePlugin/Modules/GuideController.ts","../../src/PanoMeasurePlugin/Controller/ShortcutKeyController.ts","../../src/PanoMeasurePlugin/Controller/index.ts","../../src/PanoMeasurePlugin/index.ts"],"sourcesContent":["import type { ICreateLineOpts } from './line'\nimport { TextureLoader, Color } from 'three/webgpu'\n\nconst lineWidth = 1\nconst lightLineWidth = 3\nconst lineColor = new Color(0xffffff)\nconst lightLineColor = new Color(0x6386ff)\nconst pointColor = new Color(0xffffff)\nconst lightPointColor = new Color(0x6386ff)\nconst pointSize = 6\nconst lightPointSize = 8\nconst pointImage =\n 'data:image/png;base64,' +\n 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAIVBMVEUAAAD////////////////////////////////////////PIev5AAAACnRSTlMAG/Py2baba05un7UgfgAAAHJJREFUKM9joBpgLHVSCRdA4metAoJlCJHmVWBgAeNzroKCCVCBLpjACqgJVjCBxRBT2FbBQQJYQAohsBAsUIUQWA4WiEIILAULeCEEloAFtBACizAEMLRgGIphLabDMJ2O6TlM72MGECIIMQIZIxqoBQCPvpJ/e9FaAAAAAABJRU5ErkJggg=='\nlet pointTexture: ReturnType<TextureLoader['load']> | undefined\n\nexport function getPointTexture() {\n return (pointTexture ??= new TextureLoader().load(pointImage))\n}\n\nexport const normalLineOpts: ICreateLineOpts = {\n pointSize,\n lineWidth,\n lineColor,\n pointColor,\n lineRenderOrder: 20,\n pointsRenderOrder: 20,\n}\n\nexport const dashLineOpts: ICreateLineOpts = { ...normalLineOpts, dashed: true }\n\nexport const lightLineOpts: ICreateLineOpts = {\n pointSize: lightPointSize,\n lineWidth: lightLineWidth,\n lineColor: lightLineColor,\n pointColor: lightPointColor,\n lineRenderOrder: 10,\n pointsRenderOrder: 10,\n}\n","import { FiveLine } from '../../shared-utils/five/FiveLine'\nimport type Line from '../Model/line'\nimport { getPointTexture, lightLineOpts, normalLineOpts } from './constants'\nimport type { PointsMaterial, Texture, Vector3 } from 'three/webgpu'\nimport { Color } from 'three/webgpu'\n\ntype ISetMaterialOpts = Parameters<FiveLine['setMaterial']>[0]\n\nexport interface ICreateLineOpts extends ISetMaterialOpts {\n hasPoint?: boolean\n pointSize?: number\n lineWidth?: number\n pointTexture?: Texture\n lineRenderOrder?: number\n pointsRenderOrder?: number\n lineColor?: Color | string | number\n pointColor?: Color | string | number\n}\n\nexport function createLine(start: Vector3, end: Vector3, opts?: ICreateLineOpts) {\n const lineWidth = opts?.lineWidth ?? 2\n const lineColor = opts?.lineColor ?? (new Color(0xffffff) as any)\n const pointSize = opts?.pointSize ?? 5\n const lineRenderOrder = opts?.lineRenderOrder ?? 10\n const pointsRenderOrder = opts?.lineRenderOrder ?? 20\n const line = new FiveLine(start, end)\n // set line\n line.setMaterial({ linewidth: lineWidth, color: lineColor })\n line.line.material.depthTest = false\n line.line.material.transparent = true\n line.line.renderOrder = lineRenderOrder\n // set point\n line.points.renderOrder = pointsRenderOrder\n const pointMaterial = line.points.material as PointsMaterial\n pointMaterial.depthTest = false\n pointMaterial.size = pointSize\n if (opts?.pointColor !== undefined) pointMaterial.color.set(opts.pointColor)\n if (opts?.pointTexture) pointMaterial.map = opts.pointTexture\n return line\n}\n\nexport function createLineMesh(line: Line, type: 'normal' | 'light') {\n const [point, anotherPoint] = line.points\n const opts = type === 'light' ? lightLineOpts : normalLineOpts\n const fiveLine = createLine(point.position, anotherPoint.position, { ...opts, pointTexture: getPointTexture() })\n fiveLine.name = 'normalLine_' + line.id\n return fiveLine\n}\n","import type { Vector3 } from 'three/webgpu'\n\nexport default function isNDCPointInScreen(ndcPoint: Vector3) {\n const { x, y, z } = ndcPoint\n if (Math.abs(x) > 1 || Math.abs(y) > 1 || Math.abs(z) > 1) return false\n return true\n}\n\nexport function isNDCPointInFront(ndcPoint: Vector3) {\n const { z } = ndcPoint\n if (Math.abs(z) > 1) return false\n return true\n}\n","import type { Vector3 } from 'three/webgpu'\nimport { isNDCPointInFront } from '../isNDCPointInScreen'\nimport type { Five } from '@realsee/five-webgpu'\n\nexport interface ItemDomParams {\n clickCallback?: (event: MouseEvent, item: ItemDom) => unknown\n containerStyle?: Partial<CSSStyleDeclaration>\n contentStyle?: Partial<CSSStyleDeclaration>\n}\n\nfunction createContentDom(params?: { style?: Partial<CSSStyleDeclaration> }) {\n const contentDom = document.createElement('div')\n contentDom.setAttribute(\n 'style',\n `backdrop-filter: blur(4px);-webkit-backdrop-filter: blur(4px);-webkit-tap-highlight-color: rgba(0,0,0,0);`,\n )\n contentDom.style.width = 'max-content'\n contentDom.style.padding = '3px 6px'\n contentDom.style.lineHeight = '1'\n contentDom.style.textAlign = 'center'\n contentDom.style.transform = 'translate(-50%, -50%)'\n contentDom.style.fontSize = '14px'\n contentDom.style.color = '#fff'\n contentDom.style.cursor = 'pointer'\n contentDom.style.userSelect = 'none'\n if (params?.style) Object.assign(contentDom.style, params?.style)\n\n return contentDom\n}\n\nfunction createContainerDom(params?: { id?: string; style?: Partial<CSSStyleDeclaration> }) {\n const containerDom = document.createElement('div')\n if (params?.id) containerDom.id = params?.id\n containerDom.classList.add('five-plugin-measure__distance')\n containerDom.style.position = 'absolute'\n containerDom.style.left = '0'\n containerDom.style.top = '0'\n containerDom.style.width = '0'\n containerDom.style.height = '0'\n containerDom.style.transform = 'translate(-10px, -10px)' // 狗屎代码\n containerDom.style.transformOrigin = 'left top'\n if (params?.style) Object.assign(containerDom.style, params.style)\n return containerDom\n}\n\nexport abstract class ItemDom {\n public ndcPosition: Vector3 | null\n\n protected contentDom: HTMLElement\n protected containerDom: HTMLElement\n protected params: ItemDomParams\n protected canSelected: boolean\n\n public constructor(params: ItemDomParams) {\n this.params = params\n this.contentDom = createContentDom({ style: params.contentStyle })\n this.containerDom = createContainerDom({ style: params.containerStyle })\n this.setCanSelect(true)\n }\n\n public handleClick = (e: MouseEvent) => {\n this.params.clickCallback?.(e, this)\n }\n\n public setCanSelect(canSelect: boolean) {\n this.canSelected = canSelect\n this.containerDom.style.pointerEvents = canSelect ? 'all' : 'none'\n }\n\n public highlight() {\n this.contentDom.style.border = '0.5px solid #95AEFF'\n this.contentDom.style.background = 'linear-gradient(90deg, #95AEFF 0%, #6386FF 100%)'\n }\n\n public unHighlight() {\n this.contentDom.style.border = '0.5px solid rgba(255,255,255,0.6)'\n this.contentDom.style.background = 'rgba(195,195,195,0.70)'\n }\n\n public appendTo(container: Element) {\n container.appendChild(this.containerDom)\n this.containerDom.addEventListener('click', this.handleClick)\n return this\n }\n\n public remove() {\n this.contentDom.removeEventListener('click', this.handleClick)\n this.containerDom.remove()\n }\n\n public show() {\n this.containerDom.style.visibility = 'visible'\n }\n\n public hide() {\n this.containerDom.style.visibility = 'hidden'\n }\n\n public tempHide() {\n this.containerDom.style.opacity = '0'\n }\n\n public tempShow() {\n this.containerDom.style.opacity = '1'\n }\n\n /**\n * @description: camera update 的时候,更新dom的位置\n */\n public updateDomPosition(five: Five) {\n if (!this.ndcPosition) {\n this.tempHide()\n return\n }\n\n const fiveElement = five.getElement()\n if (!fiveElement) return\n\n const screenWidth = fiveElement.clientWidth\n const screenHeight = fiveElement.clientHeight\n\n const ndcDomPosition = this.ndcPosition.clone().project(five.camera)\n if (!isNDCPointInFront(ndcDomPosition)) {\n this.tempHide()\n return\n }\n\n const left = ((ndcDomPosition.x + 1) / 2) * screenWidth\n const top = (-(ndcDomPosition.y - 1) / 2) * screenHeight\n\n this.containerDom.style.transform = `translate(${left}px, ${top}px)`\n this.tempShow()\n }\n}\n","import type { ItemDomParams } from './base'\nimport { ItemDom } from './base'\nimport type Line from '../../Model/line'\nimport type { Five } from '@realsee/five-webgpu'\nimport { Vector2 } from 'three/webgpu'\nimport { isNDCPointInFront } from '../isNDCPointInScreen'\nimport type { Polyline } from '../../Model/polyline'\nimport { centerPoint } from '../../../shared-utils/three/centerPoint'\n\nexport interface UserDistanceItem {\n element: Element\n highlight: () => void\n unHighlight: () => void\n update: (params: { line: Line; polyline: Polyline }) => void\n}\n\ninterface DistanceItemParams extends ItemDomParams {\n line: Line\n userDistanceItem?: UserDistanceItem\n}\n\nexport class DistanceItem extends ItemDom {\n protected declare params: DistanceItemParams\n private line: Line\n private lastFOV: number | undefined\n private cameraUpdateHandler: (() => void) | null = null\n\n public constructor(params: DistanceItemParams) {\n params.contentStyle = {\n ...params.contentStyle,\n ...{\n background: '#FFFFFF',\n color: '#041066',\n fontFamily: 'Arial-BoldMT',\n fontWeight: 'BoldMT',\n letterSpacing: '0',\n lineHeight: '20px',\n padding: '2px 8px',\n borderRadius: '12px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n '--distance-scale': '1' /* Default scale if not provided */,\n transition: 'font-size 0.5s ease' /* Smooth transition for font size */,\n },\n }\n super(params)\n this.line = params.line\n this.params.userDistanceItem?.element\n ? this.containerDom.appendChild(this.params.userDistanceItem.element)\n : this.containerDom.appendChild(this.contentDom)\n\n if (!document.getElementById('PanoMeasurePluginFontSizes')) {\n const style = document.createElement('style')\n style.id = 'PanoMeasurePluginFontSizes'\n document.head.appendChild(style)\n style.innerHTML = `\n .pano-measure-item-content {\n transition: font-size 0.5s ease; /* Smooth transition for font size */\n }\n \n /* sm screen */\n @media screen and (max-width: 499px) {\n .pano-measure-item-content {\n font-size: calc(12px + (14px - 12px) * var(--distance-scale));\n }\n }\n \n /* md screen */\n @media screen and (min-width: 500px) and (max-width: 929px) {\n .pano-measure-item-content {\n font-size: calc(12px + (14px - 12px) * var(--distance-scale));\n }\n }\n \n /* lg screen */\n @media screen and (min-width: 930px) and (max-width: 1365px) {\n .pano-measure-item-content {\n font-size: calc(14px + (16px - 14px) * var(--distance-scale));\n }\n }\n \n /* xl screen */\n @media screen and (min-width: 1366px) and (max-width: 2549px) {\n .pano-measure-item-content {\n font-size: calc(14px + (16px - 14px) * var(--distance-scale));\n }\n }\n \n /* xxl screen */\n @media screen and (min-width: 2550px) {\n .pano-measure-item-content {\n font-size: calc(0.875rem + (1rem - 0.875rem) * var(--distance-scale));\n }\n }\n `\n }\n\n this.contentDom.classList.add('pano-measure-item-content')\n }\n\n public appendTo(container: Element) {\n super.appendTo(container)\n // Register camera update handler when added to DOM\n if (!this.cameraUpdateHandler) {\n this.cameraUpdateHandler = () => this.onCameraUpdate()\n // Find the Five instance through the model\n const five = this.getFiveInstance()\n if (five) {\n five.on('cameraUpdate', this.cameraUpdateHandler)\n five.on('cameraFovUpdate', this.cameraUpdateHandler)\n five.on('panoArrived', this.onPanoChange)\n }\n }\n return this\n }\n\n public remove() {\n // Clean up camera update handler when removed\n if (this.cameraUpdateHandler) {\n const five = this.getFiveInstance()\n if (five) {\n five.off('cameraUpdate', this.cameraUpdateHandler)\n five.off('cameraFovUpdate', this.cameraUpdateHandler)\n five.off('panoArrived', this.onPanoChange)\n }\n this.cameraUpdateHandler = null\n }\n super.remove()\n }\n\n /** 获取内容文本 */\n public getCurrentContent() {\n if (this.line.points.length < 2) return ''\n const [startPoint, endPoint] = this.line.points\n const distance = startPoint.position.clone().distanceTo(endPoint.position)\n const customDefaultText = this.line.text ?? this.line.model.config?.defaultText\n const customDistanceText = this.line.model.config?.getDistanceText?.(distance)\n const customText = customDefaultText ?? customDistanceText\n // 优先级:用户自定义默认文本 > 用户自定义距离文本 > 默认文本\n return customText ?? distance.toFixed(2) + 'm'\n }\n\n public update(five: Five) {\n if (this.line.mesh.visible === false) {\n this.hide()\n return\n }\n const fiveElement = five.getElement()\n if (!fiveElement) return\n const screenWidth = fiveElement.clientWidth\n const screenHeight = fiveElement.clientHeight\n const halfScreenWidth = screenWidth / 2\n const halfScreenHeight = screenHeight / 2\n if (this.line.points.length < 2) return\n const [startPoint, endPoint] = this.line.points.map((p) => p.position.clone().applyMatrix4(this.line.mesh.matrixWorld))\n const ndcStartPosition = startPoint.clone().project(five.camera)\n const ndcEndPosition = endPoint.clone().project(five.camera)\n const ndcDomPosition = centerPoint(startPoint, endPoint).clone().project(five.camera)\n const screenStartPosition = new Vector2(ndcStartPosition.x * halfScreenWidth, ndcStartPosition.y * halfScreenHeight)\n const screenEndPosition = new Vector2(ndcEndPosition.x * halfScreenWidth, ndcEndPosition.y * halfScreenHeight)\n const lineScreenLength = screenStartPosition.distanceTo(screenEndPosition)\n const visible = (() => {\n // 对于超过近平面和远平面的点,计算会有问题\n if (Math.abs(ndcStartPosition.z) > 1 || Math.abs(ndcEndPosition.z) > 1) return false\n if (!isNDCPointInFront(ndcStartPosition) && !isNDCPointInFront(ndcEndPosition)) return false\n if (!isNDCPointInFront(ndcDomPosition)) return false\n if (lineScreenLength === 0) return false\n return true\n })()\n if (visible === false) {\n this.hide()\n return\n }\n\n // Calculate distance-based scale factor\n const centerPosition = centerPoint(startPoint, endPoint)\n const cameraDistance = centerPosition.distanceTo(five.camera.position)\n\n // Include FOV in scale calculation\n const fov = five.camera.fov || 60\n const sseDenominator = 2.0 * Math.tan(((0.5 * fov) / 180) * Math.PI)\n const scaleFactor = Math.max(Math.min(1 - (sseDenominator * cameraDistance) / 40, 1), 0)\n\n // Set the CSS variable for distance scaling\n this.contentDom.style.setProperty('--distance-scale', scaleFactor.toString())\n\n // 更新 UI\n const left = ((ndcDomPosition.x + 1) / 2) * screenWidth\n const top = (-(ndcDomPosition.y - 1) / 2) * screenHeight\n const rad = Math.atan((screenStartPosition.y - screenEndPosition.y) / (screenStartPosition.x - screenEndPosition.x))\n const deg = -(rad * 180) / Math.PI\n const offsetY = this.containerDom.parentElement && this.contentDom.clientWidth > lineScreenLength ? -20 : 0\n this.containerDom.style.transform = `translate(${left}px, ${top}px) rotate(${deg}deg) translateY(${offsetY}px)`\n this.show()\n\n this.params.userDistanceItem?.update({ line: this.line, polyline: this.line.getPolyline() })\n\n const content = this.getCurrentContent()\n this.contentDom.innerText = content\n }\n\n private getFiveInstance(): Five | undefined {\n // Try to get Five through the model's hierarchy\n return this.line.model?.config?.['five'] as Five | undefined\n }\n\n private onCameraUpdate() {\n const five = this.getFiveInstance()\n if (five?.camera && this.lastFOV !== five.camera.fov) {\n this.lastFOV = five.camera.fov\n this.update(five)\n }\n }\n\n private onPanoChange = () => {\n const five = this.getFiveInstance()\n if (five) {\n // Add slight delay to ensure the camera position is updated\n setTimeout(() => this.update(five), 100)\n }\n }\n}\n","import type * as THREE from 'three/webgpu'\nimport type { Model } from '.'\nimport type Point from './point'\nimport type { LineJson } from '../typings/data'\nimport type { Polyline } from './polyline'\nimport uuid from '../../shared-utils/uuid'\nimport { createLineMesh } from '../utils/line'\nimport { Subscribe, type SubscribeEventMap } from '@realsee/five-webgpu'\nimport { DistanceItem } from '../utils/dom/distanceItem'\nimport type { FiveLine } from '../../shared-utils/five/FiveLine'\n\nexport interface ILineHook extends SubscribeEventMap {\n selected: (line: Line) => void\n\n textChanged: (text: string | undefined) => void\n}\n\nexport default class Line {\n public id: string\n public selected = false\n public text?: string\n public readonly type = 'line'\n public readonly model: Model\n public readonly mesh: FiveLine\n public readonly points: Point[]\n public readonly lightMesh: FiveLine\n public readonly hook: Subscribe<ILineHook>\n public readonly distanceItem: DistanceItem\n\n private polyline?: Polyline\n private visible?: boolean\n\n public constructor(point: Point, anotherPoint: Point, model: Model) {\n this.id = uuid()\n this.model = model\n if (point.id === anotherPoint.id) throw new Error('无效的线段, 一个点无法构成线段')\n if (typeof model.config.defaultText === 'string') this.text = model.config.defaultText\n this.hook = new Subscribe<ILineHook>()\n this.points = [point, anotherPoint]\n this.mesh = createLineMesh(this, 'normal')\n this.lightMesh = createLineMesh(this, 'light')\n this.distanceItem = new DistanceItem({\n line: this,\n clickCallback: () => this.hook.emit('selected', this),\n userDistanceItem: this.model.config?.userDistanceItemCreator ? this.model.config.userDistanceItemCreator() : undefined,\n })\n }\n\n public hide() {\n if (!this.visible) return\n this.visible = false\n this.mesh.visible = false\n this.distanceItem.hide()\n }\n\n public show() {\n if (this.visible) return\n this.visible = true\n this.mesh.visible = true\n this.distanceItem.show()\n }\n\n public setPoints(startPoint: THREE.Vector3, endPoint: THREE.Vector3) {\n this.points[0].position.copy(startPoint)\n this.points[1].position.copy(endPoint)\n this.mesh.setPoints(startPoint, endPoint)\n }\n\n public remove(): void {\n if (this.mesh.parent) this.mesh.parent.remove(this.mesh)\n this.distanceItem.remove()\n }\n\n public clear(): void {\n this.selected = false\n this.polyline = undefined\n }\n\n public isEmpty() {\n return this.points.length === 0\n }\n\n public getPolyline(): Polyline {\n if (this.polyline) return this.polyline\n const modelPolyline = this.model.polylines.find((polyline) => polyline.lines.includes(this))\n if (modelPolyline) {\n this.polyline = modelPolyline\n return modelPolyline\n }\n }\n\n public findAnotherPoint(point: Point) {\n return this.points.find(({ id }) => id !== point.id)\n }\n\n public setText(text: string | null) {\n this.text = text\n this.hook.emit('textChanged', text)\n }\n\n public toJSON() {\n return this.toJson()\n }\n\n public toJson(): LineJson {\n return { id: this.id, points: this.points.map((point) => point.toJson()), text: this.text }\n }\n\n public clone() {\n const line = new Line(this.points[0].clone(), this.points[1].clone(), this.model)\n line.text = this.text\n return line\n }\n}\n","import type { PointJson } from '../typings/data'\nimport { Vector3 } from 'three/webgpu'\nimport uuid from '../../shared-utils/uuid'\n\nexport default class Point {\n public id: string\n public position: Vector3\n public readonly type = 'point'\n\n public constructor(position: Vector3 | number[]) {\n this.id = uuid()\n this.position = new Vector3()\n if (Array.isArray(position)) {\n this.position.fromArray(position)\n } else if (position instanceof Vector3) {\n this.position.copy(position)\n } else {\n throw new Error('position must be Vector3 or number[]')\n }\n }\n\n public toJson(): PointJson {\n return { id: this.id, position: this.position.toArray() }\n }\n\n public clone() {\n const point = new Point(this.position)\n return point\n }\n}\n","export const preventDefault = (e: Event) => e.preventDefault()\n","import { Color, type Group } from 'three/webgpu'\nimport type { Model } from '../Model'\nimport type { Config } from '../typings'\nimport type { PanoMeasurePluginEvent } from '../typings/event.type'\nimport type { UserDistanceItem } from '../utils/dom/distanceItem'\nimport type { Five, Intersection, IntersectMeshInterface } from '@realsee/five-webgpu'\nimport type { Subscribe } from '../../shared-utils/Subscribe'\nimport type { OpenParameter, EditParameter, MeasureType } from '../typings/data'\nimport Line from '../Model/line'\nimport Point from '../Model/point'\nimport { preventDefault } from '../utils/ironbox'\nimport type { Magnifier } from '../../shared-utils'\nimport type { WorkUtil } from '../../shared-utils/Utils/WorkUtil'\nimport type { PointSelectorConfig } from '../../shared-utils/three/PointSelector'\n\nexport interface ControllerParams {\n five: Five\n group: Group\n model: Model\n config: Config\n mouseGroup: Group\n container: Element\n workUtil: WorkUtil\n pointSelectorConfig?: PointSelectorConfig\n magnifier: Magnifier\n openParams: OpenParameter\n editParams: EditParameter\n getMeasureType: () => MeasureType\n hook: Subscribe<PanoMeasurePluginEvent>\n userDistanceItemCreator?: () => UserDistanceItem\n}\n\nexport default class BaseController {\n public model: Model\n protected five: Five\n protected group: Group\n protected config: Config\n protected dashed: Line\n protected perpendicularDashed: Line\n protected disposed = false\n protected isMobile: boolean\n protected editParams: EditParameter\n protected magnifierParams: ConstructorParameters<typeof Magnifier>[1]\n protected mouseGroup: Group\n protected container: Element\n protected hook: ControllerParams['hook']\n protected magnifier: ControllerParams['magnifier']\n protected userDistanceItemCreator: ControllerParams['userDistanceItemCreator']\n protected pointSelectorConfig: PointSelectorConfig\n protected workUtil: WorkUtil\n protected get currentMeasureType() {\n return this.getMeasureType()\n }\n private getMeasureType: ControllerParams['getMeasureType']\n\n public constructor(params: ControllerParams) {\n // ==================== Params ====================\n this.five = params.five\n this.hook = params.hook\n this.model = params.model\n this.getMeasureType = params.getMeasureType\n this.config = params.config\n this.editParams = params.editParams\n this.magnifierParams = params.pointSelectorConfig?.helper?.magnifierParams\n this.magnifier = params.magnifier\n this.pointSelectorConfig = {\n ...params.pointSelectorConfig,\n helper: { ...params.pointSelectorConfig?.helper },\n }\n this.container = params.container\n this.isMobile = params.openParams?.isMobile ?? false\n this.workUtil = params.workUtil\n this.userDistanceItemCreator = params.userDistanceItemCreator\n // ==================== Groups ====================\n this.group = params.group\n this.mouseGroup = params.mouseGroup\n // ==================== 虚线 ====================\n this.dashed = new Line(new Point([0, 0, 0]), new Point([0, 0, 0]), this.model)\n this.dashed.distanceItem.setCanSelect(false)\n this.dashed.mesh.setMaterial({ dashed: true, dashScale: 100 })\n this.dashed.mesh.name = 'dashLine'\n // ==================== 鼠标位置与面的垂线 ====================\n this.perpendicularDashed = new Line(new Point([0, 0, 0]), new Point([0, 0, 0]), this.model)\n this.perpendicularDashed.distanceItem.setCanSelect(false)\n this.perpendicularDashed.mesh.setMaterial({ dashed: true, dashScale: 40, color: new Color(0x9bea69) as any })\n this.perpendicularDashed.mesh.name = 'perpendicularDashLine'\n\n const fiveElement = this.five.getElement()\n if (fiveElement) {\n fiveElement.addEventListener('touchstart', preventDefault)\n fiveElement.addEventListener('contextmenu', preventDefault)\n }\n }\n\n public updateDistanceUI = () => {\n this.dashed.distanceItem.update(this.five)\n this.model.getAllLines().forEach((line) => line.distanceItem.update(this.five))\n }\n\n public updateAreaUI = () => {\n this.dashed.distanceItem.update(this.five)\n this.model.getAllAreas().forEach((area) => {\n area.areaItem.updateArea(this.five)\n area.polyline.lines.forEach((line) => {\n line.distanceItem.update(this.five)\n })\n })\n }\n\n protected removeLine(line: Line) {\n this.group.remove(line.mesh, line.lightMesh)\n line.distanceItem.remove()\n this.five.needsRender = true\n }\n\n protected updateMouseGroup(intersection: Intersection, mesh?: IntersectMeshInterface) {\n if (!intersection) return this.mouseGroup\n // ============ update mouseGroup position ============\n this.mouseGroup.position.copy(intersection.point)\n // ============ update mouseGroup quaternion ============\n if (mesh) {\n this.mouseGroup.quaternion.copy(mesh.quaternion)\n } else if (intersection.face) {\n const normal = intersection.face.normal\n const positionVector = normal.clone().multiplyScalar(0.05)\n const position = intersection.point.clone().add(positionVector)\n const lookAtVector = position.clone().add(positionVector)\n this.mouseGroup.lookAt(lookAtVector)\n }\n return this.mouseGroup\n }\n\n protected dispose() {\n this.disposed = true\n this.magnifier?.disable()\n this.model.getAllLines().forEach((line) => this.removeLine(line))\n this.model.areas.forEach((area) => area.remove())\n\n const fiveElement = this.five.getElement()\n if (fiveElement) {\n fiveElement.removeEventListener('touchstart', preventDefault)\n fiveElement.removeEventListener('contextmenu', preventDefault)\n }\n }\n}\n","import type { PointJson, PolylineJson } from '../typings/data'\nimport Line from './line'\nimport Point from './point'\nimport uuid from '../../shared-utils/uuid'\nimport { Subscribe, type Mode as FiveMode } from '@realsee/five-webgpu'\nimport type { Model } from '.'\n\nexport type PolylineEventMap = {\n /** 新增线条\n * @param line 被创建的线条\n */\n lineAdded: (line: Line) => void\n\n /** 删除线条\n * @param lines 被删除的线条数组\n */\n lineRemoved: (lines: Line) => void\n}\n\nexport class Polyline {\n public id = uuid()\n public lines: Line[] = []\n public visiblePanoIndexes?: number[]\n public visibleFiveMode?: FiveMode[]\n public readonly model: Model\n public readonly type = 'polyline'\n public readonly hook = new Subscribe<PolylineEventMap>()\n\n public get points(): Point[] {\n const pointsSet = new Set<Point>()\n this.lines.forEach((line) => {\n pointsSet.add(line.points[0])\n pointsSet.add(line.points[1])\n })\n return Array.from(pointsSet)\n }\n\n public constructor(config: { model: Model }) {\n this.model = config.model\n }\n\n public addLine(line: Line) {\n if (this.includes(line)) {\n console.error(new Error('不能重复添加线段'))\n return\n }\n const lastPoint = this.getLastPoint()\n const anotherPoint = lastPoint && line.findAnotherPoint(lastPoint)\n\n if (lastPoint && !anotherPoint) {\n console.error(new Error('传入线段无法与当前折线进行连接'))\n return\n }\n\n this.lines.push(line)\n this.hook.emit('lineAdded', line)\n }\n\n public removeLine(line: Line) {\n if (this.lines.length === 0) return\n if (!this.isLastLine(line)) {\n console.error(new Error('传入线段不是当前折线的最后一段'))\n return\n }\n // remove last line\n const removedLine = this.lines.pop()\n if (!removedLine) return\n this.hook.emit('lineRemoved', line)\n }\n\n public isLastLine(line: Line) {\n const lastLine = this.getLastLine()\n if (!lastLine) return false\n return line.id === lastLine.id\n }\n\n public getLastLine() {\n return this.lines.slice(-1)[0]\n }\n\n /**\n * @description: 获取连续线段的顶点数量\n */\n public getPointLength() {\n return this.lines.length + 1 // TODO:先这么算吧\n }\n\n public clear() {\n const lines = this.lines.slice()\n this.lines.length = 0\n lines.reduceRight((_: void, line) => this.hook.emit('lineRemoved', line), undefined)\n }\n\n /** 是否产生重叠 */\n public overlapWith(item: Point | Line | Polyline) {\n if (item.type === 'point') {\n return this.includes(item)\n } else if (item.type === 'line') {\n return item.points.some((point) => this.includes(point))\n } else if (item.type === 'polyline') {\n return item.points.some((point) => this.includes(point))\n } else {\n return true\n }\n }\n\n public includes(item: Point | Line) {\n if (item.type === 'point') {\n return this.points.find(({ id }) => id === item.id) !== undefined\n } else if (item.type === 'line') {\n return this.lines.find(({ id }) => id === item.id) !== undefined\n } else {\n return false\n }\n }\n\n public isEmpty() {\n return this.lines.length === 0\n }\n\n public getLastPoint() {\n return this.points.slice(-1)[0]\n }\n\n public toJSON() {\n return this.toJson()\n }\n\n public toJson(): PolylineJson {\n return {\n id: this.id,\n lines: this.lines.map((line) => line.toJson()),\n visiblePanoIndexes: this.visiblePanoIndexes,\n visibleFiveMode: this.visibleFiveMode,\n }\n }\n\n public getPointByID(id: string) {\n return this.points.find(({ id: _id }) => _id === id)\n }\n\n public fromJson(data: PolylineJson) {\n this.clear()\n this.id = data.id\n const { getPoint } = createPointCache()\n const lines = data.lines.map((data) => {\n const [pointData, anotherPointData] = data.points\n const point = getPoint(pointData)\n const anotherPoint = getPoint(anotherPointData)\n if (!point || !anotherPoint) throw new Error('线上的点不存在')\n const line = new Line(point, anotherPoint, this.model)\n line.id = data.id\n line.text = data.text\n return line\n })\n this.lines.push(...lines)\n this.visiblePanoIndexes = data.visiblePanoIndexes\n this.visibleFiveMode = data.visibleFiveMode\n\n function createPointCache() {\n const pointMap = new Map<string, Point>()\n function getPoint(pointData: PointJson) {\n const cachePoint = pointMap.get(pointData.id)\n if (cachePoint) return cachePoint\n const point = new Point(pointData.position)\n point.id = pointData.id\n pointMap.set(pointData.id, point)\n return point\n }\n\n function getAllPoints() {\n return Array.from(pointMap.values())\n }\n return { getPoint, getAllPoints }\n }\n\n return this\n }\n\n public replace(polyline: Polyline) {\n this.id = polyline.id\n this.clear()\n this.lines.push(...polyline.lines)\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { IObject3D } from '../../shared-utils/three/IObject3D'\nimport generatePolygonGeometry from '../../shared-utils/three/generatePolygonGeometry'\n\nexport const blankGeometry = new THREE.BufferGeometry()\n\nexport class PolygonMesh extends IObject3D {\n public readonly isPolygonMesh = true\n\n public geometry: THREE.BufferGeometry = new THREE.BufferGeometry()\n public isBlank = true\n public points: THREE.Vector3[] = []\n\n public constructor(points?: THREE.Vector3[]) {\n super()\n\n // 蓝的\n const materialFront = new THREE.MeshBasicMaterial({\n color: 0x3e69ff,\n transparent: true,\n side: THREE.DoubleSide,\n depthTest: true,\n opacity: 0.5,\n })\n\n // 白的\n const materialBackground = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n transparent: true,\n side: THREE.DoubleSide,\n depthTest: false,\n depthWrite: false,\n opacity: 0.3,\n })\n\n const meshFront = new THREE.Mesh(this.geometry, materialFront)\n const meshBackground = new THREE.Mesh(this.geometry, materialBackground)\n\n // 让蓝色的在白色的上面\n meshFront.renderOrder = 1\n meshBackground.renderOrder = 0\n\n if (points) this.updatePoints(points)\n\n this.add(meshFront, meshBackground)\n }\n\n /**\n * @description: 按照新的端点来更新多边形的geometry\n */\n public updatePoints(points: THREE.Vector3[]): void {\n this.points = points\n const newGeometry = generatePolygonGeometry(points)\n if (newGeometry) {\n this.geometry.copy(newGeometry)\n this.isBlank = false\n } else {\n this.geometry.copy(blankGeometry)\n this.isBlank = true\n }\n }\n}\n","import type { ItemDomParams } from './base'\nimport { ItemDom } from './base'\nimport type { Five } from '@realsee/five-webgpu'\nimport type { BufferGeometry } from 'three/webgpu'\nimport type Area from '../../Model/area'\nimport { getGeometryInfo } from '../../../shared-utils/three/geometryUtil'\nimport { isNil } from '../../../shared-utils'\n\ninterface AreaItemParams extends ItemDomParams {\n area: Area\n}\n\nexport class AreaItem extends ItemDom {\n protected declare params: AreaItemParams\n private area: Area\n\n public constructor(params: AreaItemParams) {\n params.containerStyle = {\n ...params.containerStyle,\n ...{ zIndex: '1' },\n }\n params.contentStyle = {\n ...params.contentStyle,\n ...{\n background: '#6386FF',\n borderRadius: '2px',\n },\n }\n super(params)\n this.area = params.area\n this.containerDom.appendChild(this.contentDom)\n }\n\n /**\n * @description: dom 依赖的多边形的顶点的位置更新时,更新 dom 的位置和面积\n */\n public updateArea(five: Five, _geometry?: BufferGeometry) {\n const geometry = _geometry ?? this.area.polygon.geometry\n\n const geometryInfo = getGeometryInfo(geometry)\n\n if (!geometryInfo) {\n this.ndcPosition = null\n this.updateDomPosition(five)\n return\n }\n\n const { area, center } = geometryInfo\n\n this.ndcPosition = center.clone()\n this.updateDomPosition(five)\n\n if (this.area.model?.config?.getAreaText) {\n this.contentDom.innerText = this.area.model.config.getAreaText(area)\n } else {\n this.updateAreaText(area, { fix: 2 })\n }\n }\n\n public updateAreaText(area: number, config?: { unit?: string; fix?: number }) {\n const { unit = 'm²', fix } = config ?? {}\n this.contentDom.innerText = `${isNil(fix) ? area : area.toFixed(fix)}${unit}`\n }\n}\n","import * as THREE from 'three/webgpu'\nimport uuid from '../../shared-utils/uuid'\nimport { Subscribe, type Five, type SubscribeEventMap } from '@realsee/five-webgpu'\nimport Line from './line'\nimport { PolygonMesh } from './polygon'\nimport { Polyline } from './polyline'\nimport type { Model } from '.'\nimport Point from './point'\nimport { AreaItem } from '../utils/dom/areaDom'\nimport type { FiveLine } from '../../shared-utils/five/FiveLine'\n\nexport interface AreaHook extends SubscribeEventMap {\n selected: (area: Area, position: { left: string; top: string }) => void\n}\n\n/**\n * @description: 多边形类\n */\nexport default class Area {\n public id = uuid()\n public selected = false\n public text?: string\n public readonly type = 'area'\n public readonly lightMesh: FiveLine\n public readonly areaItem: AreaItem\n public readonly hook: Subscribe<AreaHook> = new Subscribe<AreaHook>()\n public model?: Model\n\n /**\n * @description: 多边形的端点是否闭合\n */\n public get isClosed() {\n return this.points.length >= 4 && this.points.at(0)?.equals(this.points.at(-1))\n }\n\n /** 多边形mesh */\n public polygon: PolygonMesh\n /** 多边形顶点 */\n public points: THREE.Vector3[] = []\n /** 多边形前三个点组成的平面,用来使得后面加的点也落在这个平面上 */\n public planeHelper: THREE.Plane | null\n /** 多边形边框 */\n public polyline: Polyline\n /** 多边形mesh容器 */\n private meshContainer: THREE.Object3D | null\n /** 多边形dom容器 */\n private domContainer: Element | null\n private five: Five | null\n\n public constructor(\n points: THREE.Vector3[] | undefined,\n config: {\n /** @todo: 这个model整的真的太恶心了 */\n model: Model\n meshContainer?: THREE.Object3D\n domContainer?: Element\n five?: Five\n },\n ) {\n if (points) this.points = points\n this.model = config.model\n this.polygon = new PolygonMesh(points)\n this.polyline = new Polyline({ model: config.model })\n this.areaItem = new AreaItem({\n area: this,\n clickCallback: (e, item) => {\n const left = e.clientX + 'px'\n const top = e.clientY + 'px'\n this.hook.emit('selected', this, { left, top })\n },\n })\n\n this.domContainer = config.domContainer || null\n this.meshContainer = config.meshContainer || null\n this.five = config.five || null\n\n this.areaItem.appendTo(this.domContainer)\n\n this.five?.on('cameraUpdate', this.updateDom)\n }\n\n public addPoints(point: THREE.Vector3) {\n this.points = this.points.concat(point)\n\n // 添加线\n const lineStart = this.points.at(-2)\n const lineEnd = this.points.at(-1)\n if (lineStart && lineEnd) {\n const line = new Line(new Point(lineStart), new Point(lineEnd), this.polyline.model)\n this.polyline.addLine(line)\n this.meshContainer.add(line.mesh)\n if (this.five) {\n line.distanceItem.setCanSelect(false)\n line.distanceItem.appendTo(this.domContainer)\n line.distanceItem.update(this.five)\n }\n }\n\n if (!this.meshContainer?.children.includes(this.polygon)) this.meshContainer.add(this.polygon)\n\n // 更新面积\n this.polygon.updatePoints(this.points)\n this.areaItem.updateArea(this.five)\n\n // 更新plane\n if (this.points.length === 3) {\n this.planeHelper = new THREE.Plane().setFromCoplanarPoints(this.points[0], this.points[1], this.points[2])\n } else if (this.points.length < 3) {\n this.planeHelper = null\n }\n }\n\n /**\n * @description: 移除最后一个添加的点\n */\n public popPoint() {\n this.points.pop()\n\n // 移除边\n const line = this.polyline.lines.pop()\n line?.remove()\n\n // 更新面\n this.polygon.updatePoints(this.points)\n this.areaItem.updateArea(this.five)\n\n if (this.points.length < 3) this.planeHelper = null\n }\n\n /**\n * @description: 自动补全多边形的各个边\n */\n public complete() {\n if (!this.points.at(-1).equals(this.points[0]) /** 先检查是否已经闭合 */) {\n // 闭合\n this.addPoints(this.points[0])\n }\n }\n\n public hideArea() {\n this.polygon.visible = false\n this.areaItem.hide()\n }\n\n public showArea() {\n this.polygon.visible = true\n this.areaItem.show()\n }\n\n /**\n * @description: five camera update 时,更新Dom的位置\n */\n public updateDom = () => {\n if (this.five) {\n this.polyline.lines.forEach((line) => line.distanceItem.update(this.five))\n this.areaItem.updateDomPosition(this.five)\n }\n }\n\n /**\n * @description: 获取一个点投影在当前平面上的点\n */\n public projectPoint(point: THREE.Vector3) {\n if (!point) return point\n return this.planeHelper ? this.planeHelper.projectPoint(point, new THREE.Vector3()) : point\n }\n\n public remove() {\n this.polygon.removeFromParent()\n this.areaItem.remove()\n this.polyline.lines.forEach((line) => line.remove())\n }\n\n /**\n * @todo: 没写完\n */\n public dispose(): void {\n this.remove()\n this.model.areas.splice(this.model.areas.indexOf(this), 1)\n this.planeHelper = null\n this.five.off('cameraUpdate', this.updateDom)\n this.five.needsRender = true\n }\n\n public toJSON(): any {\n return {\n id: this.id,\n points: this.points.map((point) => point.toArray()),\n text: this.text,\n }\n }\n}\n","const svg = `\n<svg class=\"fpm__delete-icon\" width=\"16px\" height=\"17px\" viewBox=\"0 0 16 17\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <defs>\n <linearGradient x1=\"22.185491%\" y1=\"100%\" x2=\"66.8316686%\" y2=\"6.67239121%\" id=\"linearGradient-1\">\n <stop stop-color=\"#FFFCFC\" stop-opacity=\"0.6\" offset=\"0%\"></stop>\n <stop stop-color=\"#FFFFFF\" offset=\"100%\"></stop>\n </linearGradient>\n </defs> \n <path fill=\"url(#linearGradient-1)\" fill-rule=\"nonzero\" transform=\"translate(2.16 2.16)\" d=\"M11.2979686,2.71818182 C11.611378,2.71818182 11.8654465,2.97561809 11.8654465,3.29318182 C11.8654465,3.58428191 11.6519584,3.82485822 11.374972,3.86293275 L11.2979686,3.86818182 L10.464,3.868 L9.7236795,10.6246222 C9.64153248,11.3737453 9.04854423,11.9512142 8.32013277,12.0165596 L8.18206028,12.0227273 L3.68338622,12.0227273 C2.89302127,12.0227273 2.22904821,11.4205655 2.141767,10.6246222 L2.141767,10.6246222 L1.4,3.868 L0.567477876,3.86818182 C0.254068499,3.86818182 0,3.61074555 0,3.29318182 C0,3.00208173 0.213488114,2.76150541 0.49047449,2.72343089 L0.567477876,2.71818182 L11.2979686,2.71818182 Z M9.322,3.868 L2.542,3.868 L3.26978106,10.4976259 C3.28762252,10.6603274 3.39528004,10.7928487 3.53932022,10.8467307 L3.61412483,10.866894 L3.68338622,10.8727273 L8.18206028,10.8727273 C8.39410941,10.8727273 8.57224853,10.7111717 8.59566544,10.4976259 L8.59566544,10.4976259 L9.322,3.868 Z M8.16824216,0 C8.48165153,0 8.73572003,0.257436269 8.73572003,0.575 C8.73572003,0.866100087 8.52223192,1.1066764 8.24524554,1.14475093 L8.16824216,1.15 L3.69720434,1.15 C3.38379497,1.15 3.12972647,0.892563731 3.12972647,0.575 C3.12972647,0.283899913 3.34321458,0.0433235966 3.62020096,0.00524907226 L3.69720434,0 L8.16824216,0 Z\"></path> \n</svg>\n`\n\nexport default svg\n","const image = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTciIGhlaWdodD0iMjUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IHgxPSIxMC43MDYlIiB5MT0iNDIuNzQ0JSIgeDI9Ijg5LjA2NCUiIHkyPSI1Ny4yMDglIiBpZD0icHJlZml4X19hIj48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9Ii4zMDgiIG9mZnNldD0iNDkuNTY5JSIvPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iMCIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iLS4yNSIgeT0iLS4yNSIgd2lkdGg9IjU3LjUiIGhlaWdodD0iMjMuNSIgcng9IjExLjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIiBmaWxsPSIjMkMyQzJDIiBzdHJva2U9InVybCgjcHJlZml4X19hKSIgc3Ryb2tlLXdpZHRoPSIuNSIgZmlsbC1ydWxlPSJldmVub2RkIiBmaWxsLW9wYWNpdHk9Ii4zMDMiLz48L3N2Zz4=`\nexport default image\n","const image = `data:image/png;base64,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`\nexport default image\n","import type Line from '../../Model/line'\nimport type { Five } from '@realsee/five-webgpu'\nimport type Point from '../../Model/point'\nimport deleteSvg from './_Assets/delete.svg'\nimport deleteBg from './_Assets/delete_bg.png'\nimport deleteHoverBg from './_Assets/delete_hover_bg.png'\n\nexport default class DeleteDom {\n public visible = false\n\n private five: Five\n private lines: Line[] = []\n private points: Point[] = []\n private onClick: (e: MouseEvent, target: any) => void\n private cancel: (target: any) => void\n private content = document.createElement('div')\n private container = document.createElement('div')\n private masking = document.createElement('div')\n private target: any\n\n public constructor(\n five: Five,\n opts?: { onClick?: (e: MouseEvent, target: any) => void; cancel?: (target: any) => void; i18n?: (key: string) => string },\n ) {\n this.five = five\n this.onClick = opts?.onClick || (() => undefined)\n this.cancel = opts?.cancel || (() => undefined)\n // container\n this.container.classList.add('fpm__delete')\n this.container.style.opacity = '0'\n this.container.style.position = 'absolute'\n this.container.style.left = '0'\n this.container.style.top = '10px'\n this.container.style.transform = `translate3d(0, 0, 10px)`\n this.container.style.pointerEvents = `none`\n this.container.style.transition = 'opacity 200ms ease'\n this.container.style.zIndex = '99'\n\n // content\n this.content.classList.add('fpm__delete-content')\n this.content.style.width = '62px'\n this.content.style.height = '26px'\n this.content.style.display = 'flex'\n this.content.style.alignItems = 'center'\n this.content.style.justifyContent = 'center'\n this.content.style.transform = 'translate(-50%, -50%)'\n this.content.style.color = '#fff'\n this.content.style.fontSize = '12px'\n this.content.style.lineHeight = '17px'\n this.content.style.borderRadius = '11px'\n this.content.style.backgroundSize = '100% 100%'\n this.content.style.cursor = 'pointer'\n this.content.style.userSelect = 'none'\n this.content.style.backgroundImage = `url(${deleteBg})`\n this.content.innerHTML = `\n ${deleteSvg}\n <span>${opts.i18n?.('删除') ?? '删除'}</span>\n `\n this.container.append(this.content)\n\n const deleteSvgDom = this.content.querySelector<SVGElement>('.fpm__delete-icon')\n if (deleteSvgDom) {\n deleteSvgDom.style.width = '16px'\n deleteSvgDom.style.height = '17px'\n deleteSvgDom.style.marginRight = '1px'\n }\n\n this.content.addEventListener('click', this.clickHandler)\n this.content.addEventListener('mouseenter', this.hover)\n this.content.addEventListener('mouseleave', this.unHover)\n\n // masking\n this.masking.setAttribute('style', 'position: absolute;top: 0;left: 0;bottom: 0;right: 0;pointer-events: none;')\n this.masking.addEventListener('click', this.cancelHandler)\n this.masking.addEventListener('touchstart', this.cancelHandler)\n }\n\n public dispose() {\n this.content.removeEventListener('click', this.clickHandler)\n this.content.removeEventListener('mouseenter', this.hover)\n this.content.removeEventListener('mouseleave', this.unHover)\n this.container.remove()\n\n this.masking.removeEventListener('click', this.cancelHandler)\n this.masking.removeEventListener('touchstart', this.cancelHandler)\n this.masking.remove()\n }\n\n public appendTo(element: Element) {\n element.append(this.container)\n element.append(this.masking)\n return this\n }\n\n public setLines(lines: Line[]): this {\n this.lines = lines\n this.points = Array.from(new Set(this.lines.map((line) => [line.points[0], line.points[1]]).flat(1)))\n return this\n }\n\n public setTarget(target: any): this {\n this.target = target\n return this\n }\n\n public updatePosition(left?: string, top?: string) {\n if (left && top) {\n this.container.style.left = left\n this.container.style.top = top\n this.container.style.transform = ''\n return this.show()\n }\n if (this.lines.length === 0) return this\n const points = this.points.map((point) => point.position).map((p) => p.clone().applyMatrix4(this.lines[0].mesh.matrixWorld))\n const ndcPoints = points.map((point) => point.clone().project(this.five.camera))\n if (ndcPoints.some((ndcPoint) => Math.abs(ndcPoint.z) > 1)) return this.hide()\n const xArray = ndcPoints.map((point) => point.x)\n const yArray = ndcPoints.map((point) => point.y)\n const centerX = (Math.min(...xArray) + Math.max(...xArray)) / 2\n const maxY = Math.max(...yArray)\n\n const wrapper = this.container.parentElement\n if (!wrapper) return this\n const centerScreenX = ((centerX + 1) / 2) * wrapper.clientWidth\n const maxScreenY = (-(maxY - 1) / 2) * wrapper.clientHeight\n\n let x = centerScreenX\n let y = maxScreenY - 34\n\n // 只有一条线时且斜率大时删除按钮位于右侧\n if (this.lines.length === 1 && points.length === 2) {\n const k = (yArray[1] - yArray[0]) / (xArray[1] - xArray[0])\n const centerY = (yArray[1] + yArray[0]) / 2\n const centerScreenY = (-(centerY - 1) / 2) * wrapper.clientHeight\n if (Math.abs(k) > 0.4) {\n x = centerScreenX + 57\n y = centerScreenY\n }\n }\n\n this.container.style.top = '0'\n this.container.style.left = '0'\n this.container.style.transform = `translate3d(${x}px, ${y}px, 0)`\n\n return this.show()\n }\n\n public hide() {\n this.visible = false\n this.masking.style.pointerEvents = 'none'\n this.container.style.opacity = '0'\n this.container.style.pointerEvents = 'none'\n this.unHover()\n return this\n }\n\n public show() {\n this.visible = true\n this.masking.style.pointerEvents = 'auto'\n this.container.style.opacity = '1'\n this.container.style.pointerEvents = 'auto'\n return this\n }\n\n private clickHandler = (event: MouseEvent) => {\n this.onClick(event, this.target)\n }\n\n private cancelHandler = () => {\n this.cancel(this.target)\n }\n\n private hover = () => {\n this.content.style.backgroundImage = `url(${deleteHoverBg})`\n }\n\n private unHover = () => {\n this.content.style.backgroundImage = `url(${deleteBg})`\n }\n}\n","import { Vector2 } from 'three/webgpu'\n\n/**\n * 获取一点对于线段上最近的一点,\n * 如果可以是过直线垂线的垂足,不行的话取线段的两端\n * @param point\n * @param linePoints\n * @return\n */\nexport function closestPointOnLine(point: Vector2, linePoints: Vector2[]) {\n const tA = point.x - linePoints[0].x\n const tB = point.y - linePoints[0].y\n const tC = linePoints[1].x - linePoints[0].x\n const tD = linePoints[1].y - linePoints[0].y\n\n // 设线段为 AB 线段,线段外一点为 P\n // tDot = AP 向量与 AB 向量乘积,tLenSq 为 |AB|平方。\n // tParam 是 AP 向量在 AB 向量投影向量 AC 与 AB 向量的比。\n const tDot = tA * tC + tB * tD\n const tLenSq = tC * tC + tD * tD\n const tParam = tDot / tLenSq\n\n let tXx: number, tYy: number\n\n if (tParam < 0 || samePointAt(linePoints[0], linePoints[1])) {\n tXx = linePoints[0].x\n tYy = linePoints[0].y\n } else if (tParam > 1) {\n tXx = linePoints[1].x\n tYy = linePoints[1].y\n } else {\n tXx = linePoints[0].x + tParam * tC\n tYy = linePoints[0].y + tParam * tD\n }\n\n return new Vector2(tXx, tYy)\n}\n\n/**\n * 检查两个点是否位置相同\n * point: { x: number, y: number }\n * @param point1\n * @param point2\n * @return\n */\nexport function samePointAt(point1: Vector2, point2: Vector2) {\n return point1.x === point2.x && point1.y === point2.y\n}\n","import Line from '../Model/line'\nimport Point from '../Model/point'\nimport throttle from '../../shared-utils/throttle'\nimport BaseController from './BaseController'\nimport type { ControllerParams } from './BaseController'\nimport { Polyline } from '../Model/polyline'\nimport Area from '../Model/area'\nimport { isIntersecting } from '../utils/isIntersecting'\nimport { PointSelector, type PointIntersection } from '../../shared-utils/three/PointSelector'\nimport DeleteDom from '../Modules/DeleteDom'\nimport type { EventCallback } from '@realsee/five-webgpu'\nimport { Vector2 } from 'three/webgpu'\nimport isNDCPointInScreen from '../utils/isNDCPointInScreen'\nimport { closestPointOnLine } from '../utils/math'\nimport { getFiveModel } from '../../shared-utils/five/getFiveModel'\nimport * as THREE from 'three/webgpu'\nimport { notNil } from '../../shared-utils'\n\nconst disableFiveEvent = (): false => false\n\nexport default class EditController extends BaseController {\n public type = 'edit'\n public polyline: Polyline\n public area: Area\n private hasAppendDashed = false\n // private deleteDom: DeleteDom\n private fiveElement?: HTMLCanvasElement\n /** 上一个端点位置 */\n private lastPoint: Point | null = null\n private pointSelector: PointSelector\n private deleteDom: DeleteDom\n\n /** 根据 intersection 更新放大镜和吸附点 */\n private onIntersectionUpdate = throttle((position?: PointIntersection) => {\n if (!position) return\n if (this.currentMeasureType === 'area') {\n if (typeof position.isAdsorbed === 'boolean') {\n if (position.isAdsorbed) this.hook.emit('readyComplete')\n else this.hook.emit('notReadyComplete')\n }\n }\n this.updateDashed()\n }, 20)\n\n public constructor(params: ControllerParams) {\n super(params)\n\n // this.model = new Model(this.config)\n\n this.fiveElement = this.five.getElement()\n\n this.deleteDom = new DeleteDom(this.five, {\n i18n: this.config.i18n,\n onClick: (_, target) => {\n const isArea = target.type === 'area'\n const isLine = Array.isArray(target) && target[0]?.type === 'line'\n if (isArea) this.deleteArea(target)\n if (isLine) this.deleteLine(target)\n },\n cancel: (target) => {\n this.deleteDom.hide()\n const isArea = target.type === 'area'\n const isLine = Array.isArray(target) && target[0]?.type === 'line'\n if (isArea) this.unHighlightArea(target)\n if (isLine) this.unHighlightLines(target)\n },\n }).appendTo(this.container)\n\n this.pointSelector = new PointSelector(this.five, {\n ...this.pointSelectorConfig,\n mode: this.editParams.pointSelectorMode,\n helper: { magnifierParams: this.magnifierParams, container: this.container, ...this.pointSelectorConfig.helper },\n })\n\n this.pointSelector.enable()\n\n this.polyline = new Polyline({ model: this.model })\n this.area = new Area(undefined, {\n five: this.five,\n model: this.model,\n meshContainer: this.group,\n domContainer: this.container,\n })\n\n this.model.addPolyline(this.polyline)\n this.model.addArea(this.area)\n // ==================== 新加的逻辑: 不删除旧的东西 (依托答辩) ====================\n this.model.getAllLines().forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n line.distanceItem.setCanSelect(true)\n line.hook.on('selected', this.chooseLine)\n this.group.add(line.mesh)\n })\n this.model.getAllAreas().forEach((area) => {\n area.areaItem.appendTo(this.container)\n area.areaItem.updateDomPosition(this.five)\n area.areaItem.setCanSelect(true)\n area.hook.on('selected', this.chooseArea)\n this.group.add(area.polygon)\n area.polyline.lines.forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n this.group.add(line.mesh)\n })\n })\n\n // ==================== 事件监听 ====================\n // five\n this.five.on('cameraUpdate', this.onCameraUpdate)\n this.five.on('wantsTapGesture', this.wantsTapGesture)\n this.five.on('wantsMoveToPano', this.wantsMoveToPano)\n this.five.on('wantsChangeMode', disableFiveEvent)\n // pointSelector\n this.pointSelector.on('intersectionUpdate', this.onIntersectionUpdate)\n this.pointSelector.on('intersectionUpdate', this.checkMouseLeave)\n this.pointSelector.on('select', this.onSelect)\n this.pointSelector.on('wantsSelect', this.onWantsSelect)\n // polyline events\n this.polyline.hook.on('lineAdded', this.onLineChanged)\n this.polyline.hook.on('lineRemoved', this.onLineChanged)\n this.five.helperVisible = false\n // ==================== 其他 ====================\n this.hook.emit('anchorChange', null)\n this.hook.emit('editedDashedLineChange', null)\n this.five.refresh()\n }\n\n public dispose() {\n super.dispose()\n // 没有闭合的面要移出去,防止在其他Controller的构造函数中又加进去\n this.model.areas.forEach((area) => {\n if (area.points.length < 2 || area.polygon.isBlank) this.model.removeArea(area)\n })\n // five effect\n this.five.helperVisible = true\n this.pointSelector.disable()\n this.dashed.remove()\n this.perpendicularDashed.remove()\n // ==================== 解除事件监听 ====================\n // five\n this.five.off('cameraUpdate', this.onCameraUpdate)\n this.five.off('wantsTapGesture', this.wantsTapGesture)\n this.five.off('wantsMoveToPano', this.wantsMoveToPano)\n this.five.off('wantsChangeMode', disableFiveEvent)\n // pointSelector\n this.pointSelector.off('intersectionUpdate', this.onIntersectionUpdate)\n this.pointSelector.off('intersectionUpdate', this.checkMouseLeave)\n this.pointSelector.off('select', this.onSelect)\n this.pointSelector.off('wantsSelect', this.onWantsSelect)\n // polyline events\n this.polyline.hook.off('lineAdded', this.onLineChanged)\n this.polyline.hook.off('lineRemoved', this.onLineChanged)\n\n this.pointSelector.dispose()\n this.deleteDom.dispose()\n this.dashed.distanceItem.remove()\n this.five.needsRender = true\n }\n\n public getEditingLines() {\n return this.polyline.lines\n }\n\n /** 撤销编辑 */\n public revoke = () => {\n if (this.currentMeasureType === 'area') {\n this.revokeArea()\n } else if (this.currentMeasureType === 'line') {\n this.revokeLine()\n }\n }\n\n /**\n * @description: 测面积的撤销功能\n */\n public revokeArea = () => {\n if (this.area.points.length === 0) return\n this.area.popPoint()\n this.hook.emit('pointsChange', this.area.points)\n if (this.area.points.length === 0) {\n this.lastPoint = null\n this.hasAppendDashed = false\n this.dashed.remove()\n this.five.needsRender = true\n this.hook.emit('revoke', { isEmpty: true })\n return\n } else {\n this.lastPoint = new Point(this.area.points[this.area.points.length - 1])\n this.updateDashed()\n }\n this.five.needsRender = true\n }\n\n /**\n * @description: 测距的撤销功能\n */\n public revokeLine = (_polyline?: Polyline) => {\n const polyline = _polyline || this.polyline\n // ============ revoke points ============\n // 如果当前没有虚线,只有起始点,需要删除起始点,重置起始状态。并删除虚线实例\n if (polyline.lines.length === 0 && this.lastPoint) {\n this.lastPoint = null\n this.hasAppendDashed = false\n this.pointSelector.setAdherePoints(null)\n this.dashed.remove()\n this.hook.emit('anchorChange', null)\n this.hook.emit('editedDashedLineChange', null)\n this.five.needsRender = true\n this.hook.emit('pointsChange', [])\n return\n }\n if (polyline.lines.length === 0 && !this.lastPoint) return\n if (!this.lastPoint) return\n const revokedLine = polyline.lines[polyline.lines.length - 1]\n const lastPoint = revokedLine.findAnotherPoint(this.lastPoint)\n if (!lastPoint) return\n this.lastPoint = lastPoint\n this.hook.emit('anchorChange', lastPoint.position)\n // ============ revoke lines ============\n this.group.remove(revokedLine.mesh)\n polyline.removeLine(revokedLine)\n // ============ revoke lineDistance ============\n revokedLine.distanceItem.remove()\n // ============ revoke dashed ============\n this.updateDashed()\n\n this.five.needsRender = true\n }\n\n public selectPoint() {\n this.onSelect()\n }\n\n public complete() {\n this.hook.emit('complete')\n if (this.currentMeasureType === 'area') {\n if (this.area.points.length < 3) {\n this.deleteArea(this.area)\n } else {\n this.area.showArea()\n this.area.complete() // 闭合面积\n this.area.hook.on('selected', this.chooseArea)\n }\n this.area = new Area(undefined, { five: this.five, model: this.model, meshContainer: this.group, domContainer: this.container })\n this.model.addArea(this.area)\n } else if (this.currentMeasureType === 'line') {\n this.polyline.lines.forEach((line) => {\n line.hook.on('selected', this.chooseLine)\n line.distanceItem.setCanSelect(true)\n })\n this.polyline = new Polyline({ model: this.model })\n this.model.addPolyline(this.polyline)\n }\n this.pointSelector.setAdherePoints(null) // 重置打点器的吸附点\n this.dashed.hide()\n this.perpendicularDashed.hide()\n this.lastPoint = undefined\n }\n\n private checkMouseLeave = (position: PointIntersection) => {\n if (!position) {\n this.dashed.hide()\n this.perpendicularDashed.hide()\n this.area.hideArea()\n }\n }\n\n /** 编辑线条发生改变时通知外部 */\n private onLineChanged = () => {\n this.hook.emit('editedPolylineChange', this.polyline)\n }\n\n private onWantsSelect = () => {\n if (this.currentMeasureType === 'area') {\n const noPolygon = this.area.polygon.isBlank || this.area.polygon.visible === false\n if (this.area.points.length >= 3 && noPolygon) return false\n }\n }\n\n private wantsMoveToPano = (): false | void => {\n if (this.lastPoint) return false\n }\n\n /**\n * 1. 如果存在上一个点,需要绘制当前点到上一个点的连线\n * 2. 把上一个点的位置更新为当前点的位置\n * 3. 清除 pointSelector\n */\n private onSelect = () => {\n if (!this.hasAppendDashed) {\n this.dashed.distanceItem.appendTo(this.container)\n this.group.add(this.dashed.mesh)\n // 测面积中,鼠标位置不在平面上时,要画一条垂线来显示\n if (this.currentMeasureType === 'area') this.group.add(this.perpendicularDashed.mesh)\n }\n this.hasAppendDashed = true\n const currentPosition = (() => {\n if (this.currentMeasureType === 'area') return this.area.projectPoint(this.pointSelector.position?.point)\n else if (this.currentMeasureType === 'line') return this.pointSelector.position?.point\n })()\n if (!currentPosition) return\n\n const nowPoint = new Point(currentPosition)\n const lastPoint = this.lastPoint\n if (lastPoint?.position && nowPoint.position.equals(lastPoint?.position)) return // 不重复打点\n this.lastPoint = nowPoint\n\n const getAdherePoints = (params: { intersection: PointIntersection; pointSelectorInstance: PointSelector }) => {\n if (!this.lastPoint) return []\n const { intersection, pointSelectorInstance } = params\n const pointHelper = pointSelectorInstance.pointSelectorHelper.pointHelper\n const normal = new THREE.Vector3(0, 0, 1).applyQuaternion(pointHelper.quaternion)\n\n if (normal.x > 0.9999 || normal.y > 0.9999 || normal.z > 0.9999 || normal.x < -0.9999 || normal.y < -0.9999 || normal.z < -0.9999) {\n const intersectPoint = intersection.point\n const offset = this.lastPoint.position.clone().sub(intersectPoint)\n pointSelectorInstance.pointSelectorHelper.updateWithIntersect(intersection, { emitEvent: false })\n const xLine = new THREE.Line3(\n pointHelper.localToWorld(new THREE.Vector3(1, 0, 0)).add(offset),\n pointHelper.localToWorld(new THREE.Vector3(-1, 0, 0)).add(offset),\n )\n const yLine = new THREE.Line3(\n pointHelper.localToWorld(new THREE.Vector3(0, 1, 0)).add(offset),\n pointHelper.localToWorld(new THREE.Vector3(0, -1, 0)).add(offset),\n )\n const pointOnXLine = xLine.closestPointToPoint(intersectPoint, false, new THREE.Vector3())\n const pointOnYLine = yLine.closestPointToPoint(intersectPoint, false, new THREE.Vector3())\n return [pointOnXLine, pointOnYLine]\n }\n return []\n }\n\n this.pointSelector.setAdherePoints(getAdherePoints)\n\n // 绘制线\n if (this.currentMeasureType === 'line') {\n if (nowPoint && lastPoint) {\n const line = new Line(lastPoint, nowPoint, this.model)\n line.distanceItem.setCanSelect(false)\n line.distanceItem.appendTo(this.container)\n this.polyline.addLine(line)\n this.group.add(line.mesh)\n line.distanceItem.update(this.five)\n }\n\n const autoEndLineLength = this.editParams?.autoEndConfig?.line\n if (typeof autoEndLineLength === 'number') {\n // TODO: 重置逻辑,不知道放哪好\n if (this.polyline.getPointLength() >= autoEndLineLength) {\n this.complete()\n } else if (this.polyline.getPointLength() === autoEndLineLength - 1) {\n this.hook.emit('readyComplete')\n }\n }\n this.hook.emit('pointsChange', this.polyline.points)\n }\n // 绘制面积\n else if (this.currentMeasureType === 'area') {\n this.area.addPoints(nowPoint.position)\n if (this.area.isClosed) {\n this.complete()\n return\n }\n if (this.area.points.length >= 3) {\n this.pointSelector.setAdherePoints((...params) => [this.area.points[0], ...(getAdherePoints(...params) ?? [])].filter(notNil))\n }\n\n const autoEndAreaLength = this.editParams?.autoEndConfig?.area\n if (typeof autoEndAreaLength === 'number') {\n // TODO: 重置逻辑,不知道放哪好\n if (this.area.points.length >= autoEndAreaLength) {\n this.complete()\n } else if (this.area.points.length === autoEndAreaLength - 1) {\n this.hook.emit('readyComplete')\n }\n }\n this.hook.emit('pointsChange', this.area.points)\n }\n this.updateDashed()\n this.five.needsRender = true\n this.hook.emit('anchorChange', nowPoint.position)\n }\n\n /** 移动全景时更新 distanceItem 在屏幕上的位置 */\n private onCameraUpdate = () => {\n this.updateDistanceUI()\n }\n\n /** 更新虚线 */\n private updateDashed = () => {\n if (!this.lastPoint) return\n const dashedStart = this.lastPoint.position\n const dashedEnd = (() => {\n if (this.currentMeasureType === 'area') return this.area.projectPoint(this.pointSelector.position?.point)\n else if (this.currentMeasureType === 'line') return this.pointSelector.position?.point\n })()\n if (!dashedEnd) {\n this.dashed.hide()\n return\n }\n this.dashed.show()\n this.dashed.setPoints(dashedStart, dashedEnd)\n this.dashed.distanceItem.update(this.five)\n this.hook.emit('editedDashedLineChange', this.dashed)\n\n if (this.currentMeasureType === 'area') {\n this.area.areaItem.setCanSelect(false)\n if (this.area.points.length >= 2) {\n // 更新垂线(与落点是否合法无关)\n const mousePosition = this.pointSelector.position?.point\n if (mousePosition) {\n const perpendicularDashedStart = mousePosition\n const perpendicularDashedEnd = dashedEnd\n this.perpendicularDashed.setPoints(perpendicularDashedStart, perpendicularDashedEnd)\n this.perpendicularDashed.show()\n } else {\n this.perpendicularDashed.hide()\n }\n\n // 判断落点是否合法\n const segments = this.area.polyline.lines.map((line) => ({ start: line.points[0].position, end: line.points[1].position }))\n const intersected0 = isIntersecting({ start: dashedStart, end: dashedEnd }, segments)\n const intersected2 = isIntersecting({ start: dashedEnd, end: this.area.points[0] }, segments)\n /** true: 线段有交点,落点不合法; false: 线段没有交点,落点合法 */\n const intersected = intersected0 || intersected2\n if (intersected) {\n // ====== 落点不合法 ======\n // document.documentElement.style.cursor = 'not-allowed'\n this.area.hideArea()\n this.hook.emit('allowAddPointStateChange', 'forbid')\n } else {\n // ====== 落点合法 ======\n // document.documentElement.style.cursor = 'default'\n this.area.showArea()\n\n // 更新面积\n const newPoints = [...this.area.points, dashedEnd]\n // 更新面积Mesh\n this.area.polygon.updatePoints(newPoints)\n // 更新面积文字\n this.area.areaItem.updateArea(this.five)\n this.hook.emit('allowAddPointStateChange', 'allow')\n }\n } else {\n this.area.hideArea()\n this.perpendicularDashed.hide()\n // document.documentElement.style.cursor = 'default'\n }\n }\n\n this.five.needsRender = true\n }\n\n // ====================================================================================================================================\n\n // 下面一堆高亮相关\n private wantsTapGesture: EventCallback['wantsTapGesture'] = (raycaster) => {\n if (this.editParams.pointSelectorMode === 'cursor') return false\n if (this.lastPoint) return false // 编辑中\n\n // ================================= 这是选择面的逻辑 =================================\n const intersections = this.model.areas\n .map((area) => raycaster.intersectObject(area.polygon, true)[0]) // 获取所有的交点\n .sort((a, b) => a.distance - b.distance) // 按照距离排序\n const intersectionObject = intersections[0]?.object?.parent as any\n if (intersectionObject?.isPolygonMesh) {\n const area = this.model.areas.find((area) => area.polygon === intersectionObject)\n if (area) {\n const { x, y } = intersections[0].point.clone().project(this.five.camera)\n const left = `${((x + 1) / 2) * 100}%`\n const top = `${((-y + 1) / 2) * 100}%`\n this.chooseArea(area, { left, top })\n return false\n }\n }\n // ================================= 这后面是之前的选择线的逻辑 =================================\n const [target] = getFiveModel(this.five).intersectRaycaster(raycaster)\n if (!target) return\n const camera = this.five.camera\n const ndcTarget = target.point.clone().project(camera)\n const screenWidth = this.container.clientWidth\n const screenHeight = this.container.clientHeight\n const targetScreenPosition = new Vector2(ndcTarget.x * screenWidth, ndcTarget.y * screenHeight)\n // 把线的端点全部映射到屏幕上,过滤掉不在视野内的线,同时乘以屏幕宽 & 高\n const screenLines = this.model\n .getAllLines()\n .map((line) => {\n const [startPoint, endPoint] = line.points\n const ndcStartPoint = startPoint.position.clone().project(camera)\n const ndcEndPoint = endPoint.position.clone().project(camera)\n if (!isNDCPointInScreen(ndcStartPoint) && !isNDCPointInScreen(ndcEndPoint)) return null\n const startScreenPosition = new Vector2(ndcStartPoint.x * screenWidth, ndcStartPoint.y * screenHeight)\n const endScreenPosition = new Vector2(ndcEndPoint.x * screenWidth, ndcEndPoint.y * screenHeight)\n return { id: line.id, points: [startScreenPosition, endScreenPosition] }\n })\n .filter((line) => !!line) as { id: string; points: Vector2[] }[]\n if (screenLines.length === 0) return\n // 找这些线距离鼠标点击位置最近的线\n const distanceLines = screenLines\n .map((line) => {\n const closestPoint = closestPointOnLine(targetScreenPosition, line.points)\n return { id: line.id, distance: closestPoint.distanceTo(targetScreenPosition) }\n })\n .sort((a, b) => a.distance - b.distance)\n const closestScreenLine = distanceLines[0]\n if (closestScreenLine.distance > 20) return\n const closestLine = this.model.getAllLines().find(({ id }) => id === closestScreenLine.id)\n if (!closestLine) return\n this.chooseLine(closestLine)\n return false\n }\n\n private chooseLine = (line: Line) => {\n const highlightLines = line.getPolyline().lines\n this.deleteDom.setTarget(highlightLines).setLines(highlightLines).updatePosition().show()\n this.highlightLines(highlightLines)\n this.hook.emit('selectedChange', highlightLines)\n }\n\n private chooseArea = (area: Area, clickPosition: { left: string; top: string }) => {\n this.deleteDom.setTarget(area).updatePosition(clickPosition.left, `calc(${clickPosition.top} - 1.5rem)`).show() // 往上挪一点,出现在鼠标上方\n this.highlightArea(area)\n }\n\n private highlightArea(area: Area) {\n this.highlightLines(area.polyline.lines)\n this.five.needsRender = true\n }\n\n private unHighlightArea(area: Area) {\n this.unHighlightLines(area.polyline.lines)\n this.five.needsRender = true\n }\n\n private highlightLines(lines: Line[]) {\n lines.forEach((line) => this.highlightLine(line))\n }\n\n private unHighlightLines(lines: Line[]) {\n lines.forEach((line) => {\n line.selected = false\n line.distanceItem.unHighlight()\n this.group.remove(line.lightMesh)\n this.five.needsRender = true\n })\n }\n\n private highlightLine(line: Line) {\n this.unHighlightLines(this.model.getAllLines())\n if (line.selected) return\n line.selected = true\n this.group.add(line.lightMesh)\n line.distanceItem.highlight()\n this.five.needsRender = true\n }\n\n private deleteArea = (area: Area) => {\n this.unHighlightArea(area)\n area.dispose()\n this.deleteDom.hide()\n }\n\n private deleteLine = (lines: Line[]) => {\n const firstLine = lines[0]\n const polyline = this.model.getPolylineByLine(firstLine)\n if (!polyline) return\n this.model.removePolyline(polyline)\n polyline.lines.forEach((line) => this.removeLine(line))\n this.deleteDom.setLines([]).hide()\n }\n}\n","import type { Polyline } from '../Model/polyline'\nimport BaseController, { type ControllerParams } from './BaseController'\nimport type { Mode as FiveMode } from '@realsee/five-webgpu'\n\nexport default class ViewController extends BaseController {\n public type = 'view'\n\n public constructor(params: ControllerParams) {\n super(params)\n this.model.getAllLines().forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n this.group.add(line.mesh)\n line.mesh.updateMatrixWorld()\n })\n this.onFiveModeChange(this.five.getCurrentState().mode)\n this.onFivePanoWillArrive(this.five.getCurrentState().panoIndex)\n this.onFivePanoArrived(this.five.getCurrentState().panoIndex)\n this.updateDistanceUI()\n this.five.needsRender = true\n this.model.hook.on('polylineAdded', this.polylineAdded)\n this.model.hook.on('polylineRemoved', this.polylineRemoved)\n this.five.on('cameraUpdate', this.onCameraUpdate)\n this.five.on('panoArrived', this.onFivePanoArrived)\n this.five.on('modeChange', this.onFiveModeChange)\n this.five.on('panoWillArrive', this.onFivePanoWillArrive)\n }\n\n public dispose() {\n super.dispose()\n this.model.hook.off('polylineAdded', this.polylineAdded)\n this.model.hook.off('polylineRemoved', this.polylineRemoved)\n this.five.off('cameraUpdate', this.onCameraUpdate)\n this.five.off('panoArrived', this.onFivePanoArrived)\n this.five.off('modeChange', this.onFiveModeChange)\n this.five.off('panoWillArrive', this.onFivePanoWillArrive)\n this.five.needsRender = true\n this.hook.emit('selectedChange', [])\n }\n\n private polylineRemoved = (polyline: Polyline) => {\n polyline.lines.forEach((line) => this.removeLine(line))\n // TODO: 这个逻辑不太好,改进一下\n this.hook.emit(\n 'selectedChange',\n this.model\n .getAllLines()\n .filter((line) => line.selected)\n .map((line) => line),\n )\n }\n\n private polylineAdded = (polyline: Polyline) => {\n const { panoIndex, mode } = this.five.getCurrentState()\n polyline.lines.forEach((line) => {\n if (polyline.visibleFiveMode && !polyline.visibleFiveMode.includes(mode)) {\n line.mesh.visible = false\n }\n if (polyline.visiblePanoIndexes && !polyline.visiblePanoIndexes.includes(panoIndex)) {\n line.mesh.visible = false\n }\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n this.group.add(line.mesh)\n })\n this.updateDistanceUI()\n }\n\n private onCameraUpdate = () => {\n this.updateDistanceUI()\n }\n\n private onFiveModeChange = (mode: FiveMode) => {\n if (mode === 'Panorama') return\n\n this.model.polylines.forEach((polyline) => {\n if (polyline.visibleFiveMode && !polyline.visibleFiveMode.includes(mode)) {\n polyline.lines.forEach((line) => {\n line.mesh.visible = false\n line.distanceItem.update(this.five)\n })\n }\n })\n\n this.five.ready().then(() => {\n const mode = this.five.getCurrentState().mode\n if (mode === 'Panorama') return\n\n this.model.polylines.forEach((polyline) => {\n if (polyline.visibleFiveMode && polyline.visibleFiveMode.includes(mode)) {\n polyline.lines.forEach((line) => {\n line.mesh.visible = true\n line.distanceItem.update(this.five)\n })\n }\n })\n })\n }\n\n private onFivePanoWillArrive = (panoIndex: number) => {\n this.model.polylines.forEach((polyline) => {\n if (\n (polyline.visiblePanoIndexes && !polyline.visiblePanoIndexes.includes(panoIndex)) ||\n (polyline.visibleFiveMode && !polyline.visibleFiveMode.includes(this.five.getCurrentState().mode))\n ) {\n polyline.lines.forEach((line) => {\n line.mesh.visible = false\n line.distanceItem.update(this.five)\n })\n }\n })\n }\n\n private onFivePanoArrived = (panoIndex: number) => {\n this.model.polylines.forEach((polyline) => {\n if (polyline.visiblePanoIndexes && polyline.visiblePanoIndexes.includes(panoIndex)) {\n if (polyline.visibleFiveMode && polyline.visibleFiveMode.includes(this.five.getCurrentState().mode)) {\n polyline.lines.forEach((line) => {\n line.mesh.visible = true\n line.distanceItem.update(this.five)\n })\n }\n }\n })\n }\n}\n","import { Vector2 } from 'three/webgpu'\nimport type { Vector3 } from 'three/webgpu'\n\nexport default function ndc2Screen(ndcPosition: Vector3, containerSize: { width: number; height: number }) {\n const left = ((ndcPosition.x + 1) / 2) * containerSize.width\n const top = (-(ndcPosition.y - 1) / 2) * containerSize.height\n return new Vector2(left, top)\n}\n","import type { Vector2 } from 'three/webgpu'\nimport type Point from '../Model/point'\nimport type { Five } from '@realsee/five-webgpu'\nimport ndc2Screen from './ndc2Screen'\nimport isNDCPointInScreen from './isNDCPointInScreen'\n\n/**\n * @param tapPoint 注意这里的坐标是相对于 FiveElement 的\n */\n\nexport function findClosestPoint(five: Five, points: Point[], tapPoint: Vector2, maxDistance?: number) {\n const container = five.getElement()\n if (!container) return null\n if (points.length === 0) return null\n\n const containerSize = { width: container.clientWidth, height: container.clientHeight }\n const ndcPoints = points\n .map((point) => {\n const ndcPosition = point.position.clone().project(five.camera)\n if (!isNDCPointInScreen(ndcPosition)) return { distance: Infinity, point }\n const screenPosition = ndc2Screen(ndcPosition, containerSize)\n const distance = screenPosition.distanceTo(tapPoint)\n return { distance, point }\n })\n .sort((a, b) => a.distance - b.distance)\n if (typeof maxDistance === 'number' && ndcPoints[0].distance > maxDistance) return null\n return ndcPoints[0]\n}\n","import type Hammer from 'hammerjs'\nimport { Vector2 } from 'three/webgpu'\n\n/**\n * 从 Hammer 事件中获取操作的点在交互 DOM 中的位置\n * @ignore TODO: make a suitable name\n */\nexport function getPointFromHammerEvent(event: (typeof Hammer)['Input']) {\n // clientX 与 clientY 是相对 document 的,需要转换成相对于 target 的坐标\n const { x: clientX, y: clientY } = event.center\n const { clientWidth, clientHeight } = event.target\n const clientRect = event.target.getBoundingClientRect()\n const position = new Vector2(clientX, clientY).sub(new Vector2(clientRect.left, clientRect.top))\n const mouse = new Vector2((position.x / clientWidth) * 2 - 1, -(position.y / clientHeight) * 2 + 1)\n return { point: position, ndcPoint: mouse }\n}\n","import type Line from '../Model/line'\nimport type Point from '../Model/point'\nimport type { EventCallback, Intersection, IntersectMeshInterface } from '@realsee/five-webgpu'\nimport type { Polyline } from '../Model/polyline'\nimport type Hammer from 'hammerjs'\nimport DeleteDom from '../Modules/DeleteDom'\nimport isNDCPointInScreen from '../utils/isNDCPointInScreen'\nimport BaseController, { type ControllerParams } from './BaseController'\nimport { Raycaster, Vector2 } from 'three/webgpu'\nimport { closestPointOnLine } from '../utils/math'\nimport { findClosestPoint } from '../utils/findClosestPoint'\nimport { getPointFromHammerEvent } from '../../shared-utils/getPointFromHammerEvent'\nimport Area from '../Model/area'\nimport { PolygonMesh } from '../Model/polygon'\nimport { getFiveModel } from '../../shared-utils/five/getFiveModel'\n\nconst disableFiveEvent = (): false => false\n\nexport default class WatchController extends BaseController {\n public type = 'watch'\n private deleteDom: DeleteDom\n private choose: 'line' | Area | null // tmd 真没时间改了,先这样吧,理解万岁\n private highlightedLines: Line[] = []\n private highlightedArea: Area\n private fiveElement?: HTMLCanvasElement\n private editPointState?: {\n point: Point\n associatedLines: Line[]\n }\n private hammer?: InstanceType<(typeof Hammer)['Manager']>\n private isDisposed = false\n\n public constructor(params: ControllerParams) {\n super(params)\n this.deleteDom = new DeleteDom(this.five, {\n i18n: this.config.i18n,\n onClick: () => {\n if (this.choose === 'line') this.deleteLine()\n else if (this.choose instanceof Area) this.deleteArea(this.choose)\n },\n cancel: this.cancelDeleteClickCallback,\n }).appendTo(this.container)\n this.model.getAllLines().forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n line.hook.on('selected', this.chooseLine)\n line.distanceItem.setCanSelect(true)\n this.group.add(line.mesh)\n })\n this.model.getAllAreas().forEach((area) => {\n area.areaItem.appendTo(this.container)\n area.areaItem.updateArea(this.five)\n area.hook.on('selected', this.chooseArea)\n area.areaItem.setCanSelect(true)\n\n this.group.add(area.polygon)\n area.polyline.lines.forEach((line) => {\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n this.group.add(line.mesh)\n })\n })\n const fiveElement = this.five.getElement()\n if (fiveElement) {\n this.fiveElement = fiveElement\n void import('hammerjs').then(({ default: Hammer }) => {\n if (this.isDisposed) return\n const hammer = new Hammer(fiveElement)\n this.hammer = hammer\n hammer.on('pan', this.onPan)\n hammer.on('panstart', this.onPanStart)\n hammer.on('panend', this.onPanEnd)\n })\n }\n\n this.updateDistanceUI()\n this.five.needsRender = true\n this.five.on('cameraUpdate', this.onCameraUpdate)\n this.five.on('wantsTapGesture', this.wantsTapGesture)\n this.five.on('wantsPanGesture', this.wantsPanGesture)\n this.five.on('wantsChangeMode', disableFiveEvent)\n this.model.hook.on('polylineRemoved', this.polylineRemoved)\n }\n\n public dispose() {\n this.isDisposed = true\n super.dispose()\n this.deleteDom.dispose()\n this.model.hook.off('polylineRemoved', this.polylineRemoved)\n this.model.getAllLines().forEach((line) => line.hook.off('selected', this.chooseLine))\n this.five.off('cameraUpdate', this.onCameraUpdate)\n this.five.off('wantsPanGesture', this.wantsPanGesture)\n this.five.off('wantsTapGesture', this.wantsTapGesture)\n this.five.off('wantsChangeMode', disableFiveEvent)\n this.five.needsRender = true\n this.hook.emit('selectedChange', [])\n this.hammer?.destroy()\n }\n\n public highlightLine(line: Line) {\n if (line.selected) return\n line.selected = true\n this.group.add(line.lightMesh)\n line.distanceItem.highlight()\n this.five.needsRender = true\n }\n\n public clearHighlightLines() {\n if (this.group.children.length === 0) return\n this.unHighlightLines(this.highlightedLines)\n this.highlightedLines = []\n }\n\n private highlightArea(area: Area) {\n this.unHighlightLines()\n this.unHighlightArea()\n this.highlightLines(area.polyline.lines)\n this.five.needsRender = true\n }\n\n private unHighlightArea(_area?: Area) {\n const area = _area ?? this.highlightedArea\n if (!area) return\n this.unHighlightLines(area.polyline.lines)\n this.five.needsRender = true\n }\n\n private highlightLines(lines: Line[]) {\n this.unHighlightLines()\n this.highlightedLines = lines\n lines.forEach((line) => this.highlightLine(line))\n }\n\n private unHighlightLines(_lines?: Line[]) {\n this.unHighlightArea()\n const lines = _lines ?? this.highlightedLines\n if (!lines) return\n lines.forEach((line) => {\n line.selected = false\n line.distanceItem.unHighlight()\n this.group.remove(line.lightMesh)\n this.five.needsRender = true\n })\n }\n\n private onPanStart = (e: (typeof Hammer)['Input']) => {\n if (this.model.getAllLines().length === 0 || !this.fiveElement) return\n const mouse = getPointFromHammerEvent(e).point\n const closestPoint = findClosestPoint(this.five, this.model.getAllPoints(), mouse, 20)?.point\n if (!closestPoint) {\n this.editPointState = undefined\n return\n }\n const closestPolyline = this.model.polylines.find((polyline) => polyline.includes(closestPoint))\n const editPointState = {\n point: closestPoint,\n associatedLines: closestPolyline.lines,\n }\n const cancelDragLine = this.hook.emit('wantsDragLine', {\n point: closestPoint.id,\n lines: editPointState.associatedLines.map(({ id }) => id),\n })\n if (cancelDragLine) return\n this.editPointState = editPointState\n this.magnifier.appendTo(this.container)\n this.magnifier.enable()\n this.group.add(this.mouseGroup)\n }\n\n private onPanEnd = () => {\n if (!this.editPointState) return\n // 把拖动的线从虚线转换为实线\n this.editPointState.associatedLines.forEach((line) => line.mesh.setMaterial({ dashed: false }))\n // 还原选中态\n this.highlightLines(this.editPointState.associatedLines)\n this.editPointState = undefined\n\n this.magnifier.disable()\n this.group.remove(this.mouseGroup)\n }\n\n private onPan = (e: (typeof Hammer)['Input']) => {\n if (!this.editPointState || !this.fiveElement) return\n const mouse = getPointFromHammerEvent(e).ndcPoint\n const raycaster = new Raycaster()\n raycaster.setFromCamera(mouse, this.five.camera)\n const [intersection] = getFiveModel(this.five).intersectRaycaster(raycaster)\n if (!intersection) return\n this.onIntersectionUpdate(intersection)\n }\n\n private onIntersectionUpdate = (intersection: Intersection, mesh?: IntersectMeshInterface) => {\n if (!this.editPointState) return\n // 拖动过程中清除选中态\n this.clearHighlightLines()\n // 把拖动点相关的线变成虚线 & 改变相关线的位置\n this.editPointState.point.position.copy(intersection.point)\n this.editPointState.associatedLines.forEach((line) => {\n line.mesh.setPoints(line.points[0].position.clone(), line.points[1].position.clone())\n line.lightMesh.setPoints(line.points[0].position.clone(), line.points[1].position.clone())\n line.mesh.setMaterial({ dashed: true })\n })\n this.updateDistanceUI()\n this.magnifier.renderWithPoint(intersection.point)\n this.mouseGroup.position.copy(intersection.point)\n if (mesh) {\n this.mouseGroup.quaternion.copy(mesh.quaternion)\n } else if (intersection.face) {\n const face = intersection.face.normal\n const positionVector = face.clone().multiplyScalar(0.05)\n const position = intersection.point.clone().add(positionVector)\n const lookAtVector = position.clone().add(positionVector)\n this.mouseGroup.lookAt(lookAtVector)\n }\n this.five.needsRender = true\n this.hook.emit(\n 'selectedChange',\n this.editPointState.associatedLines.map((line) => line),\n )\n }\n\n private wantsPanGesture: EventCallback['wantsPanGesture'] = () => {\n if (this.editPointState) return false\n }\n\n private wantsTapGesture: EventCallback['wantsTapGesture'] = (raycaster) => {\n // ================================= 这是选择面的逻辑 =================================\n const intersections = this.model.areas\n .map((area) => raycaster.intersectObject(area.polygon, true)[0]) // 获取所有的交点\n .sort((a, b) => a.distance - b.distance) // 按照距离排序\n const intersectionObject = intersections[0]?.object.parent\n if (intersectionObject instanceof PolygonMesh) {\n const area = this.model.areas.find((area) => area.polygon === intersectionObject)\n if (area) {\n const { x, y } = intersections[0].point.clone().project(this.five.camera)\n const left = `${((x + 1) / 2) * 100}%`\n const top = `${((-y + 1) / 2) * 100}%`\n this.chooseArea(area, { left, top })\n return false\n }\n }\n // ================================= 这后面是之前的选择线的逻辑 =================================\n const model = getFiveModel(this.five)\n const [target] = model.intersectRaycaster(raycaster)\n if (!target) return\n const camera = this.five.camera\n const ndcTarget = target.point.clone().project(camera)\n const screenWidth = this.container.clientWidth\n const screenHeight = this.container.clientHeight\n const targetScreenPosition = new Vector2(ndcTarget.x * screenWidth, ndcTarget.y * screenHeight)\n // 把线的端点全部映射到屏幕上,过滤掉不在视野内的线,同时乘以屏幕宽 & 高\n const screenLines = this.model\n .getAllLines()\n .map((line) => {\n const [startPoint, endPoint] = line.points\n const ndcStartPoint = startPoint.position.clone().project(camera)\n const ndcEndPoint = endPoint.position.clone().project(camera)\n if (!isNDCPointInScreen(ndcStartPoint) && !isNDCPointInScreen(ndcEndPoint)) return null\n const startScreenPosition = new Vector2(ndcStartPoint.x * screenWidth, ndcStartPoint.y * screenHeight)\n const endScreenPosition = new Vector2(ndcEndPoint.x * screenWidth, ndcEndPoint.y * screenHeight)\n return { id: line.id, points: [startScreenPosition, endScreenPosition] }\n })\n .filter((line) => !!line) as { id: string; points: Vector2[] }[]\n if (screenLines.length === 0) return\n // 找这些线距离鼠标点击位置最近的线\n const distanceLines = screenLines\n .map((line) => {\n const closestPoint = closestPointOnLine(targetScreenPosition, line.points)\n return { id: line.id, distance: closestPoint.distanceTo(targetScreenPosition) }\n })\n .sort((a, b) => a.distance - b.distance)\n const closestScreenLine = distanceLines[0]\n if (closestScreenLine.distance > 20) return\n const closestLine = this.model.getAllLines().find(({ id }) => id === closestScreenLine.id)\n if (!closestLine) return\n this.chooseLine(closestLine)\n return false\n }\n\n private chooseLine = (line: Line) => {\n this.choose = 'line'\n const highlightLines = line.getPolyline().lines\n this.highlightLines(highlightLines)\n this.five.needsRender = true\n this.hook.emit(\n 'selectedChange',\n highlightLines.map((line) => line),\n )\n }\n\n private chooseArea = (area: Area, clickPosition: { left: string; top: string }) => {\n this.choose = area\n this.deleteDom.updatePosition(clickPosition.left, `calc(${clickPosition.top} - 20px)`).show() // 往上挪一点,出现在鼠标上方\n this.highlightArea(area)\n }\n\n private polylineRemoved = (polyline: Polyline) => {\n polyline.lines.forEach((line) => this.removeLine(line))\n // TODO: 这个逻辑不太好,改进一下\n this.hook.emit(\n 'selectedChange',\n this.model\n .getAllLines()\n .filter((line) => line.selected)\n .map((line) => line),\n )\n }\n\n private onCameraUpdate = () => {\n this.updateDistanceUI()\n this.highlightedLines.length > 0 && this.deleteDom.updatePosition()\n }\n\n private deleteArea = (area: Area) => {\n this.unHighlightArea(area)\n area.dispose()\n this.deleteDom.hide()\n }\n\n private deleteLine = () => {\n const firstLine = this.highlightedLines[0]\n const polyline = this.model.getPolylineByLine(firstLine)\n if (!polyline) return\n this.model.removePolyline(polyline)\n this.highlightedLines = []\n this.deleteDom.setLines([]).hide()\n }\n\n private cancelDeleteClickCallback = () => {\n this.deleteDom.hide()\n this.clearHighlightLines()\n this.unHighlightArea()\n }\n}\n","import { Subscribe } from '../../shared-utils/Subscribe'\nimport type { Config } from '../typings'\nimport type { MeasurePluginData } from '../typings/data'\nimport type Area from './area'\nimport type Line from './line'\nimport { Polyline } from './polyline'\n\ntype IModelEvent = {\n /** 新增线条\n * @param line 被创建的线条\n */\n polylineAdded: (line: Polyline) => void\n\n /** 新增面积\n * @param area 被创建的面积\n */\n areaAdded: (area: Area) => void\n\n /** 删除线条\n * @param lines 被删除的线条数组\n */\n polylineRemoved: (lines: Polyline) => void\n}\n\nexport class Model {\n public readonly config?: Config\n public readonly polylines: Polyline[] = []\n public readonly areas: Area[] = []\n public readonly hook = new Subscribe<IModelEvent>()\n\n public constructor(config?: Config) {\n this.config = config\n }\n\n public addPolyline(polyline: Polyline) {\n if (this.includes(polyline)) {\n console.error(new Error('不能重复添加 polyline'))\n return\n }\n this.polylines.push(polyline)\n this.hook.emit('polylineAdded', polyline)\n }\n\n public addArea(area: Area) {\n if (this.areas.find(({ id }) => id === area.id) !== undefined) {\n console.error(new Error('不能重复添加 area'))\n return\n }\n this.areas.push(area)\n this.hook.emit('areaAdded', area)\n }\n\n public replacePolylineByID(id: string, polyline: Polyline) {\n const prevPolyline = this.getPolylineByID(id)\n prevPolyline?.replace(polyline)\n }\n\n public removePolyline(polyline: Polyline) {\n const index = this.polylines.findIndex(({ id }) => id === polyline.id)\n if (index === -1) {\n console.error(new Error('polyline 不存在'))\n return\n }\n this.polylines.splice(index, 1)\n this.hook.emit('polylineRemoved', polyline)\n }\n\n public removeArea(area: Area) {\n const index = this.areas.findIndex(({ id }) => id === area.id)\n if (index === -1) {\n console.error(new Error('area 不存在'))\n return\n }\n this.areas.splice(index, 1)\n }\n\n public getPolylineByID(id: string) {\n return this.polylines.find((polyline) => polyline.id === id)\n }\n\n public getPolylineByLine(line: Line) {\n return this.polylines.find((polyline) => polyline.includes(line))\n }\n\n public getLineByID(id: string) {\n return this.getAllLines().find((line) => line.id === id)\n }\n\n public getAllLines() {\n return this.polylines.map((polyline) => polyline.lines).flat(1)\n }\n\n public getAllAreas() {\n return this.areas\n }\n\n public getAllPoints() {\n return this.polylines.map((polyline) => polyline.points).flat(1)\n }\n\n public includes(item: Polyline) {\n return this.polylines.find(({ id }) => id === item.id) !== undefined\n }\n\n public clear() {\n this.polylines.forEach((polyline) => this.hook.emit('polylineRemoved', polyline))\n this.areas.forEach((area) => area.dispose())\n this.polylines.splice(0, this.polylines.length)\n this.areas.splice(0, this.areas.length)\n }\n\n public dispose() {\n this.clear()\n }\n\n public getClosestPoint() {}\n\n public parse(data: MeasurePluginData) {\n this.clear()\n this.polylines.push(...data.polylines.map((polylineData) => new Polyline({ model: this }).fromJson(polylineData)))\n this.polylines.forEach((polyline) => this.hook.emit('polylineAdded', polyline))\n }\n\n public toJson(): MeasurePluginData {\n return {\n polylines: this.polylines.map((polyline) => polyline.toJson()).filter((polylines) => polylines.lines.length > 0),\n }\n }\n}\n","function noop(): void {\n return void 0\n}\n\n/**\n * 空函数\n */\nexport default noop\n","import {\n CurvePath,\n DoubleSide,\n Group,\n LinearFilter,\n LineCurve3,\n Mesh,\n MeshBasicMaterial,\n PlaneGeometry,\n BufferAttribute,\n SphereGeometry,\n SRGBColorSpace,\n TextureLoader,\n TubeGeometry,\n Vector3,\n} from 'three/webgpu'\n\n// 移动端纹理贴图(只有十字不带圆圈)\nconst mobileTextureUrl = `data:image/png;base64,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`\n\n// pc端纹理贴图(带圆圈)\nconst pcTextureUrl = `data:image/png;base64,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`\n\n\nexport interface MouseGroupParameter {\n isMobile?: boolean\n useNormalVector?: boolean // 是否展示法向量\n ballColor?: number // 法向量小球色值\n}\n\nexport function getMouseGroup(params: MouseGroupParameter) {\n const isMobile = params.isMobile ?? true\n const useNormalVector = params.useNormalVector ?? true\n let ballColor = 0x9ded6b\n if (useNormalVector && params.ballColor >= 0) {\n ballColor = params.ballColor\n }\n\n const group = new Group()\n // 底部纹理贴图面片\n const planGeometry = new PlaneGeometry(0.3, 0.3)\n const planTextureUrl = isMobile ? mobileTextureUrl : pcTextureUrl\n const planTexture = new TextureLoader().load(planTextureUrl)\n planTexture.colorSpace = SRGBColorSpace\n planTexture.minFilter = LinearFilter\n const planMaterial = new MeshBasicMaterial({\n map: planTexture,\n transparent: true,\n depthTest: false,\n })\n const planMesh = new Mesh(planGeometry, planMaterial)\n // 法向量垂直管\n const zPath = new CurvePath<Vector3>()\n zPath.add(new LineCurve3(new Vector3(0, 0, 0), new Vector3(0, 0, 0.1)))\n const zGeometry = new TubeGeometry(zPath, 8, 0.003)\n const colors = new Float32Array(zGeometry.getAttribute('position').count * 4)\n const uv = zGeometry.getAttribute('uv')\n for (let i = 0; i < uv.count; i++) colors.set([1, 1, 1, 1 - uv.getX(i)], i * 4)\n zGeometry.setAttribute('color', new BufferAttribute(colors, 4))\n const zMaterial = new MeshBasicMaterial({\n vertexColors: true,\n depthTest: false,\n transparent: true,\n })\n const zMesh = new Mesh(zGeometry, zMaterial)\n // 法向量圆球\n const ballGeometry = new SphereGeometry(0.01, 20, 20)\n const ballMaterial = new MeshBasicMaterial({\n color: ballColor,\n depthTest: false,\n transparent: true,\n side: DoubleSide,\n })\n const ballMesh = new Mesh(ballGeometry, ballMaterial)\n ballMesh.position.set(0, 0, 0.1)\n\n group.name = 'mouse-current'\n group.add(planMesh)\n if (useNormalVector) group.add(zMesh, ballMesh)\n\n return group\n}\n","import type { Five, Intersection, IntersectMeshInterface } from '@realsee/five-webgpu'\nimport type { Group, Vector3 } from 'three/webgpu'\nimport { DoubleSide, Mesh, MeshBasicMaterial, Raycaster, RingGeometry } from 'three/webgpu'\nimport type { Model } from '../../Model'\nimport type { PanoMeasurePluginEvent } from '../../typings/event.type'\nimport Point from '../../Model/point'\nimport * as TWEEN from '@tweenjs/tween.js'\nimport htmlString from '../../../shared-utils/three/PointSelector/utils/html'\nimport { requestAnimationFrameInterval } from '../../../shared-utils/animationFrame'\nimport noop from '../../../shared-utils/noop'\nimport { getMouseGroup } from '../../utils/mouseGroup'\nimport type { OpenParameter } from '../../typings/data'\nimport { calculateThreeMouse } from '../../../shared-utils/five/calculateThreeMouse'\nimport type { Subscribe } from '../../../shared-utils/Subscribe'\nimport { getFiveModel } from '../../../shared-utils/five/getFiveModel'\n\nexport interface RangePieceControllerParams {\n openParams: OpenParameter\n container: Element\n five: Five\n group: Group\n model: Model\n mouseGroup: Group\n hook: Subscribe<PanoMeasurePluginEvent>\n}\n\nexport default class RangePieceController {\n private container = document.createElement('div')\n private five: Five\n private group: Group\n private mouseGroup: Group\n private hasAppendMouseGroup = false\n private hook: Subscribe<PanoMeasurePluginEvent>\n private content: HTMLElement | null\n private intersectMesh: Mesh\n private centerMouseXY: any\n private raycaster = new Raycaster()\n private pieceStyl = {\n matrix3d: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],\n scale: 1,\n opacity: 0.4,\n }\n\n\n constructor(params: RangePieceControllerParams) {\n this.five = params.five\n this.hook = params.hook\n this.group = params.group\n this.mouseGroup = getMouseGroup({ isMobile: true, ...params.openParams.crossHairParameter })\n this.container.innerHTML = htmlString\n this.container.classList.add('range-piece-controller')\n this.content = this.container.querySelector<HTMLElement>('.range-piece__content')\n if (this.content) {\n this.content.style.transform = `matrix3d(${this.pieceStyl.matrix3d.toString()}) scale(${this.pieceStyl.scale})`\n this.content.style.opacity = `${this.pieceStyl.opacity}`\n }\n params.container.append(this.container)\n\n this.intersectMesh = new Mesh(\n new RingGeometry(0.04, 0.08, 32),\n new MeshBasicMaterial({ color: 0x12fffb, opacity: 0, side: DoubleSide, transparent: true }),\n )\n\n this.container.addEventListener('animationend', this.computedCenterMouseXY)\n\n this.five.on('cameraUpdate', this.onCameraDirectionUpdate)\n this.hook.on('willChangeState', this.onWillChangeState)\n }\n\n public dispose() {\n this.container.removeEventListener('animationend', this.computedCenterMouseXY)\n this.five.off('cameraUpdate', this.onCameraDirectionUpdate)\n this.hook.off('willChangeState', this.onWillChangeState)\n this.container.remove()\n this.group.remove(this.mouseGroup)\n this.mouseGroup.remove()\n this.hasAppendMouseGroup = false\n this.five.scene.remove(this.intersectMesh)\n }\n\n private onCameraDirectionUpdate = () => {\n const intersection = this.getIntersection()\n if (intersection) {\n this.pieceChange(intersection)\n this.updateMouseGroup(intersection)\n const nowPoint = new Point(this.mouseGroup.position)\n this.hook.emit('nowPointChange', nowPoint)\n }\n }\n\n private onWillChangeState: PanoMeasurePluginEvent['willChangeState'] = (state, newState) => {\n this.dotAnimation()\n const point = this.getIntersection()?.point\n if (!point) return\n if (newState === 'editing') {\n this.hook.emit('getStartPoint', new Point(point))\n } else {\n this.hook.emit('getEndPoint', new Point(point))\n }\n }\n\n /** 计算目标中心点经纬度 */\n private computedCenterMouseXY = () => {\n const aimRef = this.container.querySelector<HTMLElement>('.range-piece__aim')\n if (!aimRef) return null\n const { left, top, width, height } = aimRef.getBoundingClientRect()\n const mouseX = Math.round(left + width / 2)\n const mouseY = Math.round(top + height / 2)\n const mouse = { x: mouseX, y: mouseY }\n const mouseXY = calculateThreeMouse(mouse, this.five.getElement()) // 经纬度\n this.centerMouseXY = mouseXY\n }\n\n /** 计算目标中心点intersection */\n private getIntersection = () => {\n if (!this.centerMouseXY) return null\n this.raycaster.setFromCamera(this.centerMouseXY, this.five.camera)\n const intersection = getFiveModel(this.five).intersectRaycaster(this.raycaster)[0]\n if (intersection) return intersection\n else return null\n }\n\n private pieceChange(intersection: Intersection) {\n const face = intersection.face\n const point = intersection.point\n if (face && point) {\n const normal = face.normal.clone()\n const positionVector = normal.clone().multiplyScalar(0.05)\n const position = point.clone().add(positionVector)\n this.intersectMesh.position.copy(position)\n const lookAtVector = position.clone().add(positionVector)\n this.intersectMesh.lookAt(lookAtVector)\n this.five.scene.add(this.intersectMesh)\n const matrix = this.intersectMesh.modelViewMatrix.clone().toArray()\n this.changePieceStyl('matrix3d', matrix)\n const scale = this.calculateSize(point)\n this.changePieceStyl('scale', scale)\n }\n }\n\n private calculateSize(vector: Vector3) {\n if (!vector) return\n const cameraPos = this.five.camera.position\n let distance = vector.distanceTo(cameraPos)\n const maxDis = 4\n const minDis = 1\n if (distance > maxDis) distance = maxDis\n if (distance < minDis) distance = minDis\n const scale = (-0.51 / (maxDis - minDis)) * distance + 1\n return scale\n }\n\n /** 点击按钮时圆片动画 */\n private dotAnimation() {\n const firstEasing = TWEEN.Easing.Quadratic.InOut\n const from = { opacity: 0.4, scale: this.pieceStyl.scale }\n const to = { opacity: [1, 0.4], scale: [this.pieceStyl.scale * 0.8, this.pieceStyl.scale] }\n let stop = noop\n\n const firstTween = new TWEEN.Tween(from)\n .to(to, 500)\n .easing(firstEasing)\n .start(0)\n .onUpdate(({ opacity, scale }) => {\n this.changePieceStyl('scale', scale)\n this.changePieceStyl('opacity', opacity)\n })\n .onComplete(() => {\n stop()\n })\n\n stop = requestAnimationFrameInterval((time: number) => {\n firstTween.update(time)\n })\n }\n\n private changePieceStyl(key, value) {\n if (!this.content) return\n this.pieceStyl[key] = value\n this.content.style.transform = `matrix3d(${this.pieceStyl.matrix3d.toString()}) scale(${this.pieceStyl.scale})`\n this.content.style.opacity = `${this.pieceStyl.opacity}`\n }\n\n private updateMouseGroup(intersection: Intersection, mesh?: IntersectMeshInterface) {\n if (!this.hasAppendMouseGroup) {\n this.group.add(this.mouseGroup)\n this.hasAppendMouseGroup = true\n const aimRef = this.container.querySelector<HTMLElement>('.range-piece__aim')\n if (aimRef) aimRef.style.opacity = '0'\n }\n if (!intersection) return this.mouseGroup\n this.mouseGroup.position.copy(intersection.point)\n // ============ update mouseGroup quaternion ============\n if (mesh) {\n this.mouseGroup.quaternion.copy(mesh.quaternion)\n } else if (intersection.face) {\n const normal = intersection.face.normal\n const positionVector = normal.clone().multiplyScalar(0.05)\n const position = intersection.point.clone().add(positionVector)\n const lookAtVector = position.clone().add(positionVector)\n this.mouseGroup.lookAt(lookAtVector)\n }\n return this.mouseGroup\n }\n}\n","import type Point from '../Model/point'\nimport type { EventCallback } from '@realsee/five-webgpu'\nimport type { ControllerParams } from './BaseController'\nimport { Model } from '../Model'\nimport Line from '../Model/line'\nimport BaseController from './BaseController'\nimport DeleteDom from '../Modules/DeleteDom'\nimport { Vector2 } from 'three/webgpu'\nimport isNDCPointInScreen from '../utils/isNDCPointInScreen'\nimport { closestPointOnLine } from '../utils/math'\nimport { Polyline } from '../Model/polyline'\nimport RangePieceController from '../Modules/rangePiece'\nimport { getFiveModel } from '../../shared-utils/five/getFiveModel'\n\nexport type State = 'watching' | 'editing'\n\nexport default class MixedController extends BaseController {\n public state: State = 'watching'\n public polyline: Polyline\n private hasAppendDashed = false\n private mobileStartPoint: Point | null = null\n private mobileNowPoint: Point | null = null\n private highlightedLines: Line[] = []\n private deleteDom: DeleteDom\n private rangePieceController: RangePieceController\n private disposers: Function[] = []\n\n public constructor(params: ControllerParams) {\n super(params)\n this.model = new Model(this.config)\n this.polyline = new Polyline({ model: this.model })\n this.rangePieceController = new RangePieceController(params)\n this.deleteDom = new DeleteDom(this.five, {\n i18n: this.config.i18n,\n onClick: this.deleteDomClickCallback,\n cancel: this.cancelDeleteClickCallback,\n }).appendTo(this.container)\n // ==================== 事件监听 ====================\n // five\n this.five.on('cameraUpdate', this.onCameraUpdate)\n this.five.on('wantsTapGesture', this.onWantsTapGesture)\n this.five.on('wantsToMoveToPano', this.onWantsToMoveToPano)\n // five effect\n this.five.helperVisible = false\n // ==================== 触发事件 ====================\n this.hook.emit('editedDashedLineChange', null)\n // ==================== 其他 ====================\n this.hook.on('getStartPoint', this.onGetStartPoint)\n this.hook.on('getEndPoint', this.onGetEndPoint)\n this.hook.on('nowPointChange', this.onNowPointChange)\n this.hook.on('willChangeState', this.onWillChangeState)\n this.five.refresh()\n }\n\n public dispose() {\n super.dispose()\n this.disposers.forEach((disposer) => disposer())\n // five effect\n this.five.helperVisible = true\n this.rangePieceController.dispose()\n this.deleteDom.dispose()\n this.group.remove(this.mouseGroup)\n this.dashed.remove()\n this.perpendicularDashed.remove()\n // ==================== 解除事件监听 ====================\n // five\n this.five.off('cameraUpdate', this.onCameraUpdate)\n this.five.off('wantsTapGesture', this.onWantsTapGesture)\n this.five.off('wantsToMoveToPano', this.onWantsToMoveToPano)\n\n this.hook.off('getStartPoint', this.onGetStartPoint)\n this.hook.off('getEndPoint', this.onGetEndPoint)\n this.hook.off('nowPointChange', this.onNowPointChange)\n this.hook.off('willChangeState', this.onWillChangeState)\n this.hook.emit('selectedChange', [])\n this.five.needsRender = true\n }\n\n public highlightLine(line: Line) {\n if (line.selected) return\n line.selected = true\n this.group.add(line.lightMesh)\n line.distanceItem.highlight()\n this.five.needsRender = true\n }\n\n public clearHighlightLines() {\n if (this.group.children.length === 0) return\n this.deleteDom.setLines([]).hide()\n this.model.getAllLines().forEach((line) => {\n line.selected = false\n line.distanceItem.unHighlight()\n this.group.remove(line.lightMesh)\n })\n this.highlightedLines = []\n this.five.needsRender = true\n }\n\n public getEditingLines() {\n return this.model.polylines\n }\n\n private onWantsTapGesture: EventCallback['wantsTapGesture'] = (raycaster) => {\n if (this.state === 'editing') return false\n const model = getFiveModel(this.five)\n\n const [target] = model.intersectRaycaster(raycaster)\n if (!target) return\n const camera = this.five.camera\n const ndcTarget = target.point.clone().project(camera)\n const screenWidth = this.container.clientWidth\n const screenHeight = this.container.clientHeight\n const targetScreenPosition = new Vector2(ndcTarget.x * screenWidth, ndcTarget.y * screenHeight)\n // 把线的端点全部映射到屏幕上,过滤掉不在视野内的线,同时乘以屏幕宽 & 高\n const screenLines = this.model\n .getAllLines()\n .map((line) => {\n const [startPoint, endPoint] = line.points\n const ndcStartPoint = startPoint.position.clone().project(camera)\n const ndcEndPoint = endPoint.position.clone().project(camera)\n if (!isNDCPointInScreen(ndcStartPoint) && !isNDCPointInScreen(ndcEndPoint)) return null\n const startScreenPosition = new Vector2(ndcStartPoint.x * screenWidth, ndcStartPoint.y * screenHeight)\n const endScreenPosition = new Vector2(ndcEndPoint.x * screenWidth, ndcEndPoint.y * screenHeight)\n return { id: line.id, points: [startScreenPosition, endScreenPosition] }\n })\n .filter((line) => !!line) as { id: string; points: Vector2[] }[]\n if (screenLines.length === 0) return\n // 找这些线距离鼠标点击位置最近的线\n const distanceLines = screenLines\n .map((line) => {\n const closestPoint = closestPointOnLine(targetScreenPosition, line.points)\n return { id: line.id, distance: closestPoint.distanceTo(targetScreenPosition) }\n })\n .sort((a, b) => a.distance - b.distance)\n const closestScreenLine = distanceLines[0]\n if (closestScreenLine.distance > 20) return\n const closestLine = this.model.getAllLines().find(({ id }) => id === closestScreenLine.id)\n if (!closestLine) return\n this.chooseLine(closestLine)\n return false\n }\n\n /** 编辑时取消走点,watch时可以走 */\n private onWantsToMoveToPano = () => this.state === 'watching'\n\n /** 移动全景时更新 distanceItem 在屏幕上的位置 */\n private onCameraUpdate = () => {\n this.updateDistanceUI()\n this.dashed.distanceItem.update(this.five)\n }\n\n /** mobile态时更新虚线 */\n private updateMobileDashed = () => {\n if (!this.mobileStartPoint || !this.mobileNowPoint) return\n this.dashed.setPoints(this.mobileStartPoint.position, this.mobileNowPoint.position)\n this.dashed.distanceItem.update(this.five)\n this.hook.emit('editedDashedLineChange', this.dashed)\n }\n\n /** mobile态时更新放大镜 */\n private updateMagnifier = (point: Point) => {\n if (this.magnifier.containerDom !== this.container) {\n this.magnifier.appendTo(this.container)\n }\n if (!this.magnifier.state.enabled) {\n this.magnifier.enable()\n }\n requestAnimationFrame(() => this.magnifier.renderWithPoint(point.position))\n this.five.needsRender = true\n }\n\n private onGetStartPoint = (point) => {\n this.mobileStartPoint = point\n this.polyline = new Polyline({ model: this.model })\n this.polyline.hook.on('lineAdded', () => this.hook.emit('editedPolylineChange', this.polyline))\n this.polyline.hook.on('lineRemoved', () => this.hook.emit('editedPolylineChange', this.polyline))\n }\n\n private onGetEndPoint = () => {\n const endPoint = this.mobileNowPoint\n\n this.removeLine(this.dashed)\n this.hasAppendDashed = false\n\n if (this.mobileStartPoint && endPoint) {\n const line = new Line(this.mobileStartPoint, endPoint, this.model)\n this.polyline.addLine(line)\n line.distanceItem.appendTo(this.container)\n line.distanceItem.update(this.five)\n line.hook.on('selected', this.chooseLine)\n this.disposers.push(() => line.hook.off('selected', this.chooseLine))\n this.group.add(line.mesh)\n this.model.addPolyline(this.polyline)\n }\n\n this.mobileStartPoint = null\n this.mobileNowPoint = null\n\n this.five.needsRender = true\n }\n\n private onNowPointChange = (point) => {\n if (this.state === 'watching') {\n this.mobileNowPoint = point\n this.updateMagnifier(point)\n return\n }\n\n if (!this.hasAppendDashed) {\n this.dashed.distanceItem.appendTo(this.container)\n this.group.add(this.dashed.mesh)\n this.hasAppendDashed = true\n }\n\n this.five.needsRender = true\n this.mobileNowPoint = point\n this.updateMobileDashed()\n this.updateMagnifier(point)\n this.five.needsRender = true\n }\n\n private onWillChangeState = (state, newState) => {\n this.state = newState\n if (this.state === 'watching') {\n this.five.helperVisible = true\n } else {\n // 隐藏点位和鼠标聚焦环\n this.five.helperVisible = false\n }\n }\n\n private chooseLine = (line: Line) => {\n const highlightLines = line.getPolyline().lines\n this.highlightLines(highlightLines)\n this.five.needsRender = true\n this.hook.emit(\n 'selectedChange',\n highlightLines.map((line) => line),\n )\n }\n\n private highlightLines(lines: Line[]) {\n this.clearHighlightLines()\n this.highlightedLines = lines\n this.deleteDom.setLines(lines).updatePosition().show()\n lines.forEach((line) => this.highlightLine(line))\n }\n\n private deleteDomClickCallback = () => {\n this.highlightedLines.forEach((line) => {\n this.removeLine(line)\n const polyline = this.model.getPolylineByLine(line)\n this.model.removePolyline(polyline)\n })\n this.highlightedLines = []\n this.deleteDom.setLines([]).hide()\n }\n\n private cancelDeleteClickCallback = () => {\n this.clearHighlightLines()\n }\n}\n","export const startIconImage = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzIiIGhlaWdodD0iNzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxmaWx0ZXIgeD0iLTUuMyUiIHk9Ii01LjMlIiB3aWR0aD0iMTEwLjUlIiBoZWlnaHQ9IjExMC41JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0icHJlZml4X19hIj48ZmVPZmZzZXQgaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9InNoYWRvd09mZnNldE91dGVyMSIvPjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSIvPjxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93Qmx1ck91dGVyMSIgaW4yPSJTb3VyY2VBbHBoYSIgb3BlcmF0b3I9Im91dCIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDEgMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwLjUgMCIgaW49InNoYWRvd0JsdXJPdXRlcjEiLz48L2ZpbHRlcj48ZmlsdGVyIHg9Ii0xMS40JSIgeT0iLTExLjQlIiB3aWR0aD0iMTIyLjklIiBoZWlnaHQ9IjEyMi45JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0icHJlZml4X19jIj48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI0LjUiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dCbHVySW5uZXIxIi8+PGZlT2Zmc2V0IGluPSJzaGFkb3dCbHVySW5uZXIxIiByZXN1bHQ9InNoYWRvd09mZnNldElubmVyMSIvPjxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93T2Zmc2V0SW5uZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0iYXJpdGhtZXRpYyIgazI9Ii0xIiBrMz0iMSIgcmVzdWx0PSJzaGFkb3dJbm5lcklubmVyMSIvPjxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwIDEgMCAwIDAgMC4zIDAiIGluPSJzaGFkb3dJbm5lcklubmVyMSIvPjwvZmlsdGVyPjxmaWx0ZXIgeD0iLTEyNi42JSIgeT0iLTMzNy41JSIgd2lkdGg9IjM1My4xJSIgaGVpZ2h0PSI3NzUlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJwcmVmaXhfX2UiPjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjE2IiBpbj0iU291cmNlR3JhcGhpYyIvPjwvZmlsdGVyPjxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMTAwJSIgeDI9IjUwJSIgeTI9IjAlIiBpZD0icHJlZml4X19kIj48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9Ii43IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjI2LjQzMiUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iODIuMzA1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iLjQiIG9mZnNldD0iMTAwJSIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IHgxPSI1MCUiIHkxPSIwJSIgeDI9IjUwJSIgeTI9IjEwMCUiIGlkPSJwcmVmaXhfX2YiPjxzdG9wIHN0b3AtY29sb3I9IiNGRkYiIHN0b3Atb3BhY2l0eT0iLjA1IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIuMiIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48Y2lyY2xlIGlkPSJwcmVmaXhfX2IiIGN4PSIzNiIgY3k9IjM2IiByPSIyOC40NDQiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNwcmVmaXhfX2EpIiB4bGluazpocmVmPSIjcHJlZml4X19iIi8+PHVzZSBmaWxsPSIjMDAwIiBmaWx0ZXI9InVybCgjcHJlZml4X19jKSIgeGxpbms6aHJlZj0iI3ByZWZpeF9fYiIvPjxjaXJjbGUgc3Ryb2tlPSJ1cmwoI3ByZWZpeF9fZCkiIHN0cm9rZS13aWR0aD0iLjQiIGZpbGwtb3BhY2l0eT0iLjI0MSIgZmlsbD0iI0ZGRiIgc3Ryb2tlLWxpbmVqb2luPSJzcXVhcmUiIGN4PSIzNiIgY3k9IjM2IiByPSIyOC4yNDQiLz48ZWxsaXBzZSBmaWxsPSIjRkZGIiBvcGFjaXR5PSIuNTk2IiBmaWx0ZXI9InVybCgjcHJlZml4X19lKSIgY3g9IjM2IiBjeT0iMzYiIHJ4PSIxOC45NjMiIHJ5PSI3LjExMSIvPjxwYXRoIGQ9Ik0zNiAwQzE2LjExOCAwIDAgMTYuMTE4IDAgMzZzMTYuMTE4IDM2IDM2IDM2IDM2LTE2LjExOCAzNi0zNlM1NS44ODIgMCAzNiAwem0wIDQuNDQ0YzE3LjQyOCAwIDMxLjU1NiAxNC4xMjggMzEuNTU2IDMxLjU1NlM1My40MjggNjcuNTU2IDM2IDY3LjU1NiA0LjQ0NCA1My40MjggNC40NDQgMzYgMTguNTcyIDQuNDQ0IDM2IDQuNDQ0eiIgZmlsbD0idXJsKCNwcmVmaXhfX2YpIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48L2c+PC9zdmc+`\nexport const endIconImage = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzIiIGhlaWdodD0iNzIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IHgxPSIxNS41MSUiIHkxPSIxMi40OTclIiB4Mj0iODUuMjY1JSIgeTI9Ijg2LjE0MyUiIGlkPSJwcmVmaXhfX2IiPjxzdG9wIHN0b3AtY29sb3I9IiM5NUFFRkYiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjNjM4NkZGIiBvZmZzZXQ9IjEwMCUiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMTAwJSIgeDI9IjUwJSIgeTI9IjAlIiBpZD0icHJlZml4X19hIj48c3RvcCBzdG9wLWNvbG9yPSIjOTlBRUZGIiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0ZGRiIgc3RvcC1vcGFjaXR5PSIwIiBvZmZzZXQ9IjI2LjQzMiUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkZGIiBzdG9wLW9wYWNpdHk9IjAiIG9mZnNldD0iODIuMzA1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiM5OUFFRkYiIHN0b3Atb3BhY2l0eT0iLjQiIG9mZnNldD0iMTAwJSIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IHgxPSI1MCUiIHkxPSIwJSIgeDI9IjUwJSIgeTI9IjEwMCUiIGlkPSJwcmVmaXhfX2QiPjxzdG9wIHN0b3AtY29sb3I9IiM4Nzk3RDIiIHN0b3Atb3BhY2l0eT0iLjA1IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iIzYyNzdDNyIgc3RvcC1vcGFjaXR5PSIuMiIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48ZmlsdGVyIHg9Ii02My4zJSIgeT0iLTE2OC44JSIgd2lkdGg9IjIyNi42JSIgaGVpZ2h0PSI0MzcuNSUiIGZpbHRlclVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgaWQ9InByZWZpeF9fYyI+PGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iOCIgaW49IlNvdXJjZUdyYXBoaWMiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48Y2lyY2xlIHN0cm9rZT0idXJsKCNwcmVmaXhfX2EpIiBzdHJva2Utd2lkdGg9Ii40IiBmaWxsPSJ1cmwoI3ByZWZpeF9fYikiIG9wYWNpdHk9Ii43IiBjeD0iMzYiIGN5PSIzNiIgcj0iMjguMjQ0Ii8+PGVsbGlwc2UgZmlsbD0iIzdDOTBEQSIgb3BhY2l0eT0iLjU5NiIgZmlsdGVyPSJ1cmwoI3ByZWZpeF9fYykiIGN4PSIzNiIgY3k9IjM2IiByeD0iMTguOTYzIiByeT0iNy4xMTEiLz48cGF0aCBkPSJNMzYgMEMxNi4xMTggMCAwIDE2LjExOCAwIDM2czE2LjExOCAzNiAzNiAzNiAzNi0xNi4xMTggMzYtMzZTNTUuODgyIDAgMzYgMHptMCA0LjQ0NGMxNy40MjggMCAzMS41NTYgMTQuMTI4IDMxLjU1NiAzMS41NTZTNTMuNDI4IDY3LjU1NiAzNiA2Ny41NTYgNC40NDQgNTMuNDI4IDQuNDQ0IDM2IDE4LjU3MiA0LjQ0NCAzNiA0LjQ0NHoiIGZpbGw9InVybCgjcHJlZml4X19kKSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9nPjwvc3ZnPg==`\n\nconst exitIconSvg = `\n <svg class=\"fpm__exit-icon width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <radialGradient cx=\"50%\" cy=\"50%\" fx=\"50%\" fy=\"50%\" r=\"86.3016741%\" id=\"radialGradient-1\">\n <stop stop-color=\"#FFFFFF\" offset=\"0%\"></stop>\n <stop stop-color=\"#FFFFFF\" stop-opacity=\"0.3\" offset=\"100%\"></stop>\n </radialGradient>\n <radialGradient cx=\"50%\" cy=\"50%\" fx=\"50%\" fy=\"50%\" r=\"70.7106781%\" id=\"radialGradient-2\">\n <stop stop-color=\"#FFFFFF\" offset=\"0%\"></stop>\n <stop stop-color=\"#FFFFFF\" stop-opacity=\"0\" offset=\"100%\"></stop>\n </radialGradient>\n </defs>\n <g fill=\"url(#radialGradient-1)\" fill-rule=\"nonzero\" stroke=\"url(#radialGradient-2)\" stroke-width=\"0.2\">\n <path d=\"M19.1859205,4.10000004 C19.3691554,4.09993923 19.5526088,4.16602323 19.6925352,4.29904206 C19.8171021,4.41745965 19.8858582,4.56899486 19.8980316,4.7239943 C19.9103475,4.88080848 19.8647874,5.04088037 19.7661957,5.16777131 L19.7661957,5.16777131 L14.3769795,11.1697063 C14.1649599,11.4058657 14.0589501,11.7029328 14.0589501,12 C14.0589501,12.2970672 14.1649599,12.5941343 14.3769795,12.8302937 L14.3769795,12.8302937 L19.6928862,18.7509889 C19.8173649,18.8694879 19.8860087,19.0210672 19.8980683,19.1760728 C19.9102693,19.3328965 19.8645908,19.4929392 19.7701664,19.6153111 C19.6099275,19.772809 19.4324896,19.8610254 19.2586274,19.8856752 C19.0810547,19.910851 18.9081905,19.8692156 18.765363,19.7704965 L18.765363,19.7704965 L11.9999322,13.2904645 L5.32508998,19.6962598 C5.16077108,19.8156635 4.99335965,19.8785989 4.83451361,19.8898888 C4.67442082,19.9012674 4.52389835,19.8596921 4.3968979,19.7731206 C4.23619359,19.588506 4.14871527,19.4164558 4.12392544,19.2589757 C4.09801173,19.094356 4.14341261,18.9485987 4.23380428,18.8322287 L4.23380428,18.8322287 L9.62302046,12.8302937 C9.81773049,12.6134147 9.92302682,12.3451662 9.93892926,12.0727274 C9.95499717,11.7974536 9.87975312,11.5179151 9.70614397,11.2737767 L9.70614397,11.2737767 L4.31595492,5.25860214 C4.17860663,5.08857057 4.11166276,4.9104714 4.11172409,4.7432513 C4.11178577,4.57506821 4.18051603,4.41972395 4.30746483,4.29904206 C4.43371817,4.17902131 4.59543385,4.11349344 4.76041858,4.10187732 L4.76041858,4.10187732 L12.0000677,10.7085251 L18.6794563,4.29937602 C18.8192839,4.16626546 19.0026873,4.10006086 19.1859205,4.10000004 Z\" id=\"形状结合\"></path>\n </g>\n </svg>\n`\n\nexport default `\n <style>\n .mobile .fpm__exit {\n position: absolute;\n top: 53px;\n left: 16px;\n width: 24px;\n height: 24px;\n z-index: 10;\n pointer-events: all;\n }\n .mobile .fpm__exit-icon {\n width: 100%;\n height: 100%;\n cursor: pointer;\n }\n .fpm_operating--mobile {\n padding-bottom: 23px;\n }\n .fpm__main-btn {\n display: flex;\n justify-content: center;\n align-items: center;\n margin: 0 !important;\n }\n .fpm__main-btn-text {\n position: absolute;\n font-weight: 500;\n font-size: 14px;\n color: #FFFFFF;\n text-align: center;\n text-shadow: 0 2px 8px rgba(0,0,0,0.50);\n transition: all 200ms ease-in-out;\n }\n .fpm__main-text__hide {\n transform: scale(0.8) translateY(4px);\n opacity: 0;\n }\n .fpm__main-text__show {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n .fpm__main__start {\n background-image: url(${startIconImage});\n }\n .fpm__main__end {\n background-image: url(${endIconImage});\n }\n\n </style>\n <div class=\"fpm__exit\">\n ${exitIconSvg}\n </div>\n <div class=\"fpm_ui-bg\"></div>\n <div class=\"fpm_operating-space fpm_operating--mobile\">\n <div class=\"fpm__main fpm__main-btn\">\n <div class=\"fpm__main-icon fpm__main__start\"></div>\n <div class=\"fpm__text fpm__main-text fpm__main-btn-text\"></div>\n </div>\n </div>\n`\n","import { endIconImage, startIconImage } from './mobileHTML'\n\nconst revokeSvg = `\n <svg class=\"fpm__revoke-icon\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient x1=\"47.631%\" y1=\"55.183%\" x2=\"2.967%\" y2=\"86.323%\" id=\"fpm__revoke-a\">\n <stop stop-color=\"#FFF\" offset=\"0%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\".5\" offset=\"100%\" />\n </linearGradient>\n <linearGradient x1=\"5.297%\" y1=\"43.016%\" x2=\"38.238%\" y2=\"79.932%\" id=\"fpm__revoke-b\">\n <stop stop-color=\"#FFF\" offset=\"0%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\"0\" offset=\"100%\" />\n </linearGradient>\n </defs>\n <path\n d=\"M13.388 7.108c.552 0 1.005.42 1.06.957l.006.11v1.224c0 .921.745 1.667 1.666 1.667h7.184c5.804 0 10.509 4.616 10.509 10.309 0 5.595-4.544 10.15-10.21 10.305l-.3.004H8.924c-.917 0-1.66-.729-1.66-1.628 0-.846.658-1.541 1.5-1.62l.16-.008h14.38c3.972 0 7.191-3.158 7.191-7.053 0-3.81-3.08-6.916-6.933-7.049l-.257-.004H10.029l-.109-.005H8.212c-.245 0-.482-.085-.67-.237l-.09-.082a1.066 1.066 0 0 1-.065-1.422l.079-.086 5.175-5.077c.2-.195.468-.305.747-.305z\"\n fill=\"url(#fpm__revoke-a)\"\n fill-rule=\"nonzero\"\n stroke=\"url(#fpm__revoke-b)\"\n stroke-width=\".5\"\n />\n </svg>\n`\nconst exitSvg = `\n <svg class=\"fpm__exit-icon width=\"40\" height=\"40\" viewBox=\"0 0 40 40\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient x1=\"36.288%\" y1=\"73.736%\" x2=\"54.242%\" y2=\"97.166%\" id=\"fpm__exit-a\">\n <stop stop-color=\"#FFF\" offset=\"0%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\".5\" offset=\"100%\" />\n </linearGradient>\n <linearGradient x1=\"100%\" y1=\"47.234%\" x2=\"24.047%\" y2=\"47.234%\" id=\"fpm__exit-b\">\n <stop stop-color=\"#FFF\" offset=\"0%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\".005\" offset=\"99.535%\" />\n <stop stop-color=\"#FFF\" stop-opacity=\"0\" offset=\"100%\" />\n </linearGradient>\n </defs>\n <path\n d=\"M22 7a1.5 1.5 0 0 1 .144 2.993L22 10h-9a1.5 1.5 0 0 0-1.493 1.356l-.007.144v17a1.5 1.5 0 0 0 1.356 1.493L13 30h9a1.5 1.5 0 0 1 .144 2.993L22 33h-9a4.5 4.5 0 0 1-4.495-4.288L8.5 28.5v-17a4.5 4.5 0 0 1 4.288-4.495L13 7h9zm6.317 7.755a1 1 0 0 1 .7.286l4.856 4.764a1 1 0 0 1-.7 1.713h-5.856V21.5h-8.032a1.5 1.5 0 1 1 0-3h6.365c.92 0 1.666-.746 1.667-1.667v-1.078a1 1 0 0 1 1-1z\"\n fill=\"url(#fpm__exit-a)\"\n fill-rule=\"nonzero\"\n stroke=\"url(#fpm__exit-b)\"\n stroke-width=\".5\"\n />\n </svg>\n`\n\nexport default `\n <style>\n .fpm__other-btn {\n height: 40px;\n width: 88px;\n background: rgba(0, 0, 0, 0.15);\n border-radius: 20px;\n overflow: hidden; \n }\n\n .fpm__other-content {\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .fpm__revoke {\n opacity: 0.3;\n } \n .fpm__revoke.enabled {\n opacity: 0.85;\n } \n .fpm__revoke.enabled:hover {\n opacity: 1;\n }\n \n .fpm__revoke-icon {\n width: 24px;\n height: 24px;\n margin-right: 4px;\n cursor: pointer;\n }\n \n .fpm__main-btn {\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .fpm__main-btn-text {\n position: absolute;\n font-weight: 500;\n font-size: 14px;\n color: #FFFFFF;\n text-align: center;\n text-shadow: 0 2px 8px rgba(0,0,0,0.50);\n transition: all 200ms ease-in-out;\n }\n .fpm__main-text__hide {\n transform: scale(0.8) translateY(4px);\n opacity: 0;\n }\n .fpm__main-text__show {\n transform: scale(1) translateY(0);\n opacity: 1;\n }\n .fpm__main__start {\n background-image: url(${startIconImage});\n }\n .fpm__main__end {\n background-image: url(${endIconImage});\n }\n \n </style>\n <div class=\"fpm_ui-bg\"></div>\n <div class=\"fpm_operating-space\">\n <div class=\"fpm__other-btn\">\n <div class=\"fpm__other-content fpm__revoke\">\n ${revokeSvg}\n <span class=\"fpm__text fpm__revoke-text\"></span>\n </div>\n </div>\n <div class=\"fpm__main fpm__main-btn\">\n <div class=\"fpm__main-icon fpm__main__start\"></div>\n <div class=\"fpm__text fpm__main-text fpm__main-btn-text\"></div>\n </div>\n <div class=\"fpm__other-btn\">\n <div class=\"fpm__other-content fpm__exit\">\n ${exitSvg}\n <span class=\"fpm__text fpm__exit-text\"></span>\n </div>\n </div>\n </div>\n`\n","export const uiWrapperStyle: Partial<CSSStyleDeclaration> = {\n display: 'none',\n position: 'absolute',\n top: '0',\n left: '0',\n width: '100%',\n height: '100%',\n opacity: '0',\n transform: 'translate(0, 10px)',\n transition: 'opacity 500ms ease-in-out, transform 500ms ease-in-out',\n}\n\nexport const operatingSpaceStyle: Partial<CSSStyleDeclaration> = {\n position: 'absolute',\n left: '50%',\n bottom: '32px',\n transform: 'translateX(-50%)',\n height: '89px',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n fontSize: '14px',\n pointerEvents: 'all',\n color: '#fff',\n zIndex: '10',\n}\n\n// 操作区下方的背景\nexport const controllerBackgroundStyle: Partial<CSSStyleDeclaration> = {\n position: 'absolute',\n bottom: '0',\n left: '0',\n opacity: '0.5',\n width: '100%',\n height: '184px',\n background: `linear-gradient(180deg, rgba(0,0,0,0.00) 0%, #000000 100%)`,\n zIndex: '0',\n}\n\n// item\nexport const mainItemStyle: Partial<CSSStyleDeclaration> = {\n margin: '0 64px',\n}\n\nexport const exitItemStyle: Partial<CSSStyleDeclaration> = {\n opacity: '0.85',\n}\n\n// icon\nexport const mainIconStyle: Partial<CSSStyleDeclaration> = {\n width: '72px',\n height: '72px',\n backgroundSize: '100%',\n cursor: 'pointer',\n transition: 'all 200ms ease-in-out',\n}\nexport const exitIconStyle: Partial<CSSStyleDeclaration> = {\n width: '24px',\n height: '24px',\n marginRight: '4px',\n backgroundSize: '100%',\n cursor: 'pointer',\n}\n\n// text\nexport const textStyle: Partial<CSSStyleDeclaration> = {\n userSelect: 'none',\n pointerEvents: 'none',\n}\n","import type { UIControllerParams } from '.'\nimport type MeasureController from '../../Controller'\nimport type { PanoMeasurePluginEvent } from '../../typings/event.type'\nimport { mainIconStyle, mainItemStyle } from './style'\nexport class MainBtnController {\n private container: Element\n private measureController: MeasureController\n private mainElement: ReturnType<MainBtnController['getMainElement']>\n private _params: UIControllerParams\n\n private _btnTexts = {\n start: '开始',\n end: '结束',\n revoke: '撤销',\n exit: '退出',\n }\n\n public constructor(measureController: MeasureController, container: Element, params: UIControllerParams) {\n this._params = params\n\n this._btnTexts = {\n start: this._params.startButtonText ?? this._btnTexts.start,\n end: this._params.endButtonText ?? this._btnTexts.end,\n revoke: this._params.revokeButtonText ?? this._btnTexts.revoke,\n exit: this._params.exitButtonText ?? this._btnTexts.exit,\n }\n\n this.measureController = measureController\n this.container = container\n this.mainElement = this.getMainElement()\n\n Object.assign(this.mainElement.mainIcon.style, mainIconStyle)\n Object.assign(this.mainElement.mainItem.style, mainItemStyle)\n\n const { revokeTextDom, exitTextDom } = this._getTextElement()\n if (revokeTextDom) {\n revokeTextDom.innerText = this._btnTexts.revoke\n }\n if (exitTextDom) {\n exitTextDom.innerText = this._btnTexts.exit\n }\n\n this.change2Add()\n\n this.measureController.hooks.on('modeChange', this.modeChangeHandler)\n this.mainElement.mainItem.addEventListener('click', this.onClick)\n this.mainElement.mainItem.addEventListener('mouseenter', this.onMouseEnter)\n this.mainElement.mainItem.addEventListener('mouseleave', this.onMouseLeave)\n }\n\n public dispose() {\n this.measureController.hooks.off('modeChange', this.modeChangeHandler)\n this.mainElement.mainItem.removeEventListener('click', this.onClick)\n this.mainElement.mainItem.removeEventListener('mouseenter', this.onMouseEnter)\n this.mainElement.mainItem.removeEventListener('mouseleave', this.onMouseLeave)\n }\n\n private getMainElement() {\n const mainTextDom = this.container.querySelector<HTMLSpanElement>('.fpm__main-text')\n const mainItem = this.container.querySelector<HTMLButtonElement>('.fpm__main')\n const mainIcon = this.container.querySelector<HTMLElement>('.fpm__main-icon')\n if (!mainItem || !mainTextDom || !mainIcon) throw new Error('cannot find dom')\n\n return { mainTextDom, mainItem, mainIcon }\n }\n\n private _getTextElement() {\n const revokeTextDom = this.container.querySelector<HTMLSpanElement>('.fpm__revoke-text')\n const exitTextDom = this.container.querySelector<HTMLSpanElement>('.fpm__exit-text')\n return { revokeTextDom, exitTextDom }\n }\n\n private change2Add() {\n const { mainIcon, mainTextDom } = this.mainElement\n if (mainIcon.className.includes('fpm__main__start')) {\n mainTextDom.innerText = this._btnTexts.start\n return\n }\n if (mainIcon.className.includes('fpm__main__end')) {\n mainIcon.style.transform = `scale(0.8)`\n if (mainTextDom.className.includes('fpm__main-text__show')) {\n mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide')\n } else {\n mainTextDom.classList.add('fpm__main-text__hide')\n }\n setTimeout(() => {\n mainIcon.classList.replace('fpm__main__end', 'fpm__main__start')\n mainIcon.style.transform = 'scale(1)'\n mainTextDom.innerText = this._btnTexts.start\n mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show')\n }, 200)\n }\n }\n\n private change2Done() {\n const { mainTextDom, mainIcon } = this.getMainElement()\n if (mainTextDom.innerText === this._btnTexts.end) return\n if (mainIcon.className.includes('fpm__main__end')) return\n if (mainIcon.className.includes('fpm__main__start')) {\n mainIcon.style.transform = `scale(0.8)`\n if (mainTextDom.className.includes('fpm__main-text__show')) {\n mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide')\n } else {\n mainTextDom.classList.add('fpm__main-text__hide')\n }\n setTimeout(() => {\n mainIcon.classList.replace('fpm__main__start', 'fpm__main__end')\n mainIcon.style.transform = 'scale(1)'\n mainTextDom.innerText = this._btnTexts.end\n mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show')\n }, 200)\n }\n }\n\n /* 鼠标移入时 */\n private onMouseEnter = () => {\n const { mainItem } = this.mainElement\n mainItem.style.opacity = '1'\n }\n\n /* 鼠标移出时 */\n private onMouseLeave = () => {\n const { mainItem } = this.mainElement\n mainItem.style.opacity = '0.85'\n }\n\n private onClick = () => {\n const mode = this.measureController.getCurrentMode()\n if (mode !== 'Edit') {\n this.measureController.changeMode('Edit')\n } else {\n this.measureController.save().changeMode('Watch')\n }\n }\n\n private modeChangeHandler: PanoMeasurePluginEvent['modeChange'] = (mode) => {\n mode === 'Edit' ? this.change2Done() : this.change2Add()\n }\n}\n","import type { UIControllerParams } from '.'\nimport type MeasureController from '../../Controller'\nimport { mainIconStyle, mainItemStyle } from './style'\n\nexport class MobileMainBtnController {\n private container: Element\n private measureController: MeasureController\n private mainElement: ReturnType<MobileMainBtnController['getMainElement']>\n private _params: UIControllerParams\n\n private _btnTexts = {\n start: '开始',\n end: '结束',\n }\n\n public constructor(measureController: MeasureController, container: Element, params: UIControllerParams) {\n this._params = params\n\n this._btnTexts = {\n start: this._params.startButtonText ?? this._btnTexts.start,\n end: this._params.endButtonText ?? this._btnTexts.end,\n }\n\n this.measureController = measureController\n this.container = container\n this.mainElement = this.getMainElement()\n\n this.mainElement.mainIcon.setAttribute('style', `-webkit-tap-highlight-color: rgba(0,0,0,0);`)\n Object.assign(this.mainElement.mainIcon.style, mainIconStyle)\n Object.assign(this.mainElement.mainItem.style, mainItemStyle)\n this.change2Add()\n\n this.mainElement.mainItem.addEventListener('click', this.onClick)\n }\n\n public dispose() {\n this.mainElement.mainItem.removeEventListener('click', this.onClick)\n }\n\n private getMainElement() {\n const mainTextDom = this.container.querySelector<HTMLSpanElement>('.fpm__main-text')\n const mainItem = this.container.querySelector<HTMLButtonElement>('.fpm__main')\n const mainIcon = this.container.querySelector<HTMLElement>('.fpm__main-icon')\n if (!mainItem || !mainTextDom || !mainIcon) throw new Error('cannot find dom')\n\n return { mainTextDom, mainItem, mainIcon }\n }\n\n private change2Add() {\n const { mainIcon, mainTextDom } = this.mainElement\n if (mainIcon.className.includes('fpm__main__start')) {\n mainTextDom.innerText = this._btnTexts.start\n return\n }\n if (mainIcon.className.includes('fpm__main__end')) {\n mainIcon.style.transform = `scale(0.8)`\n if (mainTextDom.className.includes('fpm__main-text__show')) {\n mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide')\n } else {\n mainTextDom.classList.add('fpm__main-text__hide')\n }\n setTimeout(() => {\n mainIcon.classList.replace('fpm__main__end', 'fpm__main__start')\n mainIcon.style.transform = 'scale(1)'\n mainTextDom.innerText = this._btnTexts.start\n mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show')\n }, 200)\n }\n }\n\n private change2Done() {\n const { mainTextDom, mainIcon } = this.mainElement\n if (mainTextDom.innerText === this._btnTexts.end) return\n if (mainIcon.className.includes('fpm__main__end')) return\n if (mainIcon.className.includes('fpm__main__start')) {\n mainIcon.style.transform = `scale(0.8)`\n if (mainTextDom.className.includes('fpm__main-text__show')) {\n mainTextDom.classList.replace('fpm__main-text__show', 'fpm__main-text__hide')\n } else {\n mainTextDom.classList.add('fpm__main-text__hide')\n }\n setTimeout(() => {\n mainIcon.classList.replace('fpm__main__start', 'fpm__main__end')\n mainIcon.style.transform = 'scale(1)'\n mainTextDom.innerText = this._btnTexts.end\n mainTextDom.classList.replace('fpm__main-text__hide', 'fpm__main-text__show')\n }, 200)\n }\n }\n\n private onClick = () => {\n if (this.mainElement.mainTextDom.innerText === (this._params.startButtonText ?? '开始')) {\n this.measureController.hooks.emit('willChangeState', 'watching', 'editing')\n this.change2Done()\n } else {\n this.measureController.hooks.emit('willChangeState', 'editing', 'watching')\n this.change2Add()\n }\n }\n}\n","import type { Vector3 } from 'three/webgpu'\nimport type { Mode } from '../../../Controller'\nimport type MeasureController from '../../../Controller'\n\nexport default class Revoke {\n private container: Element\n private revokeIcon: HTMLElement\n private revokeItem: HTMLDivElement\n private measureController: MeasureController\n\n public constructor(measureController: MeasureController, container: Element) {\n this.measureController = measureController\n this.container = container\n\n const revokeIcon = this.container.querySelector<HTMLElement>('.fpm__revoke-icon')\n const revokeItem = this.container.querySelector<HTMLDivElement>('.fpm__revoke')\n if (!revokeIcon || !revokeItem) throw new Error('不正确的选择器')\n this.revokeIcon = revokeIcon\n this.revokeItem = revokeItem\n this.revokeItem.addEventListener('click', this.onClick)\n measureController.hooks.on('modeChange', this.onModeChange)\n }\n\n public dispose() {\n this.revokeItem.removeEventListener('click', this.onClick)\n this.measureController.hooks.off('modeChange', this.onModeChange)\n }\n\n private onClick = () => {\n this.measureController.revoke()\n }\n\n private onModeChange = (mode: Mode) => {\n if (mode !== 'Edit' && this.revokeItem.className.includes('enabled')) {\n this.revokeItem.classList.remove('enabled')\n this.measureController.hooks.off('anchorChange', this.onAnchorChange)\n return\n }\n this.measureController.hooks.on('anchorChange', this.onAnchorChange)\n }\n\n private onAnchorChange = (anchor: Vector3 | null) => {\n // 开始测量标记一个点后才能撤销\n anchor && this.revokeItem.classList.add('enabled')\n }\n}\n","<!--\n @component\n 一个滑动选择器,样式大概是这样\n\n ( ( 选中的选项1 ) 选项2 选项3 )\n -->\n<script lang=\"ts\" generics=\"T extends string\">\n // 要这么转换一下T应该是 svelte 的 language tools 的 bug,没时间查\n\n type K = T\n export const defaultIndex: number | null = null\n export const setIndex = (index: number | null) => {\n activeIndex = index\n }\n export let options: Array<{ key: K; value: string; icon?: string }>\n export let onChange: (key: K) => void\n\n const elementList: HTMLElement[] = []\n let container: HTMLElement\n let activeIndex: number | null = defaultIndex\n $: activeButton = elementList[activeIndex]\n\n // 用来控制滑块移动的\n let activeButtonWidth: number | undefined\n let activeButtonLeft: number | undefined\n $: {\n if (activeButton && container) {\n setTimeout(() => {\n activeButtonWidth = activeButton.clientWidth\n activeButtonLeft = activeButton.getBoundingClientRect().left - container.getBoundingClientRect().left\n }, 0)\n }\n }\n</script>\n\n<div class=\"Switcher\" bind:this={container}>\n <div class=\"Switcher-bg\" />\n {#if activeButton}\n <div class=\"active-slider\" style:width={activeButtonWidth + 'px'} style:transform={`translate(${activeButtonLeft}px, -50%)`} />\n {/if}\n <div class=\"Switcher-buttons\" class:has-divider={!activeButton}>\n {#each options as option, index}\n <!-- svelte-ignore a11y-click-events-have-key-events -->\n <div\n class=\"button\"\n class:active={activeIndex === index}\n bind:this={elementList[index]}\n on:click={() => {\n onChange(option.key)\n activeIndex = index\n }}\n >\n <div class=\"content\">\n {#if option.icon}\n <span class=\"icon\" style:background-image={`url(${option.icon})`} />\n {/if}\n {option.value}\n </div>\n </div>\n {/each}\n </div>\n</div>\n\n<style lang=\"scss\">\n .Switcher {\n position: relative;\n box-sizing: border-box;\n width: max-content;\n\n .content,\n .active-slider {\n transition-property: transform, width, opacity;\n transition-duration: 300ms;\n transition-timing-function: ease-out;\n }\n }\n\n .Switcher-bg {\n content: '';\n position: absolute;\n box-sizing: border-box;\n top: 50%;\n left: 0;\n width: 100%;\n height: 60px;\n transform: translateY(-50%);\n border-style: solid;\n border-width: 0px 30px;\n border-image: url('data:image/png;base64,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');\n border-image-slice: 0 90 fill;\n }\n\n .Switcher-buttons {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n padding: 0 3px;\n height: 100%;\n &.has-divider .button:not(:last-child)::after {\n content: '';\n position: absolute;\n right: 0;\n top: 10%;\n height: 80%;\n width: 1px;\n background-image: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.3), transparent);\n background-size: 100%;\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n\n .active-slider {\n box-sizing: border-box;\n position: absolute;\n height: 52px;\n top: 50%;\n transform: translate(0, -50%);\n border-style: solid;\n border-width: 0px 30px;\n border-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXQAAACcCAMAAABY3aA6AAAAhFBMVEX///////8AAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////88i7DIAAAALHRSTlNmawBvc3d6BAcZDid8NwyFja/XEhYkHTErIS41gpajnUyRVEE7XKpiRczDuH1q6FcAAA1mSURBVHja7Ndtk5owFAXg2KKtiiUdlTdBYH1Z//8vbC4SjkmuDlpmOht7AWfdLyaPZw4ovo06PzydcZX+Eh3QP99gXvsCRkbvsX91s/B29A41/rch9mOjq09twUl6TbNRM/d4aH9rmsWVfkDmx0XX4ORN1HGcZdlWzdLbod2pTcYx8St5Dc/7jIiOjGtw4lbSaZ4nSbJTs/J0aG9qi3meKn+i1/AM+/joWlyBk3eaJ7tj/RlEsiyr/fm3t3PeV2Upo+CzPu6SPFXyBM+4j4oO8k6cwI+nUFbdihopI49HyqbLVSXD05HgO3ejZsZDR5OrkHfiCnxWns9VKaNQzczzCa+vaiJZVudzOVPwnbuKO9RHRidyCnkrLqQCb6I73FNvhtsdyTcKXorWneIO9jHRf1zJ5/F2ma9O0X5fEriXzvfHgi/3++i0ypfbeA72EdF78jS5TKtW/J20efvWvZpekvRJdjH49rneEHld7CsZhhx44Pm48OQuq31RE/tmPfhJRgwzBzlC7mhPA2/hsTXYI+5gH/YgI4aWebZM6qhqil4c4P5ac/o0lntRVlGdLLOhHSMGxnyZH6Y9Od8n3z0fvm069qaaHvLlwLCLQTfQbbr7LEuD3NUOPD9c+1v2qCw/d+n2GvbX0RFzahbd5ZZ4z+190G/xLXfd7apjdNhfQof5PEtXk1K65AB3ZmJfX2bshbP47TDsspys0mwO9RfQ1YPiYh1v80PRFA656327dPui40uczsIxVurhDnYFdci38XqBh8cn0anOqVo+JMXcJg8c7W7V7sq/UNCZvOjDtmfYKezygyoGxf4celvnVC1N1Mdci2M099eSfWVu8cGu3fuwRw1VTFvsT6Kjzo+hLBBzM+Tv4+3g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');\n border-image-slice: 0 90 fill; // 90 随便写的,够大就行,懒得量了\n }\n\n .button {\n height: 56px;\n display: flex;\n position: relative;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n pointer-events: all;\n width: 116px;\n .content {\n position: absolute;\n display: flex;\n align-items: center;\n font-size: 16px;\n color: #fff;\n text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);\n font-weight: bold;\n .icon {\n display: inline-block;\n width: 18.5px;\n height: 18.5px;\n background-repeat: no-repeat;\n background-size: 100%;\n margin-right: 2px;\n }\n }\n\n // 动画\n &:not(.active) {\n .content {\n opacity: 0.65;\n transform: scale(0.875);\n &:hover {\n opacity: 0.85;\n }\n }\n }\n &.active {\n .content {\n opacity: 1;\n transform: scale(1);\n }\n }\n }\n</style>\n","<!-- \n @component\n 一个退出按钮\n -->\n<script lang=\"ts\">\n export let onClick: () => void | undefined | null = null\n</script>\n\n<div class=\"exit\" on:click={onClick} />\n\n<style lang=\"scss\">\n .exit {\n position: relative;\n pointer-events: all;\n cursor: pointer;\n left: 24px;\n top: 24px;\n width: 24px;\n height: 24px;\n background-image: url(data:image/png;base64,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);\n background-repeat: no-repeat;\n background-size: 100% 100%;\n }\n</style>\n","export const IconUndo =\n 'data:image/png;base64,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'\n\nexport const IconOk =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAASKADAAQAAAABAAAASAAAAACQMUbvAAAFO0lEQVR4Ae2YWYgdRRSG78SFOG6Ju4MxIRnRgCCKBlSC24P64IO4h7wI6oMPCioqAX1TfFIQRFFBETQmIioqGhDBh3GJiMSAZnABNSIuUQTFbcz4fZcup297b9+t7525wznwU11d1aervj6nurprtbAgEASCQBAIAkEgCASBIBAEgkAQCAJBIAgEgSAQBIJAEMgIzM7OLkHL0STaJ8DMgRkDyDK0CX2MptEUOrMbSGPddB6VvkAwUo5Hd6OzCuP+hfr5Y2NjvxbON60uaXp2hE8CZ3+GfzJ6ABXhOLND0VoPOrF9O+k0Kn2AM85Y16M70UTJuL8taWtoWjSAgHMYM7sQ3YyWN8yysbKZ9NrdeKp1bVGsQcBxvbkUXYsOaD3d2jbabgXQ3yV9GppGPoKA43pyDboclb3G36T9rm7g0L82soAAY/S7CG9E56GybHiLduH4BuvKRhIQcIyUi5BwTmsz47dpvwftadOvafPIAQLOUmZiSl2JVjed1dzJ7Rzei74iembnTnd+NFKAgHMIU7seXYKObTPN92kXzue9wtH/yAACjkBuQecgN3tltoNGN4rTwNlb1rFd20gAAs4JTOR2dAYqe407351IOB/2C0dnlQBiAm7vZ6oYkIPKG77XUd+E1iDvU2bTND6I3qtqLH0BYvDuWP3uORHNUHeAOxlcRx+C9C01/F1MhzvQUahsj6OfT9HDaKoqODot2zvY3tIYvOuAi+W5SD++Xf5BU+h1BvklZc+G/+u4+AbkwtxunF/QRzivcl/HUJn1E0GTjMKNmtGin7+QKeD30AQTfI1ye7dPk+uMFFPqMtRuvaFLzQfxOKocjs57ApRNwrfKDPKJ+YSV9Z/RKcj2lfR9BUi/cdzW6GsU3o98U3Uytq/p9wR6serIwWfdevoflA3mh8yHGzBfpYJK5U8cuz5dhW5k4isoS40+ptJDaD3qBM439HsKbR0UHHzXegLkhdhnaBcyrfJwhKSMGtPuAnQbAM6mbGq0HU3DI+h01Akc/+c8owYJB/9tFz/7NDUmZUqtRFegVehP5OSU64jlfpkOp/wRbUNbmNQflHXDzyoO7kMnIX16rWr18L6nbTN6FD+m9EDNAfVsGaRJHAjpOGTEJDgJViqX0WakvYu2ot3oVHQT0odRJxT7C1Y/RUtwHgNOx/90ik66qfcFyBvlIG2gOoGMjgTFMg/sQOoHo++QQFynjC7BJjjpWq/LQ3LNM62GBod79Z5iXpwsg7SWul/YQiqmW4qINPmD6OM5zUU+QbQs9vUhzgsc7tsyz23r2Ah3J/kJegE5mXFkOjVbvNMC7v7JaHMd8ZzST/4a6/MGh3vXU8GybxMS9hGOfOJG0jFIAGnylk7edpXOm1qpzWPb7Ge0mYrPoaGmFff7zxxEZZZB2oFD00RIRyAhJSh5MHkoAhFOeit5vQvyFvTksBZk7vU/qxSQ3jNIH2R3cqPoh+bvKEVMiqJ8tKSo8TLXIdPqWfT0fMLh/tWlmM6SMam9pFsRkgt3ihRhGS3FiHLT6X7JfY475KG8yrlXS6s8gtKdCpCu5ryR5Os8H0H5NDNyhGNaPc/1Kd2ozp8NDJBTKkDawKkjkZFkeuVBOY49yMh5eaHAYSyDSTEdJytAcuF2n2TqmF5pD5Tg+B9pQUQOY6ubgxyKsSYZNf4GEdJqJJylyA/Pl9AbCw0OY6o/RcuhGJB8IMJZh1Ygf4u8g3YBx5QLk4DRhMaRC3NYEAgCQSAIBIEgEASCQBAIAkEgCASBIBAEgkAQCAJBYJEQ+BdpRqKi3IjqNwAAAABJRU5ErkJggg=='\n\nexport const IconLine =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAMKADAAQAAAABAAAAMAAAAADbN2wMAAABi0lEQVRoBe2Yu20DMRBEdW7EuVLX4NQVuAEVoUhFuAFV4FQ1OHWuRkzNABRwMLhDfbhcBhyA0IEjnvYNjjxoN5upmcBMYCYQmcCifjyl9AL/E+Md4xXjjHHCOC7L8ofPcJkAufgvVPhWqPIHc7sRIJiwJSZfKp7f5zz9cCkAPjZKNV+tbeYpAD7zSjVfrW3mKQBuWKWar9Y28xQATxsl7PNkHgJqYUtPARzxQzxtLG1h7KMhZIL5KP3/HkgonMVf9Y2LA45UzneXBChVkxPfw/tY+WEQdwOw6JEgHgIYCeJhgFEgngIYAeJpgGiIJgCREM0AoiCaAkRANAfoDeEC0BPCDaAXhCtADwh3AG+ILgCeEN0AvCC6AnhAdAdoDRECICB+4bEmtmzOGNU2ZhgAirP+2dFaS7YxVVdifROX69wIOODmTN6SbGOGArDiDFF7Esw2ZjhAjr3WpjT9UQC4YZVMfxSAWhvT9EcBUG1MnkL0i6ptnuIij0mjjVl9D3jUMu85E5gJzARuT+ACS7KuMQ7rOEcAAAAASUVORK5CYII='\n\nexport const IconArea =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAMKADAAQAAAABAAAAMAAAAADbN2wMAAAByElEQVRoBe1ZMU4DMRC8Q7yCJjVNKCh4ARVfAPo0PCYNPeQLVLyAggIa6jQ8g2NGsiJjeUfHrdGd0K60Sm7t3R3P+hx503UhwUAwEAzMyUCvkg/DcITxa+gldAXdQ5+hu77vv/DZTKbmMheQAt4D4XkF5Stsm1aL8OQiw5aQ+Rp4zqed461kci5VgUegO22F0BnnA9W+qcVQFeCeX4qYWNQC+MIuRUwsxwIhTxu1hV4w/ib8fzN0hskXwoFYqqIqsIMHT5uafML4XhuYaGMsxqwJMRBLVcyXmLOzs/ku8ybzTDhkthZfiWUNzSuxxbP8zVEV6HjOQx8KdNw2rcEzBWP+2JLMTQwctEQuwHJakj0WMHc1ogJRAScDsYWcBLrdowJuCp0BogJOAt3uUQE3hc4AUQEngW73/10BXimhtwVNvIDLq2gxf+wjYzL2QZg7XWsPtvKLCSQ5Wq1FXsCfoK2ulsRxBT2BliLbmGoLqXYfE/EC3koYqwae8WUbU1UgWoutyoM4KyuW2kJ7y2kGu4nF01rcVnpGk9aWTrq8eVbGad5alO2+MvuIZ9XGlLnMl5hJ01HK02ixfzGNICemBAPBQDDwhwx8A43PdoQvgLfYAAAAAElFTkSuQmCC'\n","<!--\n @component\n pc 端控制器\n -->\n<script lang=\"ts\">\n import Switcher0 from './Common/Switcher0.svelte'\n import type MeasureController from '../Controller'\n import { onDestroy, onMount } from 'svelte'\n import type { Mode } from '../Controller'\n import Exit from './Common/Exit.svelte'\n import EditController from '../Controller/EditController'\n import { IconLine, IconOk, IconUndo, IconArea } from './Common/icons'\n\n export let measureController: MeasureController\n export let showExit = false\n export let i18n: (key: string) => string = (key) => key\n\n let canRevoke = false\n\n /** 设置哪个块高亮的 */\n let setSwitcherActiveIndex: (index: number | null) => void\n\n function handleModeChange(mode: Mode) {\n if (mode === 'Edit') {\n showController = true\n } else {\n setSwitcherActiveIndex(null)\n showController = false\n }\n }\n\n function complete() {\n if (measureController.controller instanceof EditController) {\n measureController.controller.complete()\n }\n measureController.save({ mode: 'Watch' })\n }\n\n function handlePointsChange(points: any[]) {\n canRevoke = points.length > 0\n }\n\n function handleComplete() {\n canRevoke = false\n }\n\n onMount(() => {\n measureController.hooks.on('modeChange', handleModeChange)\n measureController.hooks.on('complete', handleComplete)\n measureController.hooks.on('pointsChange', handlePointsChange)\n })\n\n onDestroy(() => {\n measureController.hooks.off('modeChange', handleModeChange)\n measureController.hooks.off('complete', handleComplete)\n measureController.hooks.off('pointsChange', handlePointsChange)\n })\n\n let showController = false\n</script>\n\n<div class=\"Measure-Controller\">\n {#if showExit}\n <Exit onClick={measureController.disable} />\n {/if}\n <div class=\"bottom\">\n <div class=\"mask\" />\n <div class=\"center\">\n {#if showController}\n <div class=\"buttons\">\n <div class=\"button\" class:forbid={!canRevoke} on:click={() => measureController.revoke()}>\n <div class=\"icon\" style:background-image={`url(${IconUndo})`} />\n {i18n('撤销')}\n </div>\n <div class=\"button\" on:click={complete}>\n <div class=\"icon\" style:background-image={`url(${IconOk})`} />\n {i18n('结束')}\n </div>\n </div>\n {/if}\n <div class=\"mode-switcher\">\n <Switcher0\n options={[\n { key: 'line', value: i18n('测距离'), icon: IconLine },\n { key: 'area', value: i18n('测面积'), icon: IconArea },\n ]}\n onChange={(value) => {\n measureController.save().changeMode('Edit') // 保存并且切换至edit态\n measureController.changeMeasureType(value)\n }}\n bind:setIndex={setSwitcherActiveIndex}\n />\n </div>\n </div>\n </div>\n</div>\n\n<style lang=\"scss\">\n *.forbid {\n pointer-events: none !important;\n opacity: 0.5;\n }\n .Measure-Controller {\n pointer-events: none;\n position: relative;\n width: 100%;\n height: 100%;\n z-index: 2;\n .mode-switcher {\n margin-top: 36px;\n }\n .bottom {\n position: absolute;\n width: 100%;\n bottom: 0;\n .mask {\n position: absolute;\n bottom: 0;\n width: 100%;\n height: 184px;\n background-size: 100%;\n background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.3));\n }\n .center {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 40px;\n }\n }\n .buttons {\n pointer-events: all;\n display: flex;\n align-items: center;\n height: 40px;\n background: rgba(0, 0, 0, 0.2);\n color: rgba(255, 255, 255, 0.85);\n width: max-content;\n border-radius: 9999px;\n overflow: hidden;\n .button {\n cursor: pointer;\n display: flex;\n align-items: center;\n position: relative;\n font-size: 14px;\n padding: 0px 16px;\n .icon {\n width: 24px;\n height: 24px;\n background-repeat: no-repeat;\n background-size: 100%;\n margin-right: 4px;\n }\n // 分割线\n &::after {\n content: '';\n position: absolute;\n display: block;\n right: -0.5px;\n height: 24px;\n width: 1px;\n background-image: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.3), transparent);\n background-size: 100%;\n background-repeat: no-repeat;\n background-position: center;\n }\n &:last-child {\n &::after {\n display: none;\n }\n }\n }\n }\n }\n</style>\n","<!--\n @component\n 一个滑动选择器,样式大概是这样,选中的选项永远在最中间\n\n 选项1 ( 选中的选项 ) 选项2 选项3\n -->\n<script lang=\"ts\" generics=\"T extends string\">\n // 要这么转换一下T应该是 svelte 的 language tools 的 bug,没时间查\n\n type K = T\n export let options: Array<{ key: K; value: string; icon?: string }>\n export let defaultKey: K | null = null\n export let onChange: (key: K) => void\n\n const gap = 18\n const elementList: HTMLElement[] = []\n let container: HTMLElement\n $: activeIndex = defaultKey ? options.findIndex((option) => option.key === defaultKey) : 0\n $: activeButton = elementList[activeIndex]\n\n // 用来控制滑块移动的\n let activeButtonWidth: number | undefined\n let activeButtonLeft = 0\n\n function setAnimeResult() {\n if (activeButton && container) {\n activeButtonWidth = activeButton.clientWidth\n const newActiveButtonLeft = activeButtonLeft + container.getBoundingClientRect().left - activeButton.getBoundingClientRect().left\n activeButtonLeft = newActiveButtonLeft\n }\n }\n\n $: {\n if (activeButton && container) setTimeout(() => setAnimeResult(), 0)\n }\n</script>\n\n<div class=\"Switcher\" bind:this={container}>\n <div class=\"highlight\" style:width={activeButtonWidth ? `${activeButtonWidth}px` : undefined} />\n <div class=\"Switcher-buttons\" style:transform={`translate(${activeButtonLeft}px, -50%)`}>\n {#each options as option, index}\n <!-- svelte-ignore a11y-click-events-have-key-events -->\n <div\n class=\"button\"\n class:active={activeIndex === index}\n bind:this={elementList[index]}\n on:click={() => {\n onChange(option.key)\n activeIndex = index\n }}\n >\n <div class=\"content\">\n {#if option.icon}\n <span class=\"icon\" style:background-image={option.icon} />\n {/if}\n {option.value}\n </div>\n </div>\n {/each}\n </div>\n</div>\n\n<style lang=\"scss\">\n .Switcher {\n pointer-events: all;\n position: relative;\n margin-bottom: 24px;\n box-sizing: border-box;\n width: max-content;\n\n * {\n transition-duration: 300ms;\n transition-timing-function: ease-out;\n }\n\n .content {\n transition-property: opacity;\n }\n\n .highlight {\n transition-property: width;\n }\n\n .Switcher-buttons {\n transition-property: transform;\n }\n\n .Switcher-buttons {\n position: absolute;\n top: 50%;\n left: 0;\n transform: translate(0, -50%);\n width: max-content;\n .button {\n display: inline-block;\n margin: 0 9px;\n }\n }\n\n .highlight {\n height: 32px;\n background: rgba(0, 0, 0, 0.3);\n border-radius: 9999px;\n }\n\n .content {\n position: relative;\n padding: 0 12px;\n }\n\n .button:not(.active) {\n .content::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 10%;\n width: 80%;\n transform: translateY(-50%);\n height: 0;\n box-shadow: 0 0 15px 5px rgba(0, 0, 0, 0.3);\n }\n }\n }\n</style>\n","<!-- \n @component\n 一个圆的按钮\n -->\n<script lang=\"ts\">\n import { fade } from 'svelte/transition'\n import { endIconImage, startIconImage } from '../../Modules/UIController/mobileHTML'\n\n export let text: string\n export let onClick: () => void | undefined | null = null\n export let color: 'white' | 'blue' = 'white'\n\n $: bgImage = (() => {\n if (color === 'white') return startIconImage\n else if (color === 'blue') return endIconImage\n else return startIconImage\n })()\n</script>\n\n<div class=\"CircleButton\" style:background-image={`url(${bgImage})`} on:click={onClick}>\n {#key text}\n <div class=\"text\" transition:fade={{ duration: 300 }}>\n {text}\n </div>\n {/key}\n</div>\n\n<style lang=\"scss\">\n .CircleButton {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 72px;\n height: 72px;\n background-image: inherit;\n background-size: 100% auto;\n background-repeat: no-repeat;\n transition: transform 200ms ease-in-out;\n &:active {\n transform: scale(0.8);\n }\n .text {\n position: absolute;\n }\n }\n</style>\n","<!--\n @component\n 移动端控制器\n -->\n<script lang=\"ts\">\n import Switcher1 from './Common/Switcher1.svelte'\n import type MeasureController from '../Controller'\n import { onDestroy, onMount } from 'svelte'\n import CircleButton from './Common/CircleButton.svelte'\n import EditController from '../Controller/EditController'\n import Exit from './Common/Exit.svelte'\n import type { MeasureType } from '../typings/data'\n import { fade } from 'svelte/transition'\n import { IconOk, IconUndo } from './Common/icons'\n\n type ButtonState = 'start' | 'add' | 'end' | 'complete'\n\n export let measureController: MeasureController\n export let showExit = false\n export let i18n: (key: string) => string = (key) => key\n\n const buttonTextMap: Record<typeof buttonState, string> = {\n start: i18n('开始'),\n add: i18n('添加'),\n end: i18n('结束'),\n complete: i18n('完成'),\n }\n\n const buttonColorMap: Record<typeof buttonState, 'white' | 'blue'> = {\n start: 'white',\n add: 'white',\n end: 'blue',\n complete: 'blue',\n }\n\n const fadeDuration = 100\n\n /** 是否展示 */\n let showButton = false\n let pointsLength = 0\n let allowAddPoint = true\n let buttonState: ButtonState = 'start'\n let lastButtonState: ButtonState | null = null\n let currentMeasureType = measureController.currentMeasureType\n\n $: showButton = currentMeasureType === 'area' && buttonState !== 'start'\n\n /**\n * @description: 开始按钮的逻辑\n */\n const start = () => {\n if (measureController.getCurrentMode() !== 'Edit') {\n measureController.changeMode('Edit')\n } else {\n changeButtonState('add')\n addPoint()\n }\n }\n\n /**\n * @description: 添加按钮的逻辑\n */\n const addPoint = () => {\n if (measureController.controller instanceof EditController) {\n measureController.controller.selectPoint()\n }\n }\n\n const complete = () => {\n if (measureController.controller instanceof EditController) {\n measureController.controller.complete()\n }\n pointsLength = 0\n }\n\n const changeButtonState = (state: ButtonState) => {\n if (buttonState !== lastButtonState) {\n lastButtonState = buttonState\n }\n buttonState = state\n }\n\n /**\n * @description: 结束按钮的逻辑,打点并结束\n */\n const end = () => {\n addPoint()\n onAllowAddPointStateChange('allow')\n }\n\n const readyComplete = () => {\n changeButtonState('complete')\n }\n\n const notReadyComplete = () => {\n if (measureController.currentMeasureType === 'area') {\n if (buttonState === 'complete') {\n changeButtonState('add')\n }\n }\n }\n\n const handlePointsChange = (point: any[]) => {\n pointsLength = point.length\n }\n\n const setStartState = () => {\n changeButtonState('start')\n onAllowAddPointStateChange('allow')\n }\n\n const onAllowAddPointStateChange = (state: 'allow' | 'forbid') => {\n allowAddPoint = state === 'allow'\n }\n\n const onMeasureTypeChange = (measureType: MeasureType) => {\n currentMeasureType = measureType\n }\n\n const onRevoke = (params: { isEmpty: boolean }) => {\n if (params.isEmpty) changeButtonState('start')\n }\n\n onMount(() => {\n measureController.hooks.on('revoke', onRevoke)\n measureController.hooks.on('measureTypeChange', onMeasureTypeChange)\n measureController.hooks.on('modeChange', setStartState)\n measureController.hooks.on('pointsChange', handlePointsChange)\n measureController.hooks.on('allowAddPointStateChange', onAllowAddPointStateChange)\n measureController.hooks.on('readyComplete', readyComplete)\n measureController.hooks.on('notReadyComplete', notReadyComplete)\n measureController.hooks.on('complete', setStartState)\n })\n\n onDestroy(() => {\n measureController.hooks.off('measureTypeChange', onMeasureTypeChange)\n measureController.hooks.off('modeChange', setStartState)\n measureController.hooks.off('allowAddPointStateChange', onAllowAddPointStateChange)\n measureController.hooks.off('readyComplete', readyComplete)\n measureController.hooks.off('pointsChange', handlePointsChange)\n measureController.hooks.off('notReadyComplete', notReadyComplete)\n measureController.hooks.off('complete', setStartState)\n })\n</script>\n\n<div class=\"Measure-Controller\">\n {#if showExit}\n <Exit onClick={measureController.disable} />\n {/if}\n <div class=\"bottom\">\n <div class=\"mask\" />\n <div class=\"center\">\n <!-- 两个以上才有切换功能 -->\n {#if measureController.allowMeasureType.length >= 2 && buttonState === 'start'}\n <div class=\"mode-switcher\" transition:fade|local={{ duration: fadeDuration }}>\n <Switcher1\n options={[\n { key: 'line', value: i18n('测距离') },\n { key: 'area', value: i18n('测面积') },\n ]}\n defaultKey={measureController.currentMeasureType}\n onChange={measureController.changeMeasureType}\n />\n </div>\n {/if}\n <div class=\"controller\">\n {#if showButton}\n <div\n transition:fade|local={{ duration: fadeDuration }}\n class=\"button\"\n class:forbid={buttonState === 'start'}\n on:click={() => measureController.revoke()}\n >\n <div class=\"icon\" style:background-image={`url(${IconUndo})`} />\n {i18n('撤销')}\n </div>\n {/if}\n <div class=\"main-button\" class:forbid={!allowAddPoint}>\n <CircleButton\n onClick={() => {\n if (buttonState === 'start') start()\n else if (buttonState === 'add') addPoint()\n else if (buttonState === 'end' || buttonState === 'complete') end()\n }}\n text={buttonTextMap[buttonState]}\n color={buttonColorMap[buttonState]}\n />\n </div>\n {#if showButton}\n <div transition:fade|local={{ duration: fadeDuration }} class=\"button\" on:click={complete}>\n <div class=\"icon\" style:background-image={`url(${IconOk})`} />\n {i18n('结束')}\n </div>\n {/if}\n </div>\n </div>\n </div>\n</div>\n\n<style lang=\"scss\">\n *.forbid {\n pointer-events: none !important;\n opacity: 0.5;\n }\n .Measure-Controller {\n pointer-events: none;\n position: relative;\n width: 100%;\n height: 100%;\n z-index: 2;\n color: white;\n .mode-switcher {\n margin-top: 36px;\n }\n .bottom {\n position: absolute;\n width: 100%;\n bottom: 0;\n .mask {\n position: absolute;\n bottom: 0;\n width: 100%;\n height: 200px;\n background-size: 100%;\n z-index: -1;\n background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.5));\n }\n .center {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 40px;\n }\n }\n }\n\n .Measure-Controller {\n .controller {\n pointer-events: all;\n display: flex;\n align-items: center;\n .button {\n cursor: pointer;\n display: flex;\n align-items: center;\n height: 40px;\n padding-left: 16px;\n padding-right: 16px;\n border-radius: 9999px;\n font-size: 14px;\n color: #fff;\n background-color: rgba(0, 0, 0, 0.2);\n .icon {\n width: 24px;\n height: 24px;\n background-repeat: no-repeat;\n background-size: 100%;\n margin: 0 4px;\n }\n }\n .main-button {\n margin-left: 28px;\n margin-right: 28px;\n font-size: 14px;\n font-weight: bold;\n }\n }\n }\n</style>\n","import type MeasureController from '../../Controller'\nimport htmlString from './HTML'\nimport mobileHTMLString from './mobileHTML'\nimport { uiWrapperStyle, operatingSpaceStyle, controllerBackgroundStyle, exitIconStyle, exitItemStyle, textStyle } from './style'\nimport { MainBtnController } from './MainBtnController'\nimport { MobileMainBtnController } from './mobileMainBtnController'\nimport Revoke from './Revoke'\nimport Controller0 from '../../Components/Controller0.svelte'\nimport Controller1 from '../../Components/Controller1.svelte'\n\nimport { mountComponent, type MountedComponent } from '../../../shared-utils/svelte/component.svelte'\nexport type UIMode = 'pc' | 'mobile'\n\nexport interface UIControllerParams {\n container?: Element\n mode?: UIMode\n pointSelectorMode?: 'fixed' | 'cursor'\n useNewUI?: boolean\n /**\n * @description: 是否展示退出按钮\n */\n showExit?: boolean\n startButtonText?: string\n endButtonText?: string\n revokeButtonText?: string\n exitButtonText?: string\n i18n?: (key: string) => string\n}\n\nexport class UIController {\n private revoke?: Revoke\n private container: HTMLDivElement\n private wrapper?: HTMLDivElement\n private mainController?: MainBtnController | MobileMainBtnController\n private disposers: (() => unknown)[] = []\n private measureController: MeasureController\n private mode: UIMode\n private svelteDom?: MountedComponent<any>\n private _params: UIControllerParams\n private useNewUI: boolean = false\n\n public constructor(measureController: MeasureController, params: UIControllerParams) {\n this._params = params\n this.measureController = measureController\n this.mode = params.mode ?? 'pc'\n this.wrapper = params.container as HTMLDivElement\n this.container = document.createElement('div')\n this.wrapper.appendChild(this.container)\n\n const useNewUI = params.useNewUI ?? false\n this.useNewUI = useNewUI\n\n // 新整的UI\n if (useNewUI) {\n this.container.style.position = 'absolute'\n this.container.style.top = '0'\n this.container.style.left = '0'\n this.container.style.width = '100%'\n this.container.style.height = '100%'\n if (params.pointSelectorMode === 'cursor') {\n this.svelteDom = mountComponent(Controller0, this.container, { measureController: this.measureController, i18n: params.i18n, showExit: params.showExit })\n } else if (params.pointSelectorMode === 'fixed') {\n this.svelteDom = mountComponent(Controller1, this.container, { measureController: this.measureController, i18n: params.i18n, showExit: params.showExit })\n }\n }\n\n // 以前的UI\n if (!useNewUI) {\n this.container.innerHTML = this.mode === 'mobile' ? mobileHTMLString : htmlString\n this.container.classList.add('fpm__ui-controller', this.mode)\n this.container.style.background = 'rgba(0, 0, 0, 0.15)'\n\n const textDoms = this.container.querySelectorAll<HTMLSpanElement>('.fpm__text')\n const bgDom = this.container.querySelector<HTMLSpanElement>('.fpm_ui-bg')\n const operatingSpaceDom = this.container.querySelector<HTMLSpanElement>('.fpm_operating-space')\n\n Object.assign(bgDom?.style, controllerBackgroundStyle)\n Object.assign(operatingSpaceDom?.style, operatingSpaceStyle)\n Object.assign(this.container.style, uiWrapperStyle)\n textDoms.forEach((item) => Object.assign(item.style, textStyle))\n }\n }\n\n public dispose() {\n this.hide()\n this.svelteDom?.destroy()\n this.container.remove()\n }\n\n public show() {\n this.container.style.display = 'block'\n this.container.style.opacity = '1'\n this.container.style.transform = 'translate(0, 0)'\n if (this.useNewUI === false) {\n if (this.mode === 'pc') {\n this.revoke = new Revoke(this.measureController, this.container)\n this.mainController = new MainBtnController(this.measureController, this.container, this._params)\n } else {\n this.mainController = new MobileMainBtnController(this.measureController, this.container, this._params)\n }\n this.disposers.push(this.handleExit())\n }\n\n return this\n }\n\n public hide() {\n this.container.style.display = 'none'\n this.container.style.opacity = '0'\n this.container.style.transform = 'translate(0, 10px)'\n if (this.useNewUI === false) {\n this.mode === 'pc' && this.revoke?.dispose()\n }\n this.mainController?.dispose()\n this.disposers.forEach((disposer) => disposer())\n this.disposers = []\n return this\n }\n\n private handleExit = () => {\n const exitIcon = this.container.querySelector<HTMLElement>('.fpm__exit-icon')\n const exitItem = this.container.querySelector<HTMLButtonElement>('.fpm__exit')\n if (!exitItem || !exitIcon) throw new Error('cannot find dom')\n\n if (this.mode === 'pc') {\n Object.assign(exitItem.style, exitItemStyle)\n Object.assign(exitIcon?.style, exitIconStyle)\n }\n\n const onMouseEnter = () => {\n exitItem.style.opacity = '1'\n }\n const onMouseLeave = () => {\n exitItem.style.opacity = '0.85'\n }\n const handleClick = () => {\n this.measureController.disable()\n }\n\n exitItem.addEventListener('click', handleClick)\n exitItem.addEventListener('mouseenter', onMouseEnter)\n exitItem.addEventListener('mouseleave', onMouseLeave)\n\n return () => {\n exitItem.removeEventListener('click', handleClick)\n exitItem.removeEventListener('mouseenter', onMouseEnter)\n exitItem.removeEventListener('mouseleave', onMouseLeave)\n }\n }\n}\n","<!--\n @component\n pc 端控制器\n -->\n<script lang=\"ts\">\n import type MeasureController from '../Controller'\n import { onDestroy, onMount } from 'svelte'\n import type { MeasureTip } from '../Modules/GuideController'\n import type { Mode } from '../Controller'\n import { fade } from 'svelte/transition'\n\n type TipKey = keyof (MeasureTip['line'] & MeasureTip['area'] & Omit<MeasureTip, 'line' | 'area'>)\n\n export let measureController: MeasureController\n export let i18n: (key: string) => string = (key) => key\n export let tips: MeasureTip\n export let tipStyle: Partial<CSSStyleDeclaration> = {}\n export let visible = true\n\n let textDom: HTMLDivElement | null = null\n\n $: {\n if (textDom) {\n for (const key in tipStyle) {\n if (tipStyle.hasOwnProperty(key)) {\n textDom.style[key] = tipStyle[key]\n }\n }\n }\n }\n\n const getTip = (key: TipKey) => {\n const currentType = measureController.currentMeasureType\n let tip = ''\n tip = tips[key as any]\n if (tip === undefined) {\n tip = tips[currentType][key as any]\n }\n return tip\n }\n\n const setTip = (key: TipKey) => {\n tip = i18n(getTip(key))\n }\n\n const clear = () => {\n tip = ''\n }\n\n let tip = ''\n\n const handleModeChange = (mode: Mode) => {\n if (mode === 'Edit') {\n if (measureController.changeMeasureType) setTip('start')\n else clear()\n } else {\n clear()\n }\n }\n\n const complete = () => {\n if (measureController.getCurrentMode() === 'Watch') {\n clear()\n }\n }\n\n const start = () => {\n if (measureController.getCurrentMode() === 'Edit') {\n setTip('start')\n }\n }\n\n const pointsChange = (points: any[]) => {\n if (measureController.currentMeasureType === 'area') {\n if (points.length >= 2) setTip('close')\n else if (points.length === 0) setTip('start')\n else clear()\n }\n }\n\n onMount(() => {\n handleModeChange(measureController.getCurrentMode())\n measureController.hooks.on('modeChange', handleModeChange)\n measureController.hooks.on('complete', complete)\n measureController.hooks.on('pointsChange', pointsChange)\n measureController.hooks.on('measureTypeChange', start)\n })\n\n onDestroy(() => {\n measureController.hooks.off('modeChange', handleModeChange)\n measureController.hooks.off('complete', complete)\n measureController.hooks.off('pointsChange', pointsChange)\n measureController.hooks.off('measureTypeChange', start)\n clear()\n })\n</script>\n\n{#if visible}\n <div class=\"Measure-Tips\" transition:fade>\n <div class=\"text\" bind:this={textDom}>{tip}</div>\n </div>\n{/if}\n\n<style lang=\"scss\">.Measure-Tips {\n box-sizing: border-box;\n position: absolute;\n pointer-events: none;\n top: 0;\n width: 100%;\n padding: 0 2.5rem;\n}\n.Measure-Tips .text {\n text-align: center;\n position: relative;\n max-width: 100%;\n top: 3.125rem;\n color: #fff;\n word-break: break-word;\n overflow-wrap: break-word;\n hyphens: auto;\n -webkit-hyphens: auto;\n text-shadow: 0 0.0625rem 0.375rem rgba(0, 0, 0, 0.5);\n font-size: 1.25rem;\n font-weight: bold;\n}</style>\n","<!--\n @component\n pc 端控制器\n -->\n<script lang=\"ts\">\n import type MeasureController from '../Controller'\n import { onDestroy, onMount } from 'svelte'\n import type { MeasureTip } from '../Modules/GuideController'\n import type { Mode } from '../Controller'\n import { fade } from 'svelte/transition'\n\n type TipKey = keyof (MeasureTip['line'] & MeasureTip['area'] & Omit<MeasureTip, 'line' | 'area'>)\n\n export let measureController: MeasureController\n export let i18n: (key: string) => string = (key) => key\n export let tips: MeasureTip\n export let tipStyle: Partial<CSSStyleDeclaration> = {}\n export let visible = true\n\n let textDom: HTMLDivElement | null = null\n\n $: {\n if (textDom) {\n for (const key in tipStyle) {\n if (tipStyle.hasOwnProperty(key)) {\n textDom.style[key] = tipStyle[key]\n }\n }\n }\n }\n\n const getTip = (key: TipKey) => {\n const currentType = measureController.currentMeasureType\n let tip = ''\n tip = tips[key as any]\n if (tip === undefined) {\n tip = tips[currentType][key as any]\n }\n return tip\n }\n\n const setTip = (key: TipKey) => {\n tip = i18n(getTip(key))\n }\n\n const clear = () => {\n tip = ''\n }\n\n let tip = ''\n\n const handleModeChange = (mode: Mode) => {\n if (mode === 'Edit') {\n if (measureController.changeMeasureType) setTip('start')\n else clear()\n } else {\n clear()\n }\n }\n\n const complete = () => {\n if (measureController.getCurrentMode() === 'Watch') {\n clear()\n }\n }\n\n const start = () => {\n if (measureController.getCurrentMode() === 'Edit') {\n setTip('start')\n }\n }\n\n const pointsChange = (points: any[]) => {\n if (measureController.currentMeasureType === 'area') {\n if (points.length >= 2) setTip('close')\n else if (points.length === 0) setTip('start')\n else clear()\n }\n }\n\n onMount(() => {\n handleModeChange(measureController.getCurrentMode())\n measureController.hooks.on('modeChange', handleModeChange)\n measureController.hooks.on('complete', complete)\n measureController.hooks.on('pointsChange', pointsChange)\n measureController.hooks.on('measureTypeChange', start)\n })\n\n onDestroy(() => {\n measureController.hooks.off('modeChange', handleModeChange)\n measureController.hooks.off('complete', complete)\n measureController.hooks.off('pointsChange', pointsChange)\n measureController.hooks.off('measureTypeChange', start)\n clear()\n })\n</script>\n\n{#if visible}\n <div class=\"Measure-Tips\" transition:fade>\n <div class=\"text\" bind:this={textDom}>{tip}</div>\n </div>\n{/if}\n\n<style lang=\"scss\">\n .Measure-Tips {\n box-sizing: border-box;\n position: absolute;\n pointer-events: none;\n top: 0;\n width: 100%;\n padding: 0 40px;\n .text {\n text-align: center;\n position: relative;\n max-width: 100%;\n top: 50px;\n color: #fff;\n word-break: break-word;\n overflow-wrap: break-word;\n hyphens: auto;\n -webkit-hyphens: auto;\n text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5);\n font-size: 20px;\n font-weight: bold;\n }\n }\n</style>\n","import objectAssignDeep from 'object-assign-deep'\nimport Tip from '../Components/Tip.svelte'\nimport type MeasureController from '../Controller'\nimport type { PartialObjectDeep } from '../../typings/typings'\nimport type { PointSelectorMode } from '../typings/data'\n\nimport { mountComponent, type MountedComponent } from '../../shared-utils/svelte/component.svelte'\nconst pcTip: MeasureTip = {\n line: {\n start: '选择一个合适的位置开始测量,点击【结束】或【鼠标右键】结束测量',\n },\n area: {\n start: '选择一个合适的位置开始绘制平面',\n close: '选择3个点后将闭合平面,点击【结束】或【鼠标右键】将自动闭合',\n },\n}\n\nconst mobileTip: MeasureTip = {\n line: {\n start: '',\n },\n area: {\n start: '',\n close: '选择3个点后将闭合平面,点击结束自动闭合',\n },\n}\n\nexport interface MeasureTip {\n line: {\n // 开始的提示\n start: string\n }\n area: {\n // 开始的提示\n start: string\n // 提示闭合\n close: string\n }\n}\n\nexport interface GuideControllerParams {\n container?: Element\n i18n?: (key: string) => string\n tips?: PartialObjectDeep<MeasureTip>\n tipStyle?: Partial<CSSStyleDeclaration>\n pointSelectorMode?: PointSelectorMode\n}\n\nexport class GuideController {\n private tipSvelteDom?: MountedComponent<any>\n\n public constructor(measureController: MeasureController, params: GuideControllerParams) {\n this.tipSvelteDom = mountComponent(Tip, params.container, {\n measureController,\n tips: objectAssignDeep({}, params.pointSelectorMode === 'fixed' ? mobileTip : pcTip, params.tips),\n i18n: params.i18n,\n visible: true,\n tipStyle: params.tipStyle,\n })\n }\n\n public dispose() {\n this.tipSvelteDom?.destroy()\n }\n\n public show() {\n this.tipSvelteDom?.update({ visible: true })\n return this\n }\n\n public hide() {\n this.tipSvelteDom?.update({ visible: false })\n return this\n }\n}\n","import type MeasureController from '.'\nimport type { Five } from '@realsee/five-webgpu'\n\n/** 快捷键控制器 */\nexport class ShortcutKeyController {\n public five: Five\n public measureController: MeasureController\n\n public constructor(measureController: MeasureController, five: Five) {\n this.five = five\n this.measureController = measureController\n\n const fiveElement = this.five.getElement()\n if (!fiveElement) return\n document.body.addEventListener('keydown', this.onKeyDown)\n }\n\n public dispose() {\n const fiveElement = this.five.getElement()\n if (!fiveElement) return\n document.body.removeEventListener('keydown', this.onKeyDown)\n }\n\n private escape() {\n if (this.measureController.getCurrentMode() === 'Watch') return this.measureController.disable()\n return this.measureController.save().changeMode('Watch')\n }\n\n private onKeyDown = (e: KeyboardEvent) => {\n // Command + S -> 保存 & 更改场景\n if (e.metaKey && e.code === 'KeyS') {\n this.measureController.save().changeMode('Watch')\n e.preventDefault()\n return\n }\n\n // Escape -> 切换到观察模式 / 如果已经在观察模式,退出功能\n if (e.code === 'Escape') return this.escape()\n }\n\n private onMouseDown = (e: MouseEvent) => {\n // 鼠标右键取消\n if (e.button !== 2) return\n e.preventDefault()\n this.measureController.save().changeMode('Watch')\n }\n}\n","import type { Config } from '../typings'\nimport type {\n EditParameter,\n MeasureType,\n OpenParameter,\n MeasurePluginData,\n PointSelectorMode,\n MeasurePluginServerData,\n} from '../typings/data'\nimport type { PanoMeasurePluginEvent } from '../typings/event.type'\nimport type { UserDistanceItem } from '../utils/dom/distanceItem'\nimport type { Polyline } from '../Model/polyline'\nimport type { ControllerParams } from './BaseController'\nimport EditController from './EditController'\nimport ViewController from './ViewController'\nimport WatchController from './WatchController'\nimport MixedController from './MixedController'\nimport { omit } from '../../shared-utils/filter'\nimport { Group } from 'three/webgpu'\nimport { Model } from '../Model'\nimport type { Subscribe } from '../../shared-utils/Subscribe'\nimport type { Five } from '@realsee/five-webgpu'\nimport { getMouseGroup } from '../utils/mouseGroup'\nimport { UIController, type UIControllerParams } from '../Modules/UIController'\nimport { GuideController, type GuideControllerParams } from '../Modules/GuideController'\nimport { ShortcutKeyController } from './ShortcutKeyController'\nimport safeObj from '../../shared-utils/safeObj'\nimport { Magnifier } from '../../shared-utils'\nimport type { MagnifierParameter } from '../../shared-utils'\nimport { isTouchDevice } from '../../shared-utils/isTouchDevice'\nimport type Area from '../Model/area'\nimport * as BasePlugin from '../../base/BasePlugin'\nimport type { PointSelectorConfig } from '../../shared-utils/three/PointSelector'\n\n// 新增Mixed模式专用于mobile端\nexport type Mode = 'Watch' | 'Edit' | 'Mixed' | 'View'\n\n// 参数\nexport interface PanoMeasureParameterType extends Partial<Config> {\n editParams?: EditParameter\n pointSelectorConfig?: PointSelectorConfig\n openParams?: OpenParameter\n useUIController?: boolean | UIControllerParams\n useGuideController?: boolean | GuideControllerParams\n // TODO: 这个参数传递的太恶心了,优化一下\n userDistanceItemCreator?: () => UserDistanceItem\n}\n\nexport default class PanoMeasureController extends BasePlugin.Controller<\n BasePlugin.State,\n BasePlugin.EventMap<BasePlugin.State> & PanoMeasurePluginEvent\n> {\n public state: BasePlugin.State = { enabled: true }\n public hasOpen = false\n public magnifier: Magnifier\n public controller: WatchController | EditController | MixedController | ViewController | null = null\n /** 允许的测量类型 */\n public allowMeasureType: Array<MeasureType>\n /** 当前的测量类型 */\n public currentMeasureType: MeasureType | null\n\n private model: Model\n private group: Group\n private config: Config\n\n private isMobile: boolean\n private useUIController?: UIController\n private params: PanoMeasureParameterType\n private useGuideController?: GuideController\n private container = document.createElement('div')\n private shortcutKeyController?: ShortcutKeyController\n\n public constructor(five: Five, params: PanoMeasureParameterType) {\n super(five)\n this.five = five\n // TODO: 最早的设计里面 params 应该是一个只读值,但是后面一直在改这个值,考虑删掉\n this.params = params\n this.config = omit(params, ['openParams', 'pointSelectorConfig'])\n this.model = new Model(this.config)\n // isMobile\n this.isMobile = params?.openParams?.isMobile ?? false\n // magnifier\n this.magnifier = new Magnifier(\n five,\n params.pointSelectorConfig?.helper?.magnifierParams ?? { width: 190, height: 190, scale: 2 },\n )\n // measure type\n this.allowMeasureType = Array.from(new Set(params.editParams?.allowMeasureType ?? ['line']))\n this.currentMeasureType = this.allowMeasureType[0] ?? 'line'\n // ==================== Group ====================\n this.group = new Group()\n this.group.name = 'plugin-measure-group'\n this.container.classList.add('five-plugin-measure-container')\n this.container.style.position = 'absolute'\n this.container.style.left = '0'\n this.container.style.top = '0'\n this.container.style.visibility = 'hidden'\n this.container.style.pointerEvents = 'none'\n this.container.style.width = '100%'\n this.container.style.height = '100%'\n this.container.style.opacity = '0'\n this.container.style.zIndex = '1'\n\n const pointSelectorMode: PointSelectorMode = params.editParams?.pointSelectorMode ?? (isTouchDevice ? 'fixed' : 'cursor')\n\n // 加载UI\n // TODO: 优化 UIController 初始化逻辑\n const openParams = this.params.openParams ?? {}\n if (this.params.useUIController !== false) {\n const uiControllerParams = {\n container: this.container,\n openParams,\n i18n: params.i18n,\n pointSelectorMode,\n useNewUI: this.allowMeasureType.length > 1,\n ...safeObj(this.params.useUIController),\n }\n this.useUIController = new UIController(this, uiControllerParams)\n }\n if (this.params.useGuideController !== false) {\n const guideControllerParams = {\n container: this.container,\n pointSelectorMode,\n i18n: params.i18n,\n ...safeObj(this.params.useGuideController),\n }\n this.useGuideController = new GuideController(this, guideControllerParams)\n }\n }\n\n public appendTo(parent: HTMLElement) {\n parent.append(this.container)\n }\n\n public clear() {\n this.model.clear()\n }\n\n public dispose() {\n this.disable()\n this.clear()\n this.useUIController?.dispose()\n this.magnifier?.dispose()\n this.five.needsRender = true\n }\n\n /** 加载数据\n * @description 数据加载时会覆盖当前已保存的数据\n * @description 如果当前正在编辑中,会自动退出并保存编辑\n */\n public load(data: MeasurePluginData | MeasurePluginServerData) {\n let transformedData: MeasurePluginData = data as any\n if ((data as any).list) {\n const polylines = (data as MeasurePluginServerData).list.map((item) => item.polyline)\n transformedData = {\n polylines: polylines.map((polyline) => ({\n ...polyline,\n visibleFiveMode: polyline.visibleFiveMode ?? ['Panorama'],\n })),\n }\n }\n\n this.model.parse(transformedData)\n this.save()\n }\n\n /** 插件功能入口\n * @description 会隐藏鼠标的默认聚焦环\n * @description 会隐藏当前 VR 内的点位展示\n */\n public override enable(config?: { mode: Mode }): void {\n if (this.hasOpen) return\n\n if (!this.container.parentElement && this.five.getElement()?.parentElement) {\n this.appendTo(this.five.getElement()!.parentElement!)\n }\n\n this.state.enabled = true\n this.hasOpen = true\n\n this.group.matrix.copy(this.workUtil.transform)\n this.group.matrix.decompose(this.group.position, this.group.quaternion, this.group.scale)\n this.group.updateMatrixWorld()\n\n this.five.scene.add(this.group)\n\n // TODO: 为什么用透明度解决,该销毁的 DOM 销毁\n // 修改透明度\n this.container.style.visibility = 'visible'\n this.container.style.opacity = '1'\n if (config?.mode) {\n this.changeMode(config.mode)\n } else if (this.isMobile) {\n this.changeMode('Mixed')\n } else {\n this.changeMode('Watch')\n }\n if (config?.mode !== 'View') {\n this.useUIController?.show()\n this.useGuideController?.show()\n }\n this.shortcutKeyController = new ShortcutKeyController(this, this.five)\n this.hooks.emit('enable', true)\n }\n\n /** 关闭插件功能\n * @description 清除标尺线条\n * @description 还原点位展示和默认鼠标 UI\n */\n public disable = (): void => {\n this.hasOpen = false\n this.state.enabled = false\n // 修改透明度\n this.container.style.visibility = 'hidden'\n this.container.style.opacity = '0'\n // 展示点位和鼠标聚焦环\n this.controller?.dispose()\n this.useUIController?.hide()\n this.useGuideController?.hide()\n this.shortcutKeyController?.dispose()\n this.controller = null\n this.five.helperVisible = true\n this.five.scene.remove(this.group)\n this.five.needsRender = true\n this.hooks.emit('disable', true)\n }\n\n public getCurrentMode = (): Mode | null => {\n if (this.controller instanceof EditController) return 'Edit'\n if (this.controller instanceof WatchController) return 'Watch'\n if (this.controller instanceof MixedController) return 'Mixed'\n if (this.controller instanceof ViewController) return 'View'\n return null\n }\n\n /** 变更场景\n * @description 如果从编辑场景改变到观看场景,不会自动保存,默认丢弃所有改动\n */\n public changeMode = (mode: Mode) => {\n if (!this.hasOpen) return\n if (this.getCurrentMode() === mode) return\n this.controller?.dispose()\n const controllerMap = {\n View: ViewController,\n Watch: WatchController,\n Edit: EditController,\n Mixed: MixedController,\n }\n if (!controllerMap[mode]) throw new Error('不存在的 Mode')\n const controllerParams = this.createControllerParams()\n this.controller = new controllerMap[mode](controllerParams)\n if (mode === 'View') {\n this.useUIController?.hide()\n this.useGuideController?.hide()\n } else {\n this.useUIController?.show()\n this.useGuideController?.show()\n }\n this.hooks.emit('modeChange', mode)\n }\n\n /**\n * @description: 切换测量的类型\n */\n public changeMeasureType = (measureType: MeasureType) => {\n this.currentMeasureType = measureType\n this.hooks.emit('measureTypeChange', measureType)\n }\n\n /** 进入编辑模式 */\n public edit(measureType?: MeasureType) {\n if (measureType) this.changeMeasureType(measureType)\n const mode: Mode = this.isMobile ? 'Mixed' : 'Edit'\n this.changeMode(mode)\n }\n\n /** 撤销编辑 */\n public revoke(): void {\n if (!(this.controller instanceof EditController)) return\n this.controller.revoke()\n return\n }\n\n public removePolyline(polyline: Polyline) {\n this.model.removePolyline(polyline)\n }\n\n public removeArea(area: Area) {\n this.model.removeArea(area)\n }\n\n public removePolylineByID(id: string) {\n const polyline = this.model.getPolylineByID(id)\n polyline && this.model.removePolyline(polyline)\n }\n\n public getPolylineByID(id: string) {\n return this.model.getPolylineByID(id)\n }\n\n public getEditedPolyline(): Polyline | undefined {\n return this.controller instanceof EditController || this.controller instanceof MixedController\n ? (this.controller as EditController | MixedController).polyline\n : undefined\n }\n\n /**\n * 高亮当前线段\n */\n public highlightLine(lineID: string) {\n if (this.getCurrentMode() !== 'Watch') return false\n const line = this.model.getLineByID(lineID)\n if (!line) return false\n ;(this.controller as WatchController).highlightLine(line)\n return true\n }\n\n public clearHighlightLines() {\n if (this.getCurrentMode() !== 'Watch') return false\n ;(this.controller as WatchController).clearHighlightLines()\n return true\n }\n\n /** 保存编辑\n * @description 以下情况可能报错\n */\n public save(config?: { mode?: Mode }) {\n if (!(this.controller instanceof EditController) && !(this.controller instanceof MixedController)) return this\n const mode = config?.mode ?? 'View'\n const areas = this.controller.model.areas\n\n if (this.controller instanceof EditController) {\n this.controller.complete()\n } else {\n areas.forEach((area) => {\n area.showArea()\n this.model.addArea(area)\n })\n }\n this.changeMode(mode)\n return this\n }\n\n /** Mixed 模式才有用,添加起点 */\n public addStartPoint() {\n if (!(this.controller instanceof MixedController)) return\n this.hooks.emit('willChangeState', 'watching', 'editing')\n }\n\n /** Mixed 模式才有用,添加终点 */\n public addEndPoint() {\n if (!(this.controller instanceof MixedController)) return\n this.hooks.emit('willChangeState', 'editing', 'watching')\n }\n\n /** 导出数据 */\n public toJson() {\n return this.model.toJson()\n }\n\n public changeConfigs(config: Config) {\n Object.assign(this.config, config)\n this.controller?.updateDistanceUI()\n this.controller?.updateAreaUI()\n }\n\n /** 设置线段的文本 */\n public setCustomText(lineID: string, text: string) {\n const line = this.model.getLineByID(lineID)\n if (!line) throw new Error('不存在的线段')\n line.setText(text)\n this.controller?.updateDistanceUI()\n }\n\n private createControllerParams(): ControllerParams {\n const openParams = this.params.openParams ?? {}\n const editParams = this.params.editParams ?? {}\n openParams.isMobile = this.isMobile\n return {\n five: this.five,\n hook: this.hooks,\n group: this.group,\n model: this.model,\n config: this.config,\n magnifier: this.magnifier,\n container: this.container,\n workUtil: this.workUtil,\n openParams,\n editParams,\n pointSelectorConfig: this.params.pointSelectorConfig,\n getMeasureType: () => this.currentMeasureType,\n mouseGroup: getMouseGroup({ ...openParams.crossHairParameter }),\n userDistanceItemCreator: this.params.userDistanceItemCreator,\n }\n }\n}\n","import type { FivePlugin } from '@realsee/five-webgpu'\nimport MeasureController, { type PanoMeasureParameterType } from './Controller'\nimport Magnifier from './Modules/Magnifier'\n\nexport const PanoMeasurePlugin: FivePlugin<PanoMeasureParameterType, PanoMeasureReturnType> = function PanoMeasurePlugin(five, params) {\n return new MeasureController(five, params)\n}\n\nexport default PanoMeasurePlugin\nexport { Magnifier }\nexport { Model as PanoMeasurePluginModel } from './Model'\nexport { default as PanoMeasurePluginPoint } from './Model/point'\nexport { default as PanoMeasurePluginLine } from './Model/line'\nexport { Polyline as PanoMeasurePluginPolyline } from './Model/polyline'\n\n// 类型导出\nexport type PanoMeasureReturnType = MeasureController\nexport type { PanoMeasurePluginEvent } from './typings/event.type'\nexport type {\n LineJson as PanoMeasurePluginLineJson,\n PointJson as PanoMeasurePluginPointJson,\n PolylineJson as PanoMeasurePluginPolylineJson,\n OpenParameter as PanoMeasurePluginOpenParameter,\n} from './typings/data'\nexport type { PanoMeasureParameterType } from './Controller'\n"],"mappings":"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"}